Is Hero Ad Blocker safe?
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.
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
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.
As you browse, the extension refreshes its ad-blocking configuration in the background.
It downloads rule payloads from heroadblocker.com and applies them to page content and network blocking.
Remote rule refreshes are scheduled hourly, so new server-side rule payloads can be picked up after the alarm fires.
| Field | Value | Why it matters | |
|---|---|---|---|
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. |
Remote payloads flow from fetch to storage, page execution, and dynamic rules
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}`)
}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) {}
}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"]
}
}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}`)
});- heroadblocker.com
Receives extension rule-update requests and returns block-list, scriptlet, CSS, cosmetic-filter, and network-rule JSON used by Hero Ad Blocker.