Is North Ad-Block safe?

Critical risk

North Ad-Block transmits open-tab domains to its server on install and allows that server to push arbitrary JavaScript into every browsed page.

On installation, the extension collects the hostnames of all open browser tabs and sends them to api.n-adb.com, then continues forwarding per-site ad-block counts and tab domains every 60 seconds. The server can respond with inline JavaScript code that the extension injects and executes in the main world of each page the user visits, giving the server full access to page content, credentials, and session data. A separate message handler in the content script accepts storage writes from any web page without validating the origin, which can allow a malicious site to overwrite authentication tokens used by the extension.

x00lyx00v1.0.22Chrome Web Store
97Risk

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

Publishers can request a review.

Findings

The vendor server can run arbitrary JavaScript on every site you visit

CriticalunwantedCWE-829Dynamic sandbox

This ad blocker periodically checks in with api.n-adb.com.

What actually happens

You did this

The vendor server replies to a routine check-in with a header that points to a rules file.

The x-fetch-scriptlets header on the /heartbeat response tells the extension to download /rules/scriptlets.txt.

The extension did this

On your next page load, JavaScript from that file runs inside the page with the same access the website's own scripts have.

Lines marked with #%# are stored as inline code and executed in the page's MAIN world.

The code that does this

Server-supplied lines are parsed as JavaScript, then executed in the page

Readable version

The chain, in plain terms

// 1. Routine /heartbeat reply includes x-fetch-scriptlets.// 2. Extension downloads /rules/scriptlets.txt from the same server.// 3. Any line like  example.com#%#<JS>  is stored as runnable code for example.com.// 4. When you open example.com, the extension runs <JS> in the page's//    MAIN world via new Function(<JS>) - same access as the page's own scripts.// 5. The content script is granted <all_urls>, so this works on any site.

Reproduce it yourself

Shows the exact storage shape the extension produces from a server-supplied scriptlets.txt line, and the line of server text that produces it. Confirms a single server-controlled line becomes JavaScript that runs in the page.

scriptlets-rule-shape.js · js
// A single line in /rules/scriptlets.txt served by api.n-adb.com:const serverLine = "example.com#%#window.__marker='ran'; document.title='changed';";// transformScriptletTextToObject() turns that line into this storage entry:const storedRule = {  "scriplet_example.com": [    {      code: "window.__marker='ran'; document.title='changed';",      isOnlyForMainFrame: false,      type: "inline"    }  ]};// On navigation to example.com, adBlocking.js executes, in the page's MAIN world://   new Function(storedRule['scriplet_example.com'][0].code)()// i.e. the server-supplied string runs as page JavaScript.console.log(JSON.stringify(storedRule, null, 2));
How to run it
  1. 1Run: node scriptlets-rule-shape.js.
  2. 2Compare output to the shape from transformScriptletTextToObject() in rulesManager.js.
  3. 3The 'code' value runs via new Function() in the page's MAIN world by executeScriptletInjections().

Why MAIN-world execution matters

Code run in the MAIN world shares the page's JavaScript context. It can read and modify anything the website's own scripts can: page content, form inputs, and the logged-in session for whatever site you are on. Because the content script is granted access to all URLs, the same mechanism applies to every site you visit, and the code that runs is chosen by the server at request time rather than fixed in the published extension.

Domains of every open tab sent to api.n-adb.com the moment you install

HighunwantedCWE-200Dynamic sandbox

On install, this ad blocker reads every open tab's domain (e.g. chatgpt.com, x.com) and sends that list in its first request to api.n-adb.com.

What actually happens

You did this

You install the ad blocker while other tabs are already open.

The extension did this

The extension reads the domain of every open tab and sends that list to its vendor server.

It runs chrome.tabs.query({}) on the install event, skips chrome:// and extension pages, and keeps the unique domain of every other tab.

The code that does this

The install handler collects open-tab domains and includes them in the first server request

Readable version

What it does, in plain terms

// 1. On install, list every open tab.// 2. Throw away chrome:// and extension URLs.// 3. Reduce each remaining URL to its domain (chatgpt.com, x.com).// 4. Save that list, then POST it to https://api.n-adb.com/initialize//    inside the initialTabDomains field of the first request body.

Captured request

POSThttps://api.n-adb.com/initialize

Observed during dynamic analysis with chatgpt.com and x.com open at install time. The server returned 204 and the same initialTabDomains list was retained for later requests.

Headers
Content-Type
application/json
Body
{  "blockedCounts": {},  "initialTabDomains": [    "chatgpt.com",    "x.com"  ]}

What the install request reveals about you

  • Domains of your open tabs
    ["chatgpt.com", "x.com"]

    The website of every tab you had open when you installed the ad blocker, captured as a one-time snapshot of what you were doing.

Open-tab domains and per-site block counts sent to api.n-adb.com on a timer

MediumunwantedCWE-200Dynamic sandbox

Beyond the install report, this ad blocker posts to api.n-adb.com/heartbeat roughly every 60 seconds, an interval the server can change.

What actually happens

You did this

A repeating alarm fires roughly once a minute.

configureSynchronizationAlarm sets the period; the server can change it via x-heartbeat-interval.

The extension did this

The extension sends your install-time tab domains and per-site block counts to its vendor server.

buildTelemetryPayload assembles the report and POSTs it to api.n-adb.com/heartbeat.

When this fires

Every 1 minute

A synchronization alarm POSTs a telemetry payload to api.n-adb.com/heartbeat about every 60 seconds. The interval defaults to 60s and is overridden by the x-heartbeat-interval header the server returns, so the vendor controls how often reporting happens.

Captured request

POSThttps://api.n-adb.com/heartbeat

Observed during dynamic analysis: repeated POSTs to api.n-adb.com/heartbeat over the session, each carrying initialTabDomains and a blockedCounts map. The response may set x-heartbeat-interval to re-time future reports.

Headers
Content-Type
application/json
Authorization
Bearer <redacted>
Body
{  "blockedCounts": {},  "initialTabDomains": [    "chatgpt.com",    "x.com"  ]}

What each heartbeat reports

  • Install-time tab domains
    ["chatgpt.com", "x.com"]

    The domains of the tabs you had open when the extension was installed, re-sent on every heartbeat.

  • Per-site block counts
    {"nytimes.com": 14, "youtube.com": 7}

    How many ad requests were blocked on each site. Because counts only accrue on sites you open, this map reveals which sites you visit.

What it can do

Permissions this extension asks for, as declared in version 1.0.22. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.

  • Read and change your data on every site you visit

    <all_urls>

  • Schedule its own background tasks

    alarms

  • Block and redirect the requests your browser makes

    declarativeNetRequest

  • Run its own code inside the pages you visit

    scripting

  • Store data in your browser

    storage

  • See the address and title of every tab you have open

    tabs

  • Store an unlimited amount of data in your browser

    unlimitedStorage

  • See every page you navigate to, as you navigate to it

    webNavigation

Where it sends data

Destinations our analysis observed North Ad-Block contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.

  • api.n-adb.com

    North Ad-Block sends data to api.n-adb.com. No other extension we have analyzed sends data here.

Updated 2 November 2026bmgfhambolgekpleooignbnnpdcnlien