Is SimplyCodes: Verified Coupon Codes by Real Shoppers safe?

Medium risk

SimplyCodes is medium risk. Dynamic analysis captured the extension sending visited URLs, a persistent user ID, and merchant IDs to api.simplycodes.com and Google Analytics on shopping-site visits, matched via a bundled domain list. Non-shopping sites aren't reported.

Product.aiv2.10.0Chrome Web Store
47Risk
Who publishes it

Product.ai - no other listings under this identity, 5 shared hostnames

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

Publisher
Product.ai

Shared hosts - 5 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.

cdn.simplycodes.com
Also called by 1 other listing: SimplyCodes: Verified Coupon Codes by Real Shopper
help.simplycodes.com
Also called by 1 other listing: SimplyCodes: Verified Coupon Codes by Real Shopper
images.simplycodes.com
Also called by 1 other listing: SimplyCodes: Verified Coupon Codes by Real Shopper
api.simplycodes.com
Also called by 3 other listings, including SimplyCodes: Verified Coupon Codes by Real Shopper
simplycodes.com
Also called by 3 other listings

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

Publishers can request a review.

Findings

Shopping Journey Transmitted to SimplyCodes API and Google Analytics

Dynamic analysis captured the extension sending visited URLs, a persistent user ID, and merchant IDs to api.simplycodes.com and Google Analytics on shopping-site visits, matched via a bundled domain list.

Non-shopping sites aren't reported.

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

You navigate to a recognized shopping site (e.g. bestbuy.com, amazon.com, walmart.com).

The extension did this

The extension matches your URL against a bundled domain list, posts it with the merchant ID to api.simplycodes.com, then fires a GA4 hit with the same URL and your linked user ID.

No interaction with the extension UI is required; the data is sent automatically on navigation.

Captured request
POSThttps://www.google-analytics.com/mp/collect?api_secret=<redacted>&measurement_id=G-WQ1RVS99FL

204 No Content (GA4 measurement protocol)

Body
{  "client_id": "f653fb0b-6df8-45b1-b3f2-dbaf0422cb79",  "user_properties": {    "is_guest": {      "value": false    }  },  "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",  "events": [    {      "name": "llm_url_analysis_checkout",      "params": {        "internal_user_id": 129429222,        "url": "https://www.bestbuy.com/",        "merchant_id": 5106,        "merchant_name": "Best Buy",        "execution_time_ms": 412,        "result": "non_checkout",        "confidence": 0.91      }    }  ]}
Fields sent to Google Analytics on each recognized merchant navigation
  • Page URL
    https://www.bestbuy.com/

    The full URL of the shopping page you are viewing.

  • Internal user ID
    129429222

    Your SimplyCodes account identifier, transmitted to Google Analytics. Links this browsing event to your account.

  • Merchant ID
    5106

    A numeric identifier for the shopping site you are visiting.

  • Merchant name
    Best Buy

    Human-readable name of the merchant (e.g. Best Buy, Amazon).

  • Client ID
    f653fb0b-6df8-45b1-b3f2-dbaf0422cb79

    A persistent UUID stored in chrome.storage.local, unique to your browser install.

The code that does this

The navigation listener and GA4 dispatch from the extension's background service worker.

Readable version

tabs.onUpdated listener

background.js
// Fires on every browser navigation (loading + complete states)chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {  const isLoading = changeInfo?.status === 'loading';  const isComplete = changeInfo?.status === 'complete';  if (tab.url && (isLoading || isComplete)) {    // n() stores the merchant URL for this tab (if merchant matched)    try { await storeMerchantUrl(tabId, tab.url); } catch {}    let referrer = '';    try {      // lS() = is internal chrome:// / extension URL → skip      if (!isInternalUrl(tab.url)) referrer = await getTabReferrer(tabId);      referrer ||= await getStoredMerchantUrl(tabId, tab.url);    } catch {}    // UE() does the merchant lookup + logUserActivity() + GA4 fire    try { await processUrlEvent(tab, isComplete, referrer); } catch {}    if (isComplete) try { await fetchAndShowPromotions(tabId, tab.windowId); } catch {}  }});

GA4 event builder — includes internal_user_id from account

background.js
const GA4_ENDPOINT = 'https://www.google-analytics.com/mp/collect';async function sendGa4Event(event) {  const { client_id, user_id, user_properties } = await getAccountIds();  // user_id = SimplyCodes internal_user_id (numeric account ID)  const params = new URLSearchParams({    api_secret: '<redacted>',    measurement_id: 'G-WQ1RVS99FL'  });  const payload = {    client_id,           // persistent UUID from chrome.storage.local    user_properties,    user_agent: navigator.userAgent,    events: [{      name: event.eventName,      params: {        internal_user_id: user_id,  // links hit to SimplyCodes account        ...event.extra,             // url, merchant_id, merchant_name, etc.        ...await getSessionParams()      }    }]  };  return ky.post(GA4_ENDPOINT, { json: payload, searchParams: params });}
Destinations receiving your shopping navigation data
    • api.simplycodes.com

    SimplyCodes' own backend. Receives merchant ID, event type (cart/pre-checkout/checkout), and shopping journey state on each recognized merchant page load.

    • www.google-analytics.com

    Google Analytics Measurement Protocol (GA4). Receives page URL, merchant ID, merchant name, and internal SimplyCodes user ID on each merchant navigation event, processed by Google.

What it can do

Permissions this extension asks for, as declared in version 2.10.0. 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

  • Run its own code inside the pages you visit

    scripting

Updated 30 September 2026gfkpklgmocbcbdabfellcnikamdaeajd