Is Ad Blocker Pro Shield safe?
Ad Blocker Pro Shield assigns each installation a persistent identifier and sends it to its servers hourly, which can also push new blocking rules and DOM-manipulation scripts to the browser.
On installation, the extension contacts adblockerproshield.com to receive a unique key (ukey) that is stored locally and included in every subsequent hourly update request, allowing the server to track a specific installation over time. Each hour, the server can also deliver new declarativeNetRequest rules that replace all existing network-level rules, or update per-domain scriptlet configurations stored in chrome.storage.local. These server-pushed changes apply to any website the user visits without requiring a Chrome Web Store update.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Remote server pushes arbitrary network filter rules to all users
Every hour, the extension checks a server for updated rules and, if newer, downloads a file and replaces rules with whatever was sent, unvalidated.
Whoever controls the server can redirect or block traffic to any site, anytime, unnoticed.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-829
- Source
- Dynamic sandbox
Every hour, a background alarm fires and the extension checks for an updated rules file.
The check sends your installation key and current extension version to adblockerproshield.com.
If the server reports a newer version, it also supplies a URL; the extension downloads that URL and replaces all active network-filter rules with whatever the server sent.
The rules can block or redirect any website you visit. No user prompt or signature check occurs.
{"version":2,"url":"https://adblockerproshield.com/update/2/net_data.json","dynamicRules":[]}
Update handler, clears and replaces all dynamic rules unconditionally
// background.js:155-194const c = async () => { const { nextUpdate: t } = await chrome.storage.local.get({ nextUpdate: 0 }); if (Date.now() < t) return; let { extensionInstance: e, curNetRulesVersion: s } = await chrome.storage.local.get({ extensionInstance: "default", curNetRulesVersion: 0 }); // Fetch version check from server const n = await r(o.update + "?ukey=" + e + "&version=" + chrome.runtime.getManifest().version); if (n["version"] > s) { // Server-supplied URL is fetched with NO integrity check await l(await r(n.url)) } await chrome.storage.local.set({ curNetRulesVersion: n["version"], nextUpdate: Date["now"]() + 24 * 3600 * 1e3 })};const l = async t => { // Remove ALL existing dynamic rules const e = await chrome.declarativeNetRequest.getDynamicRules(); const s = e.map(t => t.id); const n = o(); await chrome.declarativeNetRequest.updateDynamicRules({ removeRuleIds: s, // clears every rule addRules: n // replaces with whatever the server sent }); await chrome.storage.local.set(t); // stores the entire server JSON function o() { // No validation — maps server-supplied rules directly return t.dynamicRules?.map((t, e) => { t["id"] = e + 1; return t }) }};- adblockerproshield.com
Primary update endpoint. Returns the current rule-set version and a URL to fetch the new rules file from.
Remote server controls what scripts run on any website you visit
The extension ships per-site configs for JS patching, loaded from bundled files at install.
The update server can overwrite these without a Store update.
The content script dispatches the config to MAIN-world scriptlets that patch APIs.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-829
- Source
- Dynamic sandbox
You navigate to any website while the extension is active.
The content script runs at document_start on every page load.
The extension reads a per-domain config from local storage and dispatches it to MAIN-world scriptlets that can intercept requests, patch APIs, and modify the page.
That configuration can have been without user notification rewritten by the remote server since your last browser start.
Update path that overwrites per-domain config, background.js:178-194
// background.js:178-194// Called after every successful update-check if the server reports a newer version.// 't' is the full parsed JSON body from the server-supplied net_data.json URL.const l = async t => { // 1. Replace dynamic DNR rules (covered by claim 10790) const e = await chrome.declarativeNetRequest.getDynamicRules(); const s = e.map(t => t.id); await chrome.declarativeNetRequest.updateDynamicRules({ removeRuleIds: s, addRules: t.dynamicRules?.map((t, e) => { t["id"] = e + 1; return t }) }); // 2. Write the ENTIRE server JSON object into chrome.storage.local. // Any key in the response — including per-domain keys like 'youtube.com', // 'facebook.com', 'sbs.com.au' — silently overwrites what was loaded // from the bundled hosts_*.json files at install time. await chrome.storage.local.set(t);};Scriptlet dispatch in content script, protection.js:97-101
// content-scripts/iworld/protection.js:97-101// processActive() is called with s.active — the 'active' array from the// per-domain chrome.storage.local object. Each entry is {scriptletName: params}.// The scriptlet name becomes the CustomEvent name fired into the MAIN world.processActive(t) { for (const e of t) { const s = Object.keys(e)[0]; // e.g. 'blockXhr', 'avoidWebRTC' invokeScriptlet(s, e[s]); // dispatches CustomEvent(s, {detail:{params:e[s]}}) }}Captured after the 2026-05-18 update. The server wrote empty placeholders for YouTube subdomains, matching 50,000+ entries' key shape.
- Location
- chrome.storage.local, per-domain keys written by server update
{ "youtube.com": {}, "dynamicRules": [], "m.youtube.com": {}, "tv.youtube.com": {}, "www.youtube.com": {}, "youtubekids.com": {}, "music.youtube.com": {}, "consent.youtube.com": {}}- adblockerproshield.com
Supplies the per-domain scriptlet configuration overwriting the bundled filter lists on every hourly update cycle.
Persistent install token sent to adblockerproshield.com on every update check
Each install gets a unique token (ukey) from adblockerproshield.com, stored permanently and sent hourly.
Tied to one install, letting the operator link update traffic to a single user.
DA captured 10 such requests across two installs.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-200
- Source
- Dynamic sandbox
You install the extension.
chrome.runtime.onInstalled fires with reason INSTALL.
The extension fetches a unique token from adblockerproshield.com and stores it permanently in your browser.
The token (ukey) is written to chrome.storage.local under the key extensionInstance and is never rotated.
Every 1 hour
Every 60 minutes the extension's alarm handler reads the stored ukey from chrome.storage.local and sends it to adblockerproshield.com/update/2/ alongside the extension version number.
Returns JSON with a version field (integer) and a url field pointing to the updated rules bundle. Observed in 10 captured requests across two install sessions.
- Installation token (ukey)a3f8c2d1e9b74056f3c1a8e2d0b74c91
A server-assigned identifier unique to your installation. It is never rotated; it stays the same for as long as the extension is installed.
- Extension version2.0.0.1
The installed version of the extension, sent alongside the token on every update check.
Hourly alarm handler, reads stored ukey and sends update request
// background.js:155-177const c = async () => { const { nextUpdate: t } = await chrome.storage.local.get({ nextUpdate: 0 }); if (Date.now() < t) return; let { extensionInstance: e, curNetRulesVersion: s } = await chrome.storage.local.get({ extensionInstance: "default", curNetRulesVersion: 0 }); const n = await r(o.update + "?ukey=" + e + "&version=" + chrome.runtime.getManifest().version); if (n["version"] > s) { await l(await r(n.url)) } await chrome.storage.local.set({ curNetRulesVersion: n["version"], nextUpdate: Date.now() + 24 * 3600 * 1e3 })};- adblockerproshield.com
Operator-controlled server that assigns the ukey on install, receives it on every hourly update check, and is notified on uninstall. Hosts the ad-blocking rules bundle.
What it can do
Permissions this extension asks for, as declared in version 2.0.0.1. 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>
Store data in your browser
storage
Store an unlimited amount of data in your browser
unlimitedStorage
Block and redirect the requests your browser makes
declarativeNetRequest
Run its own code inside the pages you visit
scripting
Schedule its own background tasks
alarms
Where it sends data
Destinations our analysis observed Ad Blocker Pro Shield 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.
- adblockerproshield.com
Ad Blocker Pro Shield sends data to adblockerproshield.com. No other extension we have analysed sends data here.