Is Ad Block Wonder safe?

High risk

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.…

Wonder Blockv5.8Chrome Web Store
75Risk
Who publishes it

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.

Publisher
Wonder Block

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.

analyzer.fc2.com
Also called by 4 other listings, including aBlock - Ads Blocker
ish.tumedia.no
Also called by 4 other listings, including aBlock - Ads Blocker, SBlock
rranking3.ziyu.net
Also called by 4 other listings, including aBlock - Ads Blocker
s1.aspservice.jp
Also called by 4 other listings, including SBlock
ssl-wolterskluwer.met.vgwort.de
Also called by 4 other listings, including aBlock - Ads Blocker
t.myvisualiq.net
Also called by 4 other listings, including SBlock
ziyu.net
Also called by 4 other listings, including SBlock

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-829
SourceAI SANDBOX

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.

01EvidenceCAUSE EFFECT
What actually happens
You did this

The developer's server sends the extension a URL and version number for a bulk rules file.

The extension did this

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.

02EvidenceNETWORK CAPTURE
Captured request
GEThttps://wonderupdates.com/compiled_rules.php?extid=kejigfhcnfgbejgnacjpehlledjlgpbf
HTTP 200. This URL, including the runtime-ID query parameter, was observed being fetched by the service worker immediately after the extension's remote-config POST vended a matching rulesUrl/rulesVersion pair.
03EvidenceFIELD TABLE
What the fetched rule set can do:
FieldValueWhy it matters
Which file is downloaded
https://wonderupdates.com/compiled_rules.phpThe address the rules are fetched from, determined by the server response, not fixed in the extension package.
Your extension's runtime ID
?extid=kejigfhcnfgbejgnacjpehlledjlgpbfSent 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 fetchA single downloaded rule set can name thousands of domains to redirect or block on your device, none reviewed by the Chrome Web Store.
04EvidenceCODE COMPARE
The code that does this

Bulk rules fetch and install (src/background.js)

What it actually does
Same logic, annotatedsrc/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 });
SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

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.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You install Ad Block Wonder from the Chrome Web Store.

The extension did this

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.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://wonderadblock.com/wonder-3_7.php
HTTP 200, server accepted the payload. Request sent twice during dynamic analysis, both confirmed 200.
Headers
Content-Typeapplication/json
Body
{
  "extv": "3.8",
  "installDoms": [
    "google.com",
    "facebook.com"
  ],
  "allowedDomains": [],
  "extid": "fpkbnjejghdcncegfglnapabnljcimdc"
}
03EvidenceFIELD TABLE
What Ad Block Wonder sends on install:
FieldValueWhy 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
fpkbnjejghdcncegfglnapabnljcimdcThe unique identifier for your installation of this extension. Can be used to track you across time.
Extension version
3.8Which version of the extension you installed.
Your personal allowlist
[]Domains you have explicitly whitelisted from ad blocking, also sent on every update request.
04EvidenceCODE COMPARE
The code that does this

The install-time tab collection code (src/helper/utils.js)

What it actually does
What the code does in plain terms
// 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
05EvidenceTHIRD PARTY LIST
Where the data ends up:
  • wonderadblock.com

    Developer-controlled server receiving every new install's tab-domain snapshot. Also serves subsequent configuration updates and is the uninstall reporting endpoint.

06EvidenceARTIFACT
Reproduce it yourself

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.

RequiresChrome with Developer mode enabled
adblock-wonder-install-intercept.js · js
// 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.');
})();
How to run it
  1. 1
    Open chrome://extensions, enable Developer mode.
  2. 2
    Click Ad Block Wonder's service worker link.
  3. 3
    Paste script in console, press Enter.
  4. 4
    Remove and reinstall.
  5. 5
    Watch for WONDER_INSTALL_INTERCEPT logs showing captured installDoms.
SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-506
SourceAI SANDBOX

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.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You install or restart the browser with the extension active.

The extension did this

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.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://wonderupdates.com/wonder57.php
HTTP 200. Server returns JSON with authorized keys: rulesUrl, rulesVersion, cosmeticCssUrl, cosmeticCssVersion, google_css_raw, google_css_js, wonderlevel, wonderinformation, wondercycle, scriptletDetailsUrl, scriptletDetailsVersion.
Headers
Content-Typeapplication/json
Body
{
  "extv": "5.7",
  "installDoms": [
    "google.com",
    "facebook.com"
  ],
  "navDoms": {
    "facebook.com": 2,
    "google.com": 1
  },
  "allowedDomains": [],
  "blockedDomains": [],
  "extid": "aaaljpolocgmoplhkppilcjeijjcaedg"
}
03EvidenceFIELD TABLE
Fields included in every POST to wonderupdates.com:
FieldValueWhy it matters
Extension instance ID
aaaljpolocgmoplhkppilcjeijjcaedgA 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.7Which version of the extension is installed.
04EvidenceCODE COMPARE
The code that does this

Payload assembly in utils.js fetchData()

What it actually does
// 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,
});
05EvidenceTHIRD PARTY LIST
Data destination:
  • 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

Updated 30 September 2026fpkbnjejghdcncegfglnapabnljcimdc