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.
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.
You open or navigate within a website.
The extension checks that site origin with its GraphQL API.
operationName=isDomainBlacklisted variables.domain=https://www.example.com
| Field | Value | Why it matters | |
|---|---|---|---|
Current site origin | https://www.madhappy.com | This tells the vendor service which website you are visiting, even though it omits the path after the domain. | |
Blacklist operation | isDomainBlacklisted | This labels the request as a site-origin blacklist lookup tied to the page you opened. |
Each origin is cached for one day; after that, revisiting the same site causes another GraphQL check.
The content script chooses the current origin and the service worker sends it
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
}
}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
}
}
})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()
}
})