Is Adblock Fortress safe?

High risk

Adblock Fortress is high risk. The extension lets the operator replace all active blocking rules with whatever list the server returns, no update or notice needed. The operator could disable blocking on specific sites, redirect requests, or change what's blocked anytime.…

DevFortressv2.0.1Chrome 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-829
SourceAI SANDBOX

Operator can replace all network-blocking rules via remote server

The extension lets the operator replace all active blocking rules with whatever list the server returns, no update or notice needed.

The operator could disable blocking on specific sites, redirect requests, or change what's blocked anytime.

01EvidenceCAUSE EFFECT
What actually happens
You did this

The operator's server returns a different set of network-blocking rules.

addefenderplus.com/net/ returns a config pointing to a new rule file; addefenderplus.com/net/<path> returns a JSON array of declarativeNetRequest rule objects.

The extension did this

The extension atomically removes all current dynamic blocking rules and installs the server-provided rules with no user notification.

chrome.declarativeNetRequest.updateDynamicRules() is called with removeRuleIds containing every existing rule ID and addRules containing the server's array.

02EvidenceNETWORK CAPTURE
Captured request
GEThttps://addefenderplus.com/net/?rpsps=ai9WZkg2SXJUU20veDY0QTU5UmhKeUhYM0p2UU1NR0I3bmlobFBzNW5CWUtXcVBZVVFta3UzVUxKY29VQlNjY043TFdnV0Fn
JSON object with fields fRUqk (rule file path suffix) and sicZvM (version integer). A second GET to addefenderplus.com/net/<fRUqk>?rpsps=<UID> returns the declarativeNetRequest rule array.
03EvidenceCODE COMPARE
The code that does this

Remote-config-driven full rule replacement (net_updater.js:4-23)

What it actually does
async function UpdateNetItem(config) {
  try {
    // Build URL from server-controlled path fragment
    const ruleFileUrl = consts.netUpdateURL + config.fRUqk; // e.g. /net/net_config
    const serverVersion = config.sicZvM;
    const versionKey = `net_item_sicZvM_${ruleFileUrl}`;
    const cachedVersion = (await chrome.storage.local.get([versionKey]))[versionKey];

    // Skip if we already have this version installed
    if (cachedVersion !== undefined && cachedVersion >= serverVersion) return;

    // Download the server-provided rule array
    const response = await fetch(await addNetParams(ruleFileUrl));
    const serverRules = await response.json(); // Array of declarativeNetRequest rules

    // Collect IDs of ALL currently installed dynamic rules
    const existingRuleIds = [];
    const existingRules = await chrome.declarativeNetRequest.getDynamicRules();
    for (const rule of existingRules) existingRuleIds.push(rule.id);

    // Atomically: remove ALL existing dynamic rules, install server rules
    await chrome.declarativeNetRequest.updateDynamicRules({
      removeRuleIds: existingRuleIds,  // clears everything
      addRules: serverRules            // installs whatever server sent
    }, () => {});

    // Cache the installed version
    const versionStore = {};
    versionStore[versionKey] = config.sicZvM;
    await chrome.storage.local.set(versionStore);
  } catch (e) {}
}
04EvidencePLAIN NOTE
What the operator could do with this capability

The server controls the complete contents of `addRules`. By returning an empty array, the operator disables all dynamic blocking. By returning rules with `action.type: "redirect"`, the operator could redirect matching requests. The extension has no integrity check on the server response — any valid JSON array of declarativeNetRequest rule objects is accepted and installed.

05EvidenceTHIRD PARTY LIST
Infrastructure controlling the extension's blocking behaviour
  • addefenderplus.com

    Operator server. /net/ delivers the config index and individual rule files that fully replace the extension's dynamic declarativeNetRequest rules every 60 minutes.

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

Uninstall beacon registers the same persistent tracking ID

On install, the extension registers an uninstall URL via chrome.runtime.setUninstallURL(): https://addefenderplus.com/ciao/, carrying the tracking ID (rpsps).

It opens automatically when removed, telling the operator who uninstalled.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You install the extension.

chrome.runtime.onInstalled fires with reason INSTALL.

The extension did this

The extension registers an uninstall webhook with Chrome, tagged with your persistent tracking ID, before you have interacted with the extension at all.

chrome.runtime.setUninstallURL() is called with https://addefenderplus.com/ciao/?rpsps=<UID>.

02EvidenceCODE COMPARE
The code that does this

Uninstall URL construction and registration (service_worker.js:16-18, 41-42)

What it actually does
async function addParams(url) {
  // Appends the stored tracking ID to any URL
  return url += '?rpsps=' + (await chrome.storage.sync.get(['uid'])).uid;
}

// Inside the install handler:
const uninstallUrl = await addParams(consts.uninstalledURL); // https://addefenderplus.com/ciao/?rpsps=<UID>
chrome.runtime.setUninstallURL(uninstallUrl);
// Chrome will automatically navigate to this URL when the extension is removed.
03EvidenceTHIRD PARTY LIST
Where the uninstall notification goes
  • addefenderplus.com

    Operator server. Receives an automatic notification, tagged with the user's persistent tracking ID, whenever the extension is uninstalled.

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

Delayed install-confirmation beacon fires with the server-set delay

The server's /set/ response includes a delay (vmqwo); the install handler schedules a Chrome alarm, installFinished, for that long.

When it fires, the extension GETs addefenderplus.com/installed/ with the tracking ID.

01EvidenceCAUSE EFFECT
What actually happens
You did this

The operator's server returns a delay value (vmqwo) in its response to the extension's install-time /set/ request.

The extension stores this delay and schedules a one-time Chrome alarm for that many minutes later.

The extension did this

After the server-chosen delay elapses, the extension automatically sends a GET request confirming the install to the operator, with the user's persistent tracking ID attached.

GET https://addefenderplus.com/installed/?rpsps=<UID>.

02EvidenceNETWORK CAPTURE
Captured request
GEThttps://addefenderplus.com/installed/?rpsps=ai9WZkg2SXJUU20veDY0QTU5UmhKeUhYM0p2UU1NR080SENobGZ3OW5CWW1JYm9VTGFqVVozVkNMbGEycnZKNzhJV0I4NGZx
200 OK
03EvidenceCODE COMPARE
The code that does this

Delayed alarm scheduling and the confirmation beacon (service_worker.js:33-40, updater.js:57-63)

What it actually does
// After the install-time UID fetch, schedule a one-time alarm using the
// delay the operator's server chose (t.vmqwo, minutes):
if (!(await chrome.alarms.get('installFinished'))) {
  await chrome.alarms.create('installFinished', { delayInMinutes: serverDelay });
}

// updater.js — runs when the alarm fires:
async function finish() {
  const url = await addParams(consts.installFinishedURL); // https://addefenderplus.com/installed/?rpsps=<UID>
  fetch(url);
}
chrome.alarms.onAlarm.addListener(alarm => {
  if (alarm.name === 'updateRulesAlarm') updateData();
  else if (alarm.name === 'installFinished') finish();
});
04EvidenceTHIRD PARTY LIST
Where the confirmation beacon goes
  • addefenderplus.com

    Operator server. Sets the confirmation delay at install and receives the delayed confirmation beacon, tagged with the user's persistent tracking ID.

+3 more findings not shown

What it can do

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

  • Schedule its own background tasks

    alarms

  • Run its own code inside the pages you visit

    scripting

  • 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 every page you navigate to, as you navigate to it

    webNavigation

Updated 30 September 2026jdabkgjafjneapmfikiofbbijofnkilk