Is Popup Blocker Pro safe?
Popup Blocker Pro is high risk. Every navigation, Popup Blocker Pro sends the visited URL, referrer, and a persistent install ID to data.popup-blocker.org. 3 POSTs were captured with URL, referrer, ID, timestamps, firing on every navigation, every site, no consent prompt.…
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Browsing History Transmitted to data.popup-blocker.org on Every Navigation
Every navigation, Popup Blocker Pro sends the visited URL, referrer, and a persistent install ID to data.popup-blocker.org. 3 POSTs were captured with URL, referrer, ID, timestamps, firing on every navigation, every site, no consent prompt.
You navigate to any web page in any tab.
The extension sends the full URL, the URL you came from, and a persistent identifier tied to your install to data.popup-blocker.org.
This happens on every main-frame navigation, every site, every tab, without any user action beyond normal browsing.
| Content-Type | application/json;charset=utf-8 |
{
"fileDate": "2026-04-14T10:23:41.112Z",
"deviceTimestamp": 1744626221112,
"userId": "fe0916f3-1ff9-4931-b5ae-7ed70956b98f",
"referrerUrl": "https://www.google.com/",
"targetUrl": "https://www.google.com/account/about/",
"requestType": "GET",
"userIdSync": "fe0916f3-1ff9-4931-b5ae-7ed70956b98f"
}| Field | Value | Why it matters | |
|---|---|---|---|
The URL you visited | https://www.google.com/account/about/ | The exact page address you navigated to, including any query parameters. | |
The URL you came from | https://www.google.com/ | Where you were before this page, either the referring URL or the tab's initiator origin. | |
Your persistent user ID | fe0916f3-1ff9-4931-b5ae-7ed70956b98f | A UUID generated once when you install the extension and stored permanently. It links all your page visits together across sessions. | |
Your synced user ID | fe0916f3-1ff9-4931-b5ae-7ed70956b98f | A second UUID also stored in Chrome's sync storage, survives reinstalls if you're signed into Chrome. | |
HTTP method | GET | Whether the page load was a GET or POST request. | |
Device timestamp | 1744626221112 | The exact time on your device when the navigation completed, to the millisecond. | |
ISO timestamp | 2026-04-14T10:23:41.112Z | The same moment expressed as an ISO 8601 date-time string. |
The navigation listener and payload sender from the extension's shipping source (sw.js):
// Fires for every completed main-frame request across ALL URLs.
// There is no allowlist — every site triggers the handler.
chrome.webRequest.onCompleted.addListener(sendBrowsingHistory, {
urls: ['<all_urls>'],
types: ['main_frame']
});// Called on every page navigation.
async function sendBrowsingHistory(requestDetails) {
const localUUID = await localStore.get('uuid'); // persistent, device-local UUID
const syncedUUID = await syncStore.get('uuid'); // same UUID in Chrome sync storage
const refMap = await localStore.get('stats_refs') || {};
await postToServer({
fileDate: new Date().toISOString(), // ISO timestamp
deviceTimestamp: Date.now(), // ms since epoch
userId: localUUID, // identifies this browser install
referrerUrl: refMap[requestDetails.tabId] || requestDetails.initiator,
targetUrl: requestDetails.url, // the page you just loaded
requestType: requestDetails.method, // 'GET'
userIdSync: syncedUUID
});
// Update refMap so the next navigation on this tab gets this URL as its referrer.
refMap[requestDetails.tabId] = requestDetails.url;
chrome.storage.local.set({ stats_refs: refMap });
}- data.popup-blocker.org
Receives a POST containing the visited URL, referrer URL, and persistent UUID on every main-frame navigation. Operated by the Popup Blocker Pro developer.
Web Requests Bulk-Logged on Amazon, Walmart, Target, and 13 Other Sites
On Amazon, Walmart, Target, Costco, and 16 other sites, a click opens a 2-second window where it logs every web request (URL, IP, method, status), bulk-sent to data.popup-blocker.org/ajax with your user ID.
A POST held 19+ items.
You click on any element on Amazon, Walmart, Target, Costco, or one of 13 other retail and grocery sites.
The extension records every web request for 2 seconds after a click, then bulk-sends the records (URLs, IPs, status codes) to data.popup-blocker.org/ajax with your user ID.
The logging window is triggered by a message from the content script on click. When the request count reaches 20 or 300 seconds have elapsed since the last flush, all accumulated records are sent.
| Accept | application/json |
| Content-Type | application/json |
{
"userId": "d57b25b9-49c5-4282-b685-dc6c156f9b39",
"fileDate": "2026-04-14T11:45:03.217Z",
"deviceTimestamp": 1744630703217,
"requests": [
{
"url": "https://www.amazon.com/dp/B09V3KXJPQ",
"tabUrl": "https://www.amazon.com/",
"ip": "52.94.236.131",
"method": "GET",
"statusCode": 200
},
{
"url": "https://fls-na.amazon.com/1/action-impressions",
"tabUrl": "https://www.amazon.com/",
"ip": "54.230.128.43",
"method": "POST",
"statusCode": 200
},
{
"url": "https://completion.amazon.com/api/2017/suggestions",
"tabUrl": "https://www.amazon.com/",
"ip": "176.32.98.166",
"method": "GET",
"statusCode": 200
}
]
}| Field | Value | Why it matters | |
|---|---|---|---|
Request URL | https://completion.amazon.com/api/2017/suggestions?search-alias=aps&q=headphones | The exact URL of every network request your browser made during the 2-second window after your click. | |
Tab URL | https://www.amazon.com/ | The page you were on when the request was made, identifies which shopping page you were viewing. | |
Server IP address | 52.94.236.131 | The IP address of the server your browser contacted. | |
HTTP method | GET | Whether the request was a GET or POST. | |
HTTP status code | 200 | Whether the request succeeded. | |
Your persistent user ID | d57b25b9-49c5-4282-b685-dc6c156f9b39 | The same UUID sent with every other request from this extension. Links these shopping records to your browsing history. |
The hardcoded list of sites that activate request logging (from `config.loggingSites` in sw.js):
**US:** amazon.com, walmart.com, kroger.com, target.com, petco.com, chewy.com, instacart.com, petsmart.com, costco.com, samsclub.com, walgreens.com, checkadblock.ru
**Canada:** amazon.ca, walmart.ca, loblaws.ca
**UK:** amazon.co.uk, tesco.com, ocado.com, asda.com
Logging is not active on other sites.
The click-triggered logging system from the extension's shipping source (sw.js):
// When the user is on any of these origins AND clicks an element, // all subsequent web requests are captured for 2 seconds. const LOGGED_SHOPPING_SITES = [ 'https://www.amazon.com', // US Amazon 'https://www.walmart.com', // US Walmart 'https://www.target.com', // US Target 'https://www.costco.com', // US Costco 'https://www.kroger.com', // US Kroger 'https://www.samsclub.com', // US Sam's Club 'https://www.walgreens.com', // US Walgreens 'https://www.chewy.com', // US Chewy 'https://www.petco.com', // US Petco 'https://www.petsmart.com', // US PetSmart 'https://www.instacart.com', // US Instacart 'https://www.amazon.ca', // CA Amazon 'https://www.walmart.ca', // CA Walmart 'https://www.loblaws.ca', // CA Loblaws 'https://www.amazon.co.uk', // UK Amazon 'https://www.tesco.com', // UK Tesco 'https://www.asda.com', // UK Asda 'https://www.ocado.com', // UK Ocado 'https://checkadblock.ru', // checkadblock.ru ];
function flushIfThresholdMet() {
const now = Date.now();
const fiveMinutesPassed = (now - lastFlushTime) / 1000 >= 300;
const twentyRequestsAccumulated = pendingRequests.length >= 20;
if (pendingRequests.length > 0 && (fiveMinutesPassed || twentyRequestsAccumulated)) {
const batch = Array.from(pendingRequests);
setTimeout(async () => {
await postToServer({
userId: await localStore.get('uuid'),
fileDate: new Date().toISOString(),
deviceTimestamp: Date.now(),
requests: batch // array of {url, tabUrl, ip, method, statusCode, ...}
});
}, 250);
pendingRequests = [];
lastFlushTime = now;
}
}- data.popup-blocker.org
Receives a bulk POST of web requests made on monitored shopping sites within the capture window, plus the user's UUID. Operated by the Popup Blocker Pro developer.
Blocking Rules Fetched from Remote Server and Updated Every 60 Seconds
Every 60 seconds, it fetches api.popup-blocker.org/settings for a whitelist (skips popup blocking) and blacklist (scripts blocked), applied at once, overriding local settings.
The server adds/removes domains freely; 5 GETs seen.
Every 60 seconds, the extension contacts api.popup-blocker.org/settings.
This starts immediately on extension startup and repeats indefinitely.
The server returns whitelist/blacklist arrays, applied immediately: whitelisted domains skip popup blocking; blacklisted domains get scripts blocked via declarativeNetRequest.
If the server returns different lists on the next poll, the extension updates its blocking rules accordingly, no user interaction needed.
| Extension | kiodaajmphnkcajieajajinghpejdjai |
| X-Requested-With | XMLHtpRequest |
| Extension-Version | 2.0.5 |
After each fetch, the extension stores the whitelist/blacklist locally, controlling which domains skip blocking or get scripts blocked.
chrome.storage.local keys 'pb_defaultWhitelist' and 'pb_defaultBlacklist'{
"pb_defaultBlacklist": [
"competitor-adnetwork.com",
"unwanted-tracker.net"
],
"pb_defaultWhitelist": [
"example-partner.com",
"sponsored-site.com"
]
}The remote configuration fetch and application logic (sw.js):
// Runs immediately on startup and then every 60 seconds.
async function updateSettings() {
const response = await fetch('https://api.popup-blocker.org/settings', {
headers: {
'Extension': extensionId, // identifies this extension to server
'Extension-Version': extensionVersion,
'X-Requested-With': 'XMLHtpRequest', // note: typo in source ('XMLHtpRequest')
}
}).then(r => r.json());
// If the server returned new lists, overwrite local copies immediately.
if (response.data.whitelist) {
await chrome.storage.local.set({
pb_defaultWhitelist: response.data.whitelist, // domains exempt from popup blocking
pb_defaultBlacklist: response.data.blacklist // domains whose scripts get blocked
});
}
// Apply the new blacklist as a live DNR rule.
await applyBlacklistRule();
// Schedule the next poll.
setTimeout(updateSettings, 60_000);
}// Replaces rule ID 1 with a block rule for all domains in the server-controlled blacklist.
async function applyBlacklistRule() {
const blacklist = await localStore.get('pb_defaultBlacklist');
chrome.declarativeNetRequest.updateDynamicRules({
removeRuleIds: [1],
addRules: [{
id: 1,
priority: 1,
action: { type: 'block' },
condition: {
requestMethods: ['get'],
requestDomains: blacklist, // ← list comes entirely from the remote server
domainType: 'thirdParty',
resourceTypes: ['script'],
}
}]
});
}- api.popup-blocker.org
Provides whitelist/blacklist arrays every 60 seconds, controlling which domains skip popup blocking and which have scripts blocked. Operated by the Popup Blocker Pro developer.
+1 more finding not shown