Is Popup Blocker Max safe?

Medium risk

Popup Blocker Max sends a unique per-user token and Google search counts to its server hourly and downloads unverified blocking rules from that server.

Every hour, the extension transmits a persistent per-user identifier, a count of popups blocked, and a count of Google searches performed to popupblockermax.com. It also fetches its entire set of network-blocking rules from server-controlled URLs at that same endpoint, replacing all existing rules with whatever the server returns, with no signature or integrity check.

Popup Blocker Maxv1.1.1.2Chrome Web Store
48Risk

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

Publishers can request a review.

Findings

Daily beacon sends per-user token and usage counts to popupblockermax.com

MediumunwantedCWE-359Dynamic sandbox

Once daily, Popup Blocker Max GETs popupblockermax.com with a per-install token, runtime ID, popups blocked, and Google visits since last update.

What actually happens

You did this

You install Popup Blocker Max and use it normally.

No special action required, the beacon fires on a daily schedule regardless of what pages you visit.

The extension did this

Once per day, the extension sends your unique installation token and accumulated usage counts to popupblockermax.com.

The request includes a persistent identifier the server assigned at install time, allowing the developer to track each installation across days and browser restarts.

Captured request

GEThttps://popupblockermax.com/r/filters/?extID=chlalkigiloegdhejmihamhibleebceb&bcounter=3&scounter=7&ucounter=0&mark=<planted-marker-value>

JSON array of filter-list update objects. Extension uses response to update declarativeNetRequest rules. A planted marker value was confirmed verbatim in the captured request URL, confirming the mark parameter leaves the device.

Query parameters sent with every daily beacon

  • Your installation token (mark)
    <planted-marker-value>

    Server-assigned ID stored at install, sent with every update request. Lets the server recognize your install across restarts and updates.

  • Extension runtime ID (extID)
    chlalkigiloegdhejmihamhibleebceb

    The Chrome-assigned runtime ID for this install of the extension. Changes on reinstall but is stable across browser restarts.

  • Blocked popup count (bcounter)
    3

    How many popups the extension blocked since the previous daily update. Reveals relative browsing activity.

  • Google search count (scounter)
    7

    How many times you visited a google.*/search page since the previous daily update.

  • Update cycle count (ucounter)
    0

    Computed from elapsed time since lastUpdate. Represents the approximate number of missed update windows.

The code that does this

The URL builder and updater function from the extension's service worker:

Readable version

Beacon URL builder

// Builds the telemetry URL with usage counters and persistent token const buildBeaconUrl = async (baseUrl, extensionInstance) => { let url = baseUrl; url += '?extID=' + chrome.runtime.id; // runtime ID const { blockedCounter, searchCounter, lastUpdate } = await chrome.storage.local.get({ blockedCounter: 0, searchCounter: 0, lastUpdate: 0 }); const updateCounter = !lastUpdate ? 0 : parseInt(Date.now() - lastUpdate / 3600000); url += '&bcounter=' + blockedCounter; // popup blocks since last update url += '&scounter=' + searchCounter; // Google search visits since last update url += '&ucounter=' + updateCounter; if (extensionInstance) { url += '&mark=' + extensionInstance; // persistent per-install server token } return url; };

Updater with 24h guard and counter reset

// Alarm fires hourly; updater checks nextUpdate guard (24h window) await chrome.alarms.create('updater', { delayInMinutes: 60, periodInMinutes: 60 }); const updater = async () => { const { nextUpdate } = await chrome.storage.local.get({ nextUpdate: 0 }); if (Date.now() < nextUpdate) return; // skip if < 24h since last update const { extensionInstance } = await chrome.storage.local.get(['extensionInstance']); const response = await fetch(await buildBeaconUrl(BASE_URL + '/r/filters/', extensionInstance)); // ... process filter updates ... await chrome.storage.local.set({ nextUpdate: Date.now() + 24 * 3600 * 1e3, // next fire in 24h blockedCounter: 0, searchCounter: 0 }); };

Where the beacon data is sent

    • popupblockermax.com

    Developer's own domain. Receives the daily beacon with the install token and usage counters. Also serves filter-list updates in the same response.

What it can do

Permissions this extension asks for, as declared in version 1.1.1.2. 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

  • See which of your requests its blocking rules matched

    declarativeNetRequestFeedback

  • Run its own code inside the pages you visit

    scripting

  • Schedule its own background tasks

    alarms

  • Watch every request your browser makes

    webRequest

Where it sends data

Destinations our analysis observed Popup Blocker Max 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.

  • popupblockermax.com

    Popup Blocker Max sends data to popupblockermax.com. No other extension we have analyzed sends data here.

Updated 30 September 2026ajjpfpfbgjcgghkgbcgmifkonjdldgkh