Is Locker safe?
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.
Who publishes itLocker 2.0, Inc. - no other listings under this identity
Locker 2.0, Inc. - no other listings under this identity
What this publisher told the store about itself, and the other listings that told it the same thing.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
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.
What actually happens
You open or navigate within a website.
The extension checks that site origin with its GraphQL API.
Captured request
operationName=isDomainBlacklistedvariables.domain=https://www.example.comFields sent in the GraphQL blacklist check
- Current site originhttps://www.madhappy.com
This tells the vendor service which website you are visiting, even though it omits the path after the domain.
- Blacklist operationisDomainBlacklisted
This labels the request as a site-origin blacklist lookup tied to the page you opened.
When this fires
Every 1 day
Each origin is cached for one day; after that, revisiting the same site causes another GraphQL check.
The code that does this
The content script chooses the current origin and the service worker sends it
Readable content script blacklist check
content/App.jsasync 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 configuration
content/App.jslet 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 relay
background.cff1f634.jso.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() }})Where it sends data
Destinations our analysis observed Locker contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.
- apiext.wantlocker.com
Locker sends data to apiext.wantlocker.com. No other extension we have analyzed sends data here.
- eapiv2.wantlocker.com
Locker sends data to eapiv2.wantlocker.com. No other extension we have analyzed sends data here.
