Is Pie Shopping: AI Cash Back and Coupons safe?
Pie Shopping is medium risk. Pie Shopping's signed-in chat flow can collect offer IDs and POST them to zeroclick.dev/api/v2/impressions. The bundled ZeroClick SDK preps offer requests with user agent, origin, IP, and identity fields. DA didn't reach the logged-in path.
Who publishes itThe People's Internet Experiment (pie.org) - 1 other listing from the same operator, 1 of them carrying a finding
The People's Internet Experiment (pie.org) - 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, 2.0M+ users between them. 1 of them carries a finding.
Shared hosts - 14 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.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Pie Shopping sends chat offer IDs to ZeroClick
Pie Shopping's signed-in chat flow can collect offer IDs and POST them to zeroclick.dev/api/v2/impressions.
The bundled ZeroClick SDK preps offer requests with user agent, origin, IP, and identity fields.
DA didn't reach the logged-in path.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You use Pie Shopping's signed-in chat assistant and receive a response containing sponsored offer parts.
The code path is tied to chat parts named data-ui-offers, data-ui-top-merchants, and data-ui-products.
The extension collects ZeroClick offer impression IDs and passes them to its bundled reporting SDK.
The SDK constructs a POST request for the ZeroClick impressions endpoint.
- Offer impression IDoffer_01J1A9Z8M2K7Q3D5F6G8H9J0 (illustrative)
Lets the offer provider know which sponsored offer was shown in your chat result.
- Browser user agentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 (illustrative)
Describes your browser and operating system to the offer provider.
- Origin page contexthttps://www.target.com/c/kitchen-dining (illustrative)
Can connect the sponsored offer request to the shopping page or chat context that produced it.
- Network address198.51.100.24 (illustrative)
The destination server can see the network address used for the request, which can approximate location or organization.
- Optional identity fieldsuserSessionId: sess_9f4c21a7d8e3 (illustrative)
If provided to the SDK, these fields can tie offer requests to an account, hashed contact detail, session, or locale.
The request shape is constructed by the shipped SDK; dynamic analysis did not capture a live response because the chat path remained behind the Pie login wall.
- Content-Type
- application/json
- X-ZeroClick-SDK-Version
- 0.1.0
The SDK builds the ZeroClick POST and the chat UI feeds it offer IDs
Readable API client
deobfuscated/sidePanel.jsfunction An(e) { let { apiKey: n, baseUrl: t } = e; return { post: async function(e, r, o) { let i = `${t}${e}`, a = function(e) { let n = { "Content-Type": "application/json", "X-ZeroClick-SDK-Version": "0.1.0" }; e && (n["x-zc-api-key"] = e); let t = function() { if (typeof navigator < "u" && navigator.userAgent) return navigator.userAgent }(); return t && (n["X-ZeroClick-User-Agent"] = t), n }(o?.authenticate ?? 1 ? n : void 0), s = await fetch(i, { method: "POST", headers: a, body: JSON.stringify(r) }); if (!s.ok) throw new kn(await async function(e) { try { let n = await e.json(); return { message: n.error?.message ?? n.message ?? "An unknown error occurred", status: e.status } } catch { return { message: e.statusText || "An unknown error occurred", status: e.status } } }(s)); if (204 !== s.status) return s.json() } }}Readable impression tracker
deobfuscated/sidePanel.jsstatic async trackOfferImpressions(n) { if (e.ensureInitialized(), !n || 0 === n.length) throw Error("ZeroClick: ids array cannot be empty"); await e.apiClient.post("/api/v2/impressions", { ids: n }, { authenticate: !1 })}Readable chat-part collector
deobfuscated/sidePanel.js(0, e.useEffect)((function() { var e, n, t, r, o = c[c.length - 1]; if (c.length || w.current.clear(), o) { var i = o.parts.filter((function(e) { return "data-ui-prompts" === e.type })).find((function(e) { var n; return "success" === (null === (n = e.data) || void 0 === n ? void 0 : n.status) })); i && (null === (n = null === (e = i.data) || void 0 === e ? void 0 : e.prompts) || void 0 === n ? void 0 : n.length) ? v(i.data.prompts) : v([]); var a = new Set, s = null === (t = o.parts) || void 0 === t ? void 0 : t.filter((function(e) { return "text" === e.type })).map((function(e) { return e.text })).join(""); null === (r = o.parts) || void 0 === r || r.forEach((function(e) { var n, t, r; if ("data-ui-offers" === e.type) { var o = (null === (n = e.data) || void 0 === n ? void 0 : n.offers) || []; O(o), o.forEach((function(e) { e.aiOfferId && s.includes(e.clickUrl) && a.add(e.aiOfferId) })) } "data-ui-top-merchants" === e.type && (o = (null === (t = e.data) || void 0 === t ? void 0 : t.offers) || [], O(o), o.forEach((function(e) { e.aiOfferId && a.add(e.aiOfferId) }))), "data-ui-products" === e.type && (o = (null === (r = e.data) || void 0 === r ? void 0 : r.products) || [], O(o), o.forEach((function(e) { e.aiOfferId && a.add(e.aiOfferId) }))) })); var l = Array.from(a).filter((function(e) { return !w.current.has(e) })); l.length > 0 && (l.forEach((function(e) { return w.current.add(e) })), T(l)) } p()}), [c, O, T])The extension bundle contains the ZeroClick host and API key
Readable production constants
deobfuscated/background.jsconst t = { NODE_ENV: "production", BUILD_ENV: "production", VERSION: "1.33.6", APP_NAME: "@piedotorg/extension", EXTENSION_TYPE: "shopping", PLATFORM: "ch", SEGMENT_WRITE_KEY: "cuVYSvijPDykxOEOXeDMZp7nA9zyFxFF", BROWSER_TARGET: "chrome", SLEEK_API_KEY: "b88024fa0f76d7fd23fedfb14f53229b0a4a8e4851d3e3d9", ZEROCLICK_API_KEY: "pd2hD-6QllX1nNCmmtDLOrEb60rJzGn0GcSwzYrDvdc"}.APP_ID;Readable runtime hosts
deobfuscated/sidePanel.jsconst Pm = "https://zeroclick.dev", Lm = "https://www.pie.org", Om = "https://chat.pie.org/api/v1";- zeroclick.dev
Receives the SDK's offer and impression API requests for sponsored chat offers.
- chat.pie.org
Supplies the Pie shopping assistant chat responses whose sponsored offer parts feed the impression tracker.
- www.pie.org
Provides the login cookie checked before the chat path becomes reachable.
Dynamic analysis reached Pie's login wall and did not observe any requests to zeroclick.dev or chat.pie.org. The confirmed evidence for this claim is the shipped code path: the login check looks for an is-logged-in cookie, and without a valid Pie session the chat flow that feeds ZeroClick impression tracking was not reachable.
What it can do
Permissions this extension asks for, as declared in version 1.33.6. 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 1.33.1, which we have not unpacked yet.
Read and change your data on every site you visit
<all_urls>
Schedule its own background tasks
alarms
Read and change cookies, including the ones that keep you signed in
cookies
See the address and title of every tab you have open
tabs
Store data in your browser
storage
Run its own code inside the pages you visit
scripting
See every page you navigate to, as you navigate to it
webNavigation
Store an unlimited amount of data in your browser
unlimitedStorage
See which of your requests its blocking rules matched
declarativeNetRequestFeedback
Run hidden pages in the background
offscreen
Watch every request your browser makes
webRequest
See, disable and uninstall your other extensions, including your security ones
management
Show a panel beside the page
sidePanel