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
48Risk

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

Publishers can request a review.

Findings

Remote ad-blocking rules apply without integrity checks

MediumunwantedCWE-829Dynamic sandbox

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

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.

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.

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.

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.

Concrete payload fields used by the remote rule system

  • Scriptlet function name
    Terminate-current-inline-script

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

The code that does this

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

Readable version

Readable block-rule fetch and storage path

upcore.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 path

net_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 path

ad_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 listener

sc_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}`)});

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.

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

  • Act on the current tab, but only after you click the extension

    activeTab

  • See the address and title of every tab you have open

    tabs

  • 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

  • Watch every request your browser makes

    webRequest

  • Run its own code inside the pages you visit

    scripting

Updated 15 October 2026onlmpoiokhmjmfhaaobipcafdngmppoi