Is Ad Blocker Pro - block ads ad blocker safe?
Ad Blocker Pro reports which sites it blocked ads on, and every Google search you run, to its own server every 4 hours.
Whenever the extension's filters remove an ad or tracker element from a page, and whenever you run a search on Google, it records the site's hostname (and the search timestamp) in local storage. Every 4 hours it bundles up that history and sends it to proadblocker.com, tagged with a persistent install ID issued when the extension was first installed, so the reports can be tied together as one installation over time.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Ad-blocked sites and Google searches sent to the vendor every 4 hours
We observed the extension log which sites it blocked ads on and when you opened Google search, then send that history to its own proadblocker.com server every four hours, tied to a persistent installation ID.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You browse a site where the extension's filters remove an ad or tracker element, or you open a Google search results page.
This happens on ordinary browsing; no extension setting needs to be changed.
The extension records the site's hostname and how many elements it blocked there, or the search visit, for later upload.
A content script message tells the service worker to log the hit against that hostname.
- Sites where ads were blocked{"edition.cnn.com": [[1757272045123, 9]], "forbes.com": [[1757272051876, 4]]}
Every hostname you visited where the extension removed page content, paired with how many elements it blocked there.
- Google search visits[1757272060015, 1757272391542]
A timestamp recorded every time you open a Google search results page.
- Your installation IDb6f2a911-4d3e-4a08-9c77-2e15f0a8d611
A persistent ID the vendor's own server assigned to your install. It ties every upload back to the same install over time.
- Extension IDnigoagcimgiifniljaedijgilbfdplbb
The Chrome Web Store ID for this extension, sent alongside your installation ID on every request.
This is the local queue the extension builds up between uploads. It is cleared only once the periodic upload to the vendor succeeds.
- Location
- chrome.storage.local keys _stats_ab and _stats_search_ts
{ "_stats_ab": { "forbes.com": [ [ 1757272051876, 4 ], [ 1757272070001, 4 ] ], "edition.cnn.com": [ [ 1757272045123, 9 ] ] }, "_stats_search_ts": [ 1757272060015, 1757272391542 ]}Every 4 hours
Regardless of how much has queued up, a chrome.alarms trigger named sendStatsAlarm fires every four hours and uploads whatever is queued.
200 OK. On success the extension clears its local _stats_ab and _stats_search_ts queues.
- Content-Type
- application/json
{ "adblock": { "edition.cnn.com": [ [ 1757272045123, 9 ] ], "forbes.com": [ [ 1757272051876, 4 ], [ 1757272070001, 4 ] ], "google.com": [ [ 1757272090442, 7 ], [ 1757272110981, 7 ] ] }, "inst_id": "b6f2a911-4d3e-4a08-9c77-2e15f0a8d611", "search_timestamps": [ 1757272060015, 1757272391542 ], "crx": "nigoagcimgiifniljaedijgilbfdplbb"}Registering a persistent install ID, then using it on every periodic upload
Register call (deobfuscated)
abp_service_worker.js:180-239async function ge() { let { iid: t } = await chrome.storage.local["get"]({ iid: null }); if (!(t && t !== "default")) { e(); function e() { Event["currentTarget"] } } else { return t } try { const o = await fetch(Y, { credentials: "include", body: JSON["stringify"]({ version: pe, crx: chrome["runtime"].id }), method: "POST", headers: { "Content-Type": "application/json" } }); if (!o["ok"]) { throw new Error(`register returned HTTP ${o["status"]}`) } const i = await o.json(); n(); function n() { t = i["iid"] || "default" } } catch (e) { r(); function r() { t = "default" } } if (t === "default") { const { iidFailedSince: ah } = await chrome["storage"]["local"]["get"]({ iidFailedSince: 0 }); await chrome["storage"]["local"].set({ iid: t, iidFailedSince: ah || Date["now"]() }) } else { await chrome["storage"]["local"].set({ iid: t, iidFailedSince: 0 }) } return tPeriodic-send + alarm setup (deobfuscated)
abp_service_worker.js:1422-1478async function De() { await Ie(); function e() { return t[S] } const t = await chrome.storage.local.get({ [x]: [], [S]: {} }); const n = t[x]; const r = e(); if (n["length"] === 0 && Object.keys(r).length === 0) { return } try { const o = await ve(); if (o === "default") { const { iidFailedSince: ai } = await chrome["storage"]["local"]["get"]({ iidFailedSince: 0 }); if (!ai || Date["now"]() - ai < ag) { return } } const i = await fetch(te, { headers: { "Content-Type": "application/json" }, method: "POST", body: JSON["stringify"]({ adblock: r, inst_id: o || "default", search_timestamps: n, crx: chrome["runtime"].id }) }); if (!i["ok"]) { return } await chrome["storage"]["local"]["set"]({ [x]: [], [S]: {} }) } catch (e) {}}async function _e() { const e = await chrome.alarms.get("sendStatsAlarm"); if (!e) { await chrome.alarms.create("sendStatsAlarm", { periodInMinutes: 240, delayInMinutes: 240 }) }}- proadblocker.com
The extension vendor's own server. Issues the persistent install ID and receives the periodic stats upload plus the install/uninstall pings, all keyed to that ID.
Where it sends data
Destinations our analysis observed Ad Blocker Pro - block ads ad blocker 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.
- proadblocker.com
Ad Blocker Pro - block ads ad blocker sends data to proadblocker.com. No other extension we have analyzed sends data here.