Is Popup Blocker Pro safe?

High risk

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.…

Popup Blocker Prov3.0.6Chrome Web Store
75Risk

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

Publishers can request a review.

Findings

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

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.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You navigate to any web page in any tab.

The extension did this

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.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://data.popup-blocker.org/process
Our dynamic analysis captured 3 POST requests to this endpoint. Browsing history was transmitted on every main_frame navigation.
Headers
Content-Typeapplication/json;charset=utf-8
Body
{
  "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"
}
03EvidenceFIELD TABLE
What Popup Blocker Pro sends on every page you visit:
FieldValueWhy 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-7ed70956b98fA 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-7ed70956b98fA second UUID also stored in Chrome's sync storage, survives reinstalls if you're signed into Chrome.
HTTP method
GETWhether the page load was a GET or POST request.
Device timestamp
1744626221112The exact time on your device when the navigation completed, to the millisecond.
ISO timestamp
2026-04-14T10:23:41.112ZThe same moment expressed as an ISO 8601 date-time string.
04EvidenceCODE COMPARE
The code that does this

The navigation listener and payload sender from the extension's shipping source (sw.js):

What it actually does
Registers a listener on every completed top-level navigation
// 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']
});
Collects URL + referrer + two persistent UUIDs and POSTs them
// 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 });
}
05EvidenceTHIRD PARTY LIST
Where your browsing history is sent:
  • 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.

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

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.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You click on any element on Amazon, Walmart, Target, Costco, or one of 13 other retail and grocery sites.

The extension did this

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.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://data.popup-blocker.org/ajax
Captured during dynamic analysis after clicking on an Amazon navigation element. Request body contained 19+ request objects with url, tabUrl, ip, method, and statusCode from the Amazon browsing session.
Headers
Acceptapplication/json
Content-Typeapplication/json
Body
{
  "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
    }
  ]
}
03EvidenceFIELD TABLE
What each logged request record contains:
FieldValueWhy it matters
Request URL
https://completion.amazon.com/api/2017/suggestions?search-alias=aps&q=headphonesThe 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.131The IP address of the server your browser contacted.
HTTP method
GETWhether the request was a GET or POST.
HTTP status code
200Whether the request succeeded.
Your persistent user ID
d57b25b9-49c5-4282-b685-dc6c156f9b39The same UUID sent with every other request from this extension. Links these shopping records to your browsing history.
04EvidencePLAIN NOTE
Which sites trigger logging

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.

05EvidenceCODE COMPARE
The code that does this

The click-triggered logging system from the extension's shipping source (sw.js):

What it actually does
Hardcoded list of 16 retail/grocery sites that trigger request logging
// 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
];
Bulk flush: sends accumulated requests when 20+ collected or 5 minutes elapsed
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;
  }
}
06EvidenceTHIRD PARTY LIST
Where shopping activity data is sent:
  • 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.

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-829
SourceAI SANDBOX

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.

01EvidenceCAUSE EFFECT
What actually happens
You did this

Every 60 seconds, the extension contacts api.popup-blocker.org/settings.

This starts immediately on extension startup and repeats indefinitely.

The extension did this

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.

02EvidenceNETWORK CAPTURE
Captured request
GEThttps://api.popup-blocker.org/settings
Our dynamic analysis observed 5 GET requests to this endpoint at approximately 60-second intervals. The extension's storage showed pb_defaultWhitelist and pb_defaultBlacklist being populated with server-provided data after each response.
Headers
Extensionkiodaajmphnkcajieajajinghpejdjai
X-Requested-WithXMLHtpRequest
Extension-Version2.0.5
03EvidenceSTORAGE DUMP
What's stored on your device

After each fetch, the extension stores the whitelist/blacklist locally, controlling which domains skip blocking or get scripts blocked.

Locationchrome.storage.local keys 'pb_defaultWhitelist' and 'pb_defaultBlacklist'
Contents (JSON)
{
  "pb_defaultBlacklist": [
    "competitor-adnetwork.com",
    "unwanted-tracker.net"
  ],
  "pb_defaultWhitelist": [
    "example-partner.com",
    "sponsored-site.com"
  ]
}
04EvidenceCODE COMPARE
The code that does this

The remote configuration fetch and application logic (sw.js):

What it actually does
Polls remote server every 60 seconds for updated blocking rules
// 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);
}
Applies blacklisted domains as a Chrome declarativeNetRequest script-blocking rule
// 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'],
      }
    }]
  });
}
05EvidenceTHIRD PARTY LIST
Remote configuration server:
  • 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.

Updated 20 September 2026kiodaajmphnkcajieajajinghpejdjai