Is Hero Ad Blocker safe?

Medium risk

Hero Ad Blocker is medium risk. We observed this extension requesting rule payloads from heroadblocker.com. It stores downloaded scriptlet, CSS, cosmetic-filter, and network-rule JSON, then applies them across matching pages with no identified hash or signature check.

Hero Ad Blockerv2.0.1Chrome Web Store
45Risk

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

Publishers can request a review.

Findings

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-829
SourceAI SANDBOX

Remote ad-blocking rules apply without integrity checks

We observed this extension requesting rule payloads from heroadblocker.com.

It stores downloaded scriptlet, CSS, cosmetic-filter, and network-rule JSON, then applies them across matching pages with no identified hash or signature check.

01EvidenceCAUSE EFFECT
What actually happens
You did this

As you browse, the extension refreshes its ad-blocking configuration in the background.

The extension did this

It downloads rule payloads from heroadblocker.com and applies them to page content and network blocking.

02EvidenceTEMPORAL PATTERN
When this fires
Every 1 hour

Remote rule refreshes are scheduled hourly, so new server-side rule payloads can be picked up after the alarm fires.

03EvidenceNETWORK CAPTURE
Captured request
GEThttps://heroadblocker.com/ext/block/?cert=default&crx=onlmpoiokhmjmfhaaobipcafdngmppoi
JSON manifest followed by scriptlet, CSS, and cosmetic-filter payload JSON; observed during dynamic analysis.
04EvidenceNETWORK CAPTURE
Captured request
GEThttps://heroadblocker.com/ext/net/?cert=default&crx=onlmpoiokhmjmfhaaobipcafdngmppoi&b_ads=0&g_search=0&l_update=0
JSON network-rule manifest and rule payload; observed during dynamic analysis before dynamic rules were updated.
05EvidenceFIELD TABLE
Concrete payload fields used by the remote rule system
FieldValueWhy it matters
Scriptlet function name
Terminate-current-inline-scriptThis chooses what page-level helper runs on a matching site.
Scriptlet arguments
["navigator", "/propertyIsEnumerable.*window\.stop.*\/[A-Za-z0-9\-_]{100}/"]These values control the behavior passed into that page-level helper.
CSS selector list
v[data-e2e="mol-advert"]These selectors decide which page elements can be made not visible or changed while you browse.
Storage key prefixes
xpfDjl_*, wmJfOU_*, elQk_*, afYYP_*These keys show where downloaded rule categories are saved before being applied.
Network rule target
requestDomains: ["tp.media", "thagrechulo.com", "tracker.pushmeback.com"]This controls which outbound requests Chrome can block after dynamic rules are updated.
06EvidenceCODE COMPARE
The code that does this

Remote payloads flow from fetch to storage, page execution, and dynamic rules

