Is Ad Block Wonder safe?
Ad Block Wonder is high risk. Beyond the reviewed rule lists in the Web Store package, Ad Block Wonder downloads a larger rule set from the developer's server, applied to declarativeNetRequest. DA confirmed thousands of domains installed live, changeable at runtime.…
Who publishes itWonder Block - no other listings under this identity, 7 shared hostnames
Wonder Block - no other listings under this identity, 7 shared hostnames
What this publisher told the store about itself, and the other listings that told it the same thing.
Shared hosts - 7 hostnames
Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Extension Downloads and Applies Thousands of Blocking Rules From Its Own Server
Beyond the reviewed rule lists in the Web Store package, Ad Block Wonder downloads a larger rule set from the developer's server, applied to declarativeNetRequest.
DA confirmed thousands of domains installed live, changeable at runtime.
The developer's server sends the extension a URL and version number for a bulk rules file.
The extension downloads that file and loads thousands of domain-matching rules directly into Chrome's blocking engine.
The request for the rules file includes your extension's runtime ID as a URL parameter.
| Field | Value | Why it matters | |
|---|---|---|---|
Which file is downloaded | https://wonderupdates.com/compiled_rules.php | The address the rules are fetched from, determined by the server response, not fixed in the extension package. | |
Your extension's runtime ID | ?extid=kejigfhcnfgbejgnacjpehlledjlgpbf | Sent as a query parameter on every rules download, letting the server tell individual installs apart. | |
Rule scale | 4,709 domains in one rule; 5,000 in another in the same fetch | A single downloaded rule set can name thousands of domains to redirect or block on your device, none reviewed by the Chrome Web Store. |
Bulk rules fetch and install (src/background.js)
// rulesUrl came from the server's last config response, not the extension package.
const fetchUrl = rulesUrl.includes("?")
? `${rulesUrl}&extid=${encodeURIComponent(ch.runtime.id)}` // tags the download with your install ID
: `${rulesUrl}?extid=${encodeURIComponent(ch.runtime.id)}`;
// Download whatever JSON array is at that URL, up to 60s.
const response = await fetch(fetchUrl, { signal: controller.signal });
if (!response.ok) return;
const bulkRules = JSON.parse(await response.text());
if (!Array.isArray(bulkRules)) return;
// Swap out the previous server-fetched rule set for the new one, applied
// directly to Chrome's declarativeNetRequest engine — bypassing the
// packaged-rules review path entirely.
const existing = await ch.declarativeNetRequest.getDynamicRules();
const existingBulkIds = existing.filter(r => r.id >= 11000).map(r => r.id);
if (existingBulkIds.length > 0) {
await ch.declarativeNetRequest.updateDynamicRules({ removeRuleIds: existingBulkIds });
}
await ch.declarativeNetRequest.updateDynamicRules({ addRules: bulkRules });Install-Time Tab Snapshot Sent to Developer Server
On install, Ad Block Wonder reads every open tab's domain and sends the list to wonderadblock.com automatically, with no prompt, revealing which sites you were browsing at install.
The request also includes your extension ID and version.
You install Ad Block Wonder from the Chrome Web Store.
The extension reads every domain you have open across all your browser tabs and sends the list to the developer's server without a consent prompt.
This happens automatically in the background during first-install setup, before any blocking rules are applied.
| Content-Type | application/json |
{
"extv": "3.8",
"installDoms": [
"google.com",
"facebook.com"
],
"allowedDomains": [],
"extid": "fpkbnjejghdcncegfglnapabnljcimdc"
}| Field | Value | Why it matters | |
|---|---|---|---|
Your open tab domains | ["google.com","facebook.com","mail.yahoo.com"] | The domain of every website you had open at the exact moment you installed the extension. Reveals your browsing session snapshot. | |
Your extension ID | fpkbnjejghdcncegfglnapabnljcimdc | The unique identifier for your installation of this extension. Can be used to track you across time. | |
Extension version | 3.8 | Which version of the extension you installed. | |
Your personal allowlist | [] | Domains you have explicitly whitelisted from ad blocking, also sent on every update request. |
The install-time tab collection code (src/helper/utils.js)
// Called immediately when the extension is first installed.
async function installDataGathering() {
// Ask Chrome for every open tab in every window — no filter.
const allTabs = await chrome.tabs.query({});
const domains = new Set();
for (const tab of allTabs) {
if (tab.url) {
// Extract just the hostname (e.g. "google.com" from "https://google.com/search?q=...").
const domain = getHostName(tab.url);
if (domain) domains.add(domain);
}
}
// Write the domain list to chrome.storage so fetchData() can include it in the POST body.
if (domains.size > 0) {
await storage.setItem("installDoms", Array.from(domains));
}
}
// Immediately after, fetchData() reads chrome.storage and POSTs:
// { extv, installDoms, allowedDomains, extid } → https://wonderadblock.com/wonder-3_7.php- wonderadblock.com
Developer-controlled server receiving every new install's tab-domain snapshot. Also serves subsequent configuration updates and is the uninstall reporting endpoint.
Intercepts the outbound POST from Ad Block Wonder on install and logs the installDoms payload to the DevTools console, confirming which tab domains were captured.
// adblock-wonder-install-spy.js
// Intercepts the fetch() call made by Ad Block Wonder on first install
// and logs the request body (including installDoms) to the console.
//
// Run in the DevTools console of the extension's service worker BEFORE installing.
(function() {
const originalFetch = self.fetch.bind(self);
self.fetch = async function(input, init) {
const url = typeof input === 'string' ? input : input?.url;
if (url && url.includes('wonderadblock.com')) {
try {
const body = init?.body;
console.log('[WONDER_INSTALL_SPY] Outbound POST intercepted:', url);
if (body) {
const parsed = JSON.parse(body);
console.log('[WONDER_INSTALL_SPY] installDoms:', parsed.installDoms);
console.log('[WONDER_INSTALL_SPY] extid:', parsed.extid);
console.log('[WONDER_INSTALL_SPY] Full body:', JSON.stringify(parsed, null, 2));
}
} catch (e) {
console.error('[WONDER_INSTALL_SPY] Failed to parse body:', e);
}
}
return originalFetch(input, init);
};
console.log('[WONDER_INSTALL_SPY] Installed. Remove and reinstall Ad Block Wonder to capture the install payload.');
})();
- 1Open chrome://extensions, enable Developer mode.
- 2Click Ad Block Wonder's service worker link.
- 3Paste script in console, press Enter.
- 4Remove and reinstall.
- 5Watch for WONDER_INSTALL_INTERCEPT logs showing captured installDoms.
C2 Endpoint Versioned: All Data Now Routed to wonder57.php
Each run, the extension POSTs to wonderupdates.com/wonder57.php: install-time domains, current browsing domains, your allow/block lists, and a unique extension ID.
The response updates its behavior.
Captured live in dynamic analysis.
You install or restart the browser with the extension active.
The extension POSTs your browsing domains, allow/block lists, and extension ID to wonderupdates.com/wonder57.php.
The POST repeats on a server-controlled schedule (wondercycle). No user action is required after the initial install.
| Content-Type | application/json |
{
"extv": "5.7",
"installDoms": [
"google.com",
"facebook.com"
],
"navDoms": {
"facebook.com": 2,
"google.com": 1
},
"allowedDomains": [],
"blockedDomains": [],
"extid": "aaaljpolocgmoplhkppilcjeijjcaedg"
}| Field | Value | Why it matters | |
|---|---|---|---|
Extension instance ID | aaaljpolocgmoplhkppilcjeijjcaedg | A unique identifier for your specific installation, allowing the server to track you individually across sessions. | |
Domains open at install time | ["google.com", "facebook.com", "news.ycombinator.com"] | All website domains that were open in your browser when you installed the extension. | |
Navigation domain counts | {"facebook.com": 2, "google.com": 1} | A frequency map of domains you have navigated to since install, reveals your browsing habits. | |
User allow-list | ["myintranet.example.com"] | Sites you have manually allowed the extension to skip, revealing sites you chose to protect. | |
User block-list | ["ads.example.com"] | Custom domains you configured the extension to block. | |
Extension version | 5.7 | Which version of the extension is installed. |
Payload assembly in utils.js fetchData()
// src/helper/utils.js lines 66-143 (deobfuscated)
const neededKeys = [
"wonderinformation", "wondercycle", "wonderlevel",
"extv", "installDoms", "navDoms", "sid", "cid", "an"
];
let allStorageItems = await ch.storage.local.get(neededKeys);
// ...
wonderinformation.allowedDomains = allowedDomains;
wonderinformation.blockedDomains = blockedDomains;
wonderinformation.extid = ch.runtime.id;
const response = await httpClient.post(config.URLS.GET_RESOURCE, {
body: wonderinformation,
});- wonderupdates.com
C2 server operated by the extension developer. Receives browsing telemetry and returns dynamic configuration controlling rules, CSS injection, and scriptlet behavior.
+7 more findings not shown