Is Amazon Quick View by AMZScout safe?
Amazon Quick View by AMZScout accepts backend tasks to fetch Amazon product pages and return parsed page data to AMZScout.
The extension opens a WebSocket to ws.amzscout.net and can receive tasks that tell it to load specific Amazon product URLs. It parses those pages and returns product details, URLs, and page DOM content to AMZScout over the WebSocket or the amzscout.net quickview endpoint.
Who publishes itAMZscout Corp. - 4 other listings from the same operator, none carrying a finding
AMZscout Corp. - 4 other listings from the same operator, none carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same store account
4 other listings published from this account, 240k+ users between them, none of them carrying a finding.
Shared hosts - 1 hostname
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
AMZScout remote tasks fetch and parse Amazon product pages
Amazon Quick View by AMZScout fetches an Amazon product page and posts parsed data back to AMZScout.
Its source shows a WebSocket accepting remote task messages with Amazon ASINs, building product URLs and returning results over the socket.
- Severity
- High unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
AMZScout can send the extension a product-parsing task.
Task messages carry a task id, Amazon marketplace domain, and ASIN list.
The extension fetches those Amazon product pages and returns parsed product data.
Dynamic analysis observed this pattern for an Amazon product URL ending in /dp/B0F4R67XFL.
- Product identifierB0F4R67XFL
Tells AMZScout exactly which Amazon product page the extension was directed to process.
- Amazon marketplacecom
Selects the country-specific Amazon site used for the fetch.
- Amazon product URLhttps://www.amazon.com/dp/B0F4R67XFL?th=1
Shows the exact product page fetched by the extension before parsing.
- Parsed product recordASIN B0F4R67XFL, product name beginning with EPICKA
Contains product details extracted from the Amazon page and sent back to AMZScout.
- Extension version2.2.6
Lets AMZScout associate the returned parsing result with the installed extension build.
Observed after a GET request for an Amazon product page ending in /dp/B0F4R67XFL; the POST body included a products array with ASIN B0F4R67XFL and a product name beginning with EPICKA.
The service worker opens AMZScout tasking and dispatches remote task messages
Readable WebSocket connection and event dispatch
background.jskey: "connect",value: function connect() { var t, r = this; chrome.storage.local.get(Sr, (function(o) { t = o && o["CALC_EXT-next-delay-run"]; var i = (new Date).getTime(), a = !t || t > i; if ((!r.socket || r.socket.readyState !== WebSocket.OPEN) && a) { var c = chrome.runtime.getManifest(), u = c && c.version || void 0; r.socket = new WebSocket("".concat("wss://ws.amzscout.net/so/", "?software=").concat("QUICK_VIEW_EXT", "&version=").concat(u)), r.socket.onmessage = function(t) { return r.onMessage(t) }, r.socket.onerror = function(t) { return r.onError(t) }, r.socket.onopen = function(t) { return r.openConnection(t) }, r.socket.onclose = function(t) { return r.closeConnection(t) } } }))}key: "onMessage",value: function onMessage(t) { var r = t.data; switch ((r = JSON.parse(r)).event) { case "update": this.onUpdate(r.data); break; case "task": this.onTask(r.data); break; case "check": this.onCheck(r.data); break; case "stop": this.onStop(r.data) }}Readable task validator
background.jskey: "onTask",value: function onTask(t) { var r = this; try { var o = JSON.parse(t), i = o && o.id || void 0, a = chrome.runtime.getManifest(), c = a && a.version; if (this.checkId || !i) return void this.sendMessage({ event: "task", data: JSON.stringify({ id: i, error: "progress", version: c }) }); this.checkId = i, o && o.asins && o.asins.length && o.domain && i && this.doParse(o).then((function() { 0 })).finally((function() { r.checkId = void 0 })) } catch (u) { this.sendMessage({ event: "task", data: JSON.stringify({ error: "parse error" }) }) }}The parser builds Amazon URLs and returns products, errors, and tool metadata
Readable Amazon URL builder
background.jsgetProductUrl: function getProductUrl(t) { return "https://www.amazon.".concat(t.domain.toLowerCase().replace("_", "."), "/dp/").concat(t.asin, "?th=1")}Readable remote-task parser and return payload
background.jskey: "doParse",value: (i = extraparse_service_asyncToGenerator((function*(t) { var r = this, o = t.domain, i = (t && t.asins || []).map((function(t) { return { domain: o, asin: t } })); if (i && i.length > 0) { var a = t && t.short || !1, u = i.map((function(t) { return c.e.getProductUrl(t) })), l = yield Promise.wait(u.map((function(t) { return r.parser.parseProduct(t, null, !1, null, a).catch((function(r) { return { url: t, error: r } })) }))), p = l.filter((function(t) { return t && !t.error })), y = l.filter((function(t) { return t && t.error })).map((function(t) { var r = "404" === t.error ? "NOT_FOUND" : "OTHER"; return { asin: c.e.getASIN(t.url), domain: o, errorType: r, error: t.error } })), d = chrome.runtime.getManifest(); if (p.length > 0 || y.length > 0) { var _ = { id: t.id, products: p, errors: y, tool: { software: "QUICK_VIEW_EXT", version: d && d.version || void 0 } }; t && t.url ? (yield Object(c.c)("".concat("https://amzscout.net/extensions/quickview").concat(t.url), "POST", _), this.checkId = void 0) : (this.sendMessage({ event: "task", data: JSON.stringify(_) }), this.checkId = void 0) } else this.sendMessage({ event: "task", data: JSON.stringify({ error: "parse error" }) }), this.checkId = void 0 }})), function doParse(t) { return i.apply(this, arguments)})Readable quickview renew POST observed during analysis
background.jsvar r = t.products || [];if ((r = r.filter((function(t) { return t }))).length) { r.forEach((function(t) { delete t.imageData, delete t.promises, t.container && delete t.container, t.estSales && isNaN(t.estSales) && delete t.estSales, t.hasOwnProperty("estSalesSign") && delete t.estSalesSign, t.parsedEstSales && isNaN(t.parsedEstSales) && delete t.parsedEstSales, t.hasOwnProperty("isEstSalesParsed") && delete t.isEstSalesParsed, t.hasOwnProperty("isNewMarketplace") && delete t.isNewMarketplace, t.hasOwnProperty("isAllCategory") && delete t.isAllCategory })); var o = chrome.runtime.getManifest(), i = { products: r = r.filter((function(t) { return t.rank && t.rank < 5e5 })), errors: [], tool: { software: "QUICK_VIEW_EXT", version: o && o.version || void 0 } }; Object(Cr.b)("https://amzscout.net/extensions/quickview/v1/products/renew", "POST", i)}- ws.amzscout.net
AMZScout WebSocket host used to send task, update, check, and stop messages to the service worker.
- amzscout.net
AMZScout quickview API host that receives returned product records, errors, and extension version metadata.
Where it sends data
Destinations our analysis observed Quick View 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.
- amzscout.net
Quick View sends data to amzscout.net. One other extension we have analysed sends data here.
- ws.amzscout.net
Quick View sends data to ws.amzscout.net. One other extension we have analysed sends data here.