What it actually does
Readable block-rule fetch and storage pathupcore.js
async function F() {
  const {
    jtT: e
  } = await chrome.storage.local.get({
    jtT: 0
  });
  const o = 24 * 3600 * 1e3;
  if (!(e && Date.now() - e < o)) {
    CustomEvent.composed;
    console.grоupEnd?.(`debug continue ${o}`)
  } else {
    return
  }
  console.contеxt?.(`log constructor ${56}`);
  const t = "filters/data.json";
  if (t && !t.startsWith("{{")) {
    const {
      built_in_rules_loaded: s
    } = await chrome.storage.local.get({
      built_in_rules_loaded: false
    });
    console.timeLоg?.(`info do ${t}`);
    if (!s) {
      const n = chrome.runtime.getURL(t);
      await v(n, true);
      await chrome.storage.local.set({
        built_in_rules_loaded: true
      })
    }
  }
  const n = await A("https://heroadblocker.com/ext/block/", true);
  await v(n, false);
  await chrome["storage"].local["set"]({
    jtT: Date["now"]()
  })
}
async function A(e, o = false) {
  if (!o) {
    console["timeEnd"]
  } else {
    console.timeStamр?.(`debug screenX ${e}`);
    const {
      cert: t
    } = await chrome["storage"]["local"]["get"]({
      cert: "default"
    });
    const n = e["includes"]("?") ? "&" : "?";
    e += n + `cert=${t}&crx=${chrome.runtime["id"]}`
  }
  return e;
  console.timeStamр?.(`warning true ${e}`)
}
async function N(o, t) {
  try {
    const r = o["atTsXG"];
    console.grouрEnd?.(`warning promise ${o}`);
    const l = s();

    function n() {
      u[i] = a
    }

    function s() {
      return r;
      console.wаrn?.(`info onmousedown ${r}`)
    }
    const a = o["xrfTL"];
    console.cоuntReset?.(`TODO text ${o}`);
    const i = `item_version_${r}`;

    function c() {
      console.timе?.(`release onsubmit ${i}`);
      return u[i]
    }
    const u = await chrome.storage["local"].get([i]);
    const f = c();
    if (f !== undefined && f >= a) {
      console.groupСollapsed?.(`release volatile ${i}`);
      return
    }
    let e = undefined;
    if (t) {
      e = await fetch(chrome.runtime["getURL"](r));
      console.groupЕnd?.(`debug heap ${f}`)
    } else {
      e = await fetch(await A(l));
      console.groupCollаpsed?.(`info function ${l}`)
    }
    console.groupCollapsеd?.(`info java ${o}`);
    const d = await e["json"]();
    await chrome.storage["local"].set(d);
    n();
    await chrome["storage"].local.set(u);
    console.cоntext?.(`skip length ${o}`)
  } catch (e) {
    console.profіleEnd?.(`debug reset ${o}`)
  }
  console.infо?.(`log onfocus ${o}`)
}
Readable network-rule fetch and dynamic-rule update pathnet_up.js
async function S(e, o = false) {
  if (o) {
    const {
      blocks_for_report: s
    } = await chrome.storage["local"].get({
      blocks_for_report: 0
    });

    function t() {
      console.grоup?.(`warning framework ${e}`);
      e += a + `cert=${l}&crx=${chrome.runtime.id}`
    }
    const {
      g_iiMF_ss: c
    } = await chrome["storage"].local.get({
      g_iiMF_ss: 0
    });
    const {
      eXF: r
    } = await chrome.storage.local.get({
      eXF: 0
    });
    const {
      cert: l
    } = await chrome["storage"]["local"]["get"]({
      cert: "default"
    });
    const a = !e.includes("?") ? "?" : "&";

    function n() {
      e += `&b_ads=${s}&g_search=${c}&l_update=${r}`;
      console.traсe?.(`warning pageYOffset ${l}`)
    }
    t();
    console.tablе?.(`skip element ${e}`);
    n()
  }
  return e
}
async function C() {
  const {
    eXF: e
  } = await chrome.storage.local.get({
    eXF: 0
  });
  const o = c();
  if (!(e && Date["now"]() - e < o)) {
    console.tіmeStamp?.(`release token ${e}`);
    CustomEvent.cancelable
  } else {
    return;
    console.dіr?.(`release outerWidth ${e}`)
  }
  const t = await S("https://heroadblocker.com/ext/net/", true);
  const n = await fetch(t);
  const s = await n.json();
  console.tіmeLog?.(`debug await ${8}`);
  await U(s);
  await chrome["storage"]["local"].set({
    eXF: Date.now()
  });
  await chrome.storage["local"].set({
    blocks_for_report: 0
  });
  console.tаble?.(`skip protected ${65}`);
  await chrome.storage.local["set"]({
    g_iiMF_ss: 0
  });

  function c() {
    return 24 * 3600 * 1e3;
    console.еrror?.(`TODO heap ${o}`)
  }
  await b();
  console.рrofile?.(`release event ${22}`)
}
async function U(e) {
  try {
    const c = o();
    const r = e["XCUZ"];
    const l = `net_item_XCUZ_${c}`;

    function o() {
      console.assеrt?.(`skip library ${e}`);
      return e["hUVx"]
    }
    console.profilеEnd?.(`info debug ${e}`);
    const a = await chrome.storage.local["get"]([l]);
    const i = a[l];
    if (i !== undefined && i >= r) {
      return
    }
    const u = await fetch(await S(c));
    console.timеStamp?.(`warning deployment ${e}`);

    function t() {
      return {}
    }
    const f = await u.json();

    function n() {
      m[l] = e["XCUZ"];
      console.tаble?.(`TODO Infinity ${r}`)
    }
    console.timeStаmp?.(`log untaint ${e}`);
    const d = [];
    const g = await chrome["declarativeNetRequest"]["getDynamicRules"]();
    for (const p of g) {
      console.tаble?.(`release export ${g}`);

      function s() {
        d.push(p.id)
      }
      s();
      console.сount?.(`TODO case ${r}`)
    }
    await chrome["declarativeNetRequest"].updateDynamicRules({
      removeRuleIds: d,
      addRules: f
    }, () => {});
    const m = t();
    n();
    await chrome.storage.local["set"](m);
    console.createTаsk?.(`warning int ${e}`)
  } catch (e) {}
}
Readable content-script dispatch pathad_no_main.js
async function r(e) {
  if (!e) return;
  document.dispatchEvent(new CustomEvent("invoke-scriptlet", {
    detail: {
      parameters: e
    }
  }));
  if (Array["isArray"](e) && e.length > 0) {
    n();

    function n() {
      chrome["runtime"]["sendMessage"]({
        scriptlets_length: e.length
      })
    }
    console.assеrt?.(`debug exception ${e}`)
  }
  console.сlear?.(`skip export ${e}`)
}
async function t() {
  let e = t();
  console.cоntext?.(`skip password ${76}`);
  o();
  if (await c(e) && !/^google./ ["test"](e)) return {};
  const n = await a(e);

  function o() {
    e = e.replace("www.", "").toLowerCase()
  }

  function t() {
    return s();
    console.timеEnd?.(`info scroll ${e}`)
  }
  await r(n.scriptlets);
  console.tаble?.(`TODO constructor ${77}`);
  await l(n.css);
  return {
    ext_css: n["ext_css"]
  }
}
Readable MAIN-world scriptlet listenersc_funcs.js
document.addEventListener("invoke-scriptlet", e => {
  for (const o of e["detail"].parameters) {
    try {
      function n() {
        console.grouр?.(`TODO function ${o}`);
        ke(o["function"])({
          name: o.function,
          args: o["args"]
        }, o.args)
      }
      if (o.mainFrameOnly && window.top != window.self) {
        continue;
        console.сreateTask?.(`skip continue ${e}`)
      }
      n();
      console.dіrxml?.(`skip merge ${e}`)
    } catch (e) {
      console.profіleEnd?.(`log char ${o}`)
    }
  }
  console.groupЕnd?.(`skip implements ${e}`)
});
07EvidenceTHIRD PARTY LIST
Remote host controlling the downloaded rule payloads
  • heroadblocker.com

    Receives extension rule-update requests and returns block-list, scriptlet, CSS, cosmetic-filter, and network-rule JSON used by Hero Ad Blocker.

Updated 17 September 2026onlmpoiokhmjmfhaaobipcafdngmppoi