Is Locker safe?

Medium risk

Locker sends every URL visited, the domain of each site, and product page details to its vendor servers across all websites.

On every page load, Locker transmits the current URL along with a persistent device ID, session ID, and user ID to eapiv2.wantlocker.com for analytics. It also queries apiext.wantlocker.com with the domain of each site you visit to check a blocklist, sending your browsing domains to the vendor's GraphQL API. On shopping product pages, it additionally scrapes and transmits structured product data — including title, price, brand, and canonical URL — derived from schema.org markup and page DOM.

Lockerv1.1.10Chrome 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-200
SourceAI SANDBOX

Locker sends visited site origins to GraphQL API

Opening an HTTP or HTTPS page, Locker checks the site origin against `apiext.wantlocker.com`.

We observed POSTs to `/v1/graphql` with `operationName=isDomainBlacklisted` and `variables.domain` for origins like madhappy.com and google.com.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You open or navigate within a website.

The extension did this

The extension checks that site origin with its GraphQL API.

02EvidenceNETWORK CAPTURE
Captured request
POSThttps://apiext.wantlocker.com/v1/graphql
Body
operationName=isDomainBlacklisted
variables.domain=https://www.example.com
03EvidenceFIELD TABLE
Fields sent in the GraphQL blacklist check
FieldValueWhy it matters
Current site origin
https://www.madhappy.comThis tells the vendor service which website you are visiting, even though it omits the path after the domain.
Blacklist operation
isDomainBlacklistedThis labels the request as a site-origin blacklist lookup tied to the page you opened.
04EvidenceTEMPORAL PATTERN
When this fires
Every 1 day

Each origin is cached for one day; after that, revisiting the same site causes another GraphQL check.

05EvidenceCODE COMPARE
The code that does this

The content script chooses the current origin and the service worker sends it

What it actually does
Readable content script blacklist checkcontent/App.js
async function I() {
  var e;
  let t = (await d.default.storage.local.get("blacklistedDomains")).blacklistedDomains,
    r = window.location.origin,
    n = Date.now(),
    i = (0, a.default)(n, {
      days: 1
    });
  if ((null == t ? void 0 : t[r]) && (null == (e = null == t ? void 0 : t[r]) ? void 0 : e.lastChecked) >= i) return t[r].isBlacklisted;
  {
    let e = await (0, E.getApolloClient)(),
      {
        data: n
      } = await e.query({
        query: w.IsDomainBlacklistedDocument,
        variables: {
          domain: r
        },
        fetchPolicy: "network-only"
      });
    return await d.default.storage.local.set({
      blacklistedDomains: {
        ...t || {},
        [r]: {
          lastChecked: Date.now(),
          isBlacklisted: n.isDomainBlacklisted
        }
      }
    }), n.isDomainBlacklisted
  }
}
Readable Apollo link configurationcontent/App.js
let d = new(0, o.HttpLink)({
  uri: `${l.Config.API_BASE}/v1/graphql`,
  fetch: async (e, t) => {
    null == t || delete t.signal;
    let r = await c.default.sendMessage("APOLLO_OPERATION", {
      input: e,
      init: t
    });
    return {
      ...r,
      text: async () => r.text
    }
  }
})
Readable service worker fetch relaybackground.cff1f634.js
o.default.addListener("APOLLO_OPERATION", async ({
  input: e,
  init: r
}) => {
  let {
    method: t,
    body: s,
    headers: n
  } = r || {}, a = await fetch(e, {
    method: t,
    body: s,
    headers: n
  });
  return {
    ...a,
    status: a.status,
    text: await a.text()
  }
})

Data recipients

eapiv2.wantlocker.comapiext.wantlocker.com
Updated 17 September 2026bdacnlgpemjkfhlphdhhpamgopagnlie