Is Smart Adblocker safe?

High risk

Smart Adblocker is high risk. Each POST to smartadblocker.com includes the previous page's URL in field 'dr'. Across four requests, 'dr' matched the prior 'url': google.com to amazon.com to facebook.com, letting the vendor reconstruct page order within a session.…

Smart Adblockerv3.4.5Chrome Web Store
78Risk

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

Publishers can request a review.

Findings

Per-Tab Referrer Chain Transmitted with Each Navigation Event

Each POST to smartadblocker.com includes the previous page's URL in field 'dr'.

Across four requests, 'dr' matched the prior 'url': google.com to amazon.com to facebook.com, letting the vendor reconstruct page order within a session.

Severity
High unwanted
Type
Unexpected
CWE
CWE-200
Source
Dynamic sandbox
What actually happens
You did this

You navigate to a second page in the same tab.

The extension did this

The extension reads the URL of the previous page from session storage and includes it as 'dr' (document referrer) in the POST to smartadblocker.com.

After each navigation, the new URL overwrites the stored value, so the next navigation will chain off of it. The session storage resets when the tab is closed.

Observed navigation sequence, each 'dr' field matches the prior request's 'url'
  1. Request 1

    You did

    Navigate to google.com

    The extension did

    POST: url=https://www.google.com/, dr=undefined (first navigation)

  2. Request 2

    You did

    Navigate to amazon.com

    The extension did

    POST: url=https://www.amazon.com/, dr=https://www.google.com/

  3. Request 3

    You did

    Navigate to facebook.com

    The extension did

    POST: url=https://www.facebook.com/, dr=https://www.amazon.com/

  4. Request 4

    You did

    Navigate to facebook.com/checkpoint

    The extension did

    POST: url=https://www.facebook.com/checkpoint/..., dr=https://www.facebook.com/

The code that does this

Referrer read, payload assembly, and referrer update (assets/index.js)

Readable version

Readable version

// D() = chrome.storage.session.get(key)// F() = chrome.storage.session.set({key: value})async function getTabReferrer(tabId) {  const referrers = await sessionGet('referrers') || {};  referrers[tabId] = referrers[tabId] || {};  return referrers[tabId];}// Inside onTabUpdated(tabId, tab):const tabReferrer = await getTabReferrer(tabId);const previousUrl = tabReferrer?.url;   // undefined on first navigationconst payload = base64Encode({  url: tab.url,  userId,  dr: previousUrl,  // sent as the 'document referrer'  plt: 0,  bc: blockedCount,  ts: Date.now()});// After POST: store current URL as referrer for the NEXT navigationconst referrers = await sessionGet('referrers') || {};referrers[tabId] = { url: tab.url };await sessionSet('referrers', referrers);
Scope of the referrer chain

The referrer chain is stored in `chrome.storage.session`, which resets when the browser closes. Navigation across different tabs does not chain — each tab maintains its own referrer entry keyed by tab ID. However, because the same persistent `userId` UUID appears in every request, the vendor can correlate navigation paths across sessions by matching that UUID.

Visited URL Transmitted to smartadblocker.com on Every Navigation

Dynamic analysis captured four POSTs from this ad blocker's worker to smartadblocker.com after each navigation.

Each body has the visited URL, a user ID, previous URL, blocked-ad count, and timestamp, base64-encoded, undisclosed in listing.

Severity
High unwanted
Type
Unexpected
CWE
CWE-200
Source
Dynamic sandbox
What actually happens
You did this

You navigate to any website while this extension is installed and active.

The extension did this

The extension encodes the URL you just visited, your persistent user ID, the previous URL for this tab, and a timestamp into a base64 payload, then POSTs it to smartadblocker.com.

Fires on every tab navigation that reaches status 'complete' and whose URL starts with 'http'. No allowlist or sampling, every page, every tab.

Captured request
POSThttps://smartadblocker.com/extension/rules/api/v2

Server optionally returns JSON with a 'rules' array of declarativeNetRequest dynamic rules; if present they are applied via updateDynamicRules().

Headers
credentials
include
Content-Type
application/json
Body
{  "payload": "eyJ1cmwiOiJodHRwczovL3d3dy5hbWF6b24uY29tLyIsInVzZXJJZCI6IjZhN2VjMGI4LWJhMGMtNDQzZi1hMTA1LWMyMTMwOTZjODBiZCIsImRyIjoiaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS8iLCJwbHQiOjAsImJjIjo0LCJ0cyI6MTc0NTk4MDQyNTExN30="}
Why you can't catch this in DevTools

The navigation data is JSON-serialized, URI-encoded, then base64-encoded before being placed in the 'payload' field. The encoding is reversible with standard browser APIs.

Decoded value
{  "url": "https://www.facebook.com/",  "userId": "6a7ec0b8-ba0c-443f-a105-c213096c80bd",  "dr": "https://www.amazon.com/",  "plt": 0,  "bc": 5,  "ts": 1745980438722}
Fields inside each transmitted payload
  • Page URL
    https://www.amazon.com/gp/cart/view.html

    The exact URL of the page you just navigated to, including any query parameters.

  • Persistent user ID
    6a7ec0b8-ba0c-443f-a105-c213096c80bd

    A UUID generated on install and stored permanently. Ties every navigation event to you across sessions.

  • Previous page URL
    https://www.google.com/search?q=laptop+deals

    The URL of the page you were on before this one in the same tab. Enables reconstruction of your navigation path.

  • Blocked ad count
    4

    Number of ads the extension blocked on this tab. Sent alongside the URL.

  • Timestamp
    1745980425117

    Unix millisecond timestamp of when the navigation completed.

The code that does this

Navigation listener and payload dispatch (assets/index.js)

Readable version

Readable version of the payload builder

// tn() = btoa(unescape(encodeURIComponent(JSON.stringify(data))))// Qe = "https://smartadblocker.com/extension/rules/api/v2"async function onTabUpdated(tabId, tab) {  const eulaAccepted = await getEulaAccepted();          // tt()  const userId = await localGet("userId");               // f()  const tabReferrer = await getTabReferrer(tabId);       // ln()  const previousUrl = tabReferrer?.url;  if (tab.url && tab.url.startsWith("http")) {    const blockedCount = await getBadgeCount(tabId);     // z()    const encodedPayload = base64Encode({      url: tab.url,      userId,      dr: previousUrl,      plt: 0,      bc: blockedCount,      ts: Date.now()    });    const enhancedProtection = await localGet("enhancedProtection");    if (encodedPayload && eulaAccepted && enhancedProtection === true) {      const response = await postJSON(RULES_API_URL, { payload: encodedPayload });      if (response?.rules) await applyDynamicRules(response.rules);    }    // Always update the referrer for next navigation    const referrers = await sessionGet("referrers") || {};    referrers[tabId] = { url: tab.url };    await sessionSet("referrers", referrers);  }}
Where the navigation data is sent
    • smartadblocker.com

    Extension vendor's server. Receives per-navigation POSTs with URL, user ID, referrer, and ad-blocked count. Also hosts the config endpoint (c.smartadblocker.com/configuration).

Persistent UUID Assigned at Install and Sent with Every Navigation

Dynamic analysis confirmed the UUID 6a7ec0b8-ba0c-443f-a105-c213096c80bd in every POST to smartadblocker.com across all four navigations (google, amazon, facebook), generated at install via randomUUID(), linking visits to one install.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-359
Source
Dynamic sandbox
What actually happens
You did this

You install or update the extension; this happens once.

The extension did this

The extension generates a unique identifier using crypto.randomUUID() and saves it permanently to chrome.storage.local as 'userId'.

This ID is then attached to every navigation event sent to smartadblocker.com for the lifetime of the extension install.

What's stored on your device

The persistent identifier assigned to your install. Read on every navigation and sent to smartadblocker.com with the URL you're visiting.

Location
chrome.storage.local key 'userId'
Contents
6a7ec0b8-ba0c-443f-a105-c213096c80bd
Captured request
POSThttps://smartadblocker.com/extension/rules/api/v2

Optionally returns dynamic blocking rules. The userId in the payload allows the server to attribute this and all prior navigation events to one install.

Headers
Content-Type
application/json
Body
{  "payload": "eyJ1cmwiOiJodHRwczovL3d3dy5mYWNlYm9vay5jb20vIiwidXNlcklkIjoiNmE3ZWMwYjgtYmEwYy00NDNmLWExMDUtYzIxMzA5NmM4MGJkIiwiZHIiOiJodHRwczovL3d3dy5hbWF6b24uY29tLyIsInBsdCI6MCwiYmMiOjUsInRzIjoxNzQ1OTgwNDM4NzIyfQ=="}
The code that does this

UUID generation and persistence (assets/index.js)

Readable version

Readable version

// f() = chrome.storage.local.get(key)// G() = chrome.storage.local.set({key: value})async function initializeUserId() {  const existingId = await localGet('userId');  if (existingId) return existingId;          // reuse existing — never regenerates  const newId = crypto.randomUUID();  await localSet('userId', newId);  return newId;}// Called from both://   chrome.runtime.onInstalled (line 1438)//   chrome.runtime.onStartup   (line 1471)
Updated 30 September 2026iojpcjjdfhlcbgjnpngcmaojmlokmeii