Is Cashback Assistant safe?

Medium risk

Cashback Assistant sends merchant-site visit events to Google Analytics with a persistent extension-generated client ID.

When you visit a site that matches its remotely fetched cashback or merchant lists, the background worker records an event such as supported_page_visited or checkout_page_visited. The event is posted to Google Analytics with the visited merchant host in the label field and a persistent client_id stored by the extension.

Opera Norway ASv4.1.9Chrome Web Store
50Risk
Who publishes it

Opera Norway AS - 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
Opera Norway AS
Declared legal entity
Opera Norway AS
Registered address
Vitaminveien 4, Oslo 0485, NO
Registered contact
Opera Norway AS

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

Publishers can request a review.

Findings

Cashback Assistant sends your merchant-site visits to Google Analytics

Cashback Assistant runs on every site and checks its domain against a merchant list from its own API.

On a match, it sends Google Analytics the domain and a persistent client ID.

Dynamic analysis: 4 test visits, 4 POST requests.

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

The user's active tab navigates to a merchant, competitor, or checkout page from the extension's offer list.

The extension observes the navigation because it has access to every site the user visits.

The extension did this

The extension sends the visited domain and a persistent client ID to Google Analytics.

The event also names which category the page matched: supported partner, competitor, non-partner, or checkout.

Captured request
POSThttps://www.google-analytics.com/mp/collect?measurement_id=G-504Y0HBTWD&api_secret=<redacted>
Body
{  "client_id": "15f6f5e3-ecb6-4dc0-a7a5-afb9c73bf4fb",  "events": [    {      "name": "automatic_popup_cashback_available",      "params": {        "label": "cyfrowe.pl"      }    }  ]}
Fields in the reported event
  • Persistent client ID
    15f6f5e3-ecb6-4dc0-a7a5-afb9c73bf4fb

    A random ID generated once and stored on your device. Every reported visit carries this ID, linking them to one install.

  • Visited site's domain
    cyfrowe.pl

    The normalized hostname of the merchant, competitor, or checkout page you were on when the event fired.

  • Visit category
    automatic_popup_cashback_available

    Which kind of page you were on: a supported cashback partner, a competitor, a non-partner site, or a checkout page.

The code that does this

From tab navigation to the Google Analytics POST

Readable version

Every tab navigation is routed to the tracker

background.js
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {  await offersLoadedGate;  showPageAction(tabId);  checkVisitedDomain(tabId, tab.url); // Zt() in the shipped bundle});

The matched category becomes the event name; the visited host becomes the label

background.js
const eventNameByCategory = {  [Category.PROMO]: seasonalPromoEventName(),  [Category.COMPETITOR]: "competitor_page_visited",  [Category.NOT_PARTNER]: "non_partner_page_visited",  [Category.CHECKOUT]: "checkout_page_visited",  [Category.WELCOME]: "welcome_page_visited",  [Category.ACTIVATION]: "supported_page_visited",};if (shouldSendStats && matchedCategory && matchedOffer) {  // Strip a leading "www." and use the bare host as the tracked label  const normalizedHost = tabUrl.host    .split(".")    .splice(tabUrl.host.startsWith("www.") ? 1 : 0)    .join(".");  reportEvent({    action: eventNameByCategory[matchedCategory],    category: "impression",    label: normalizedHost, // e.g. "cyfrowe.pl"  });}

reportEvent() builds the Measurement Protocol body and sends it

background.js
function reportEvent({ category, action, label, value, badge_state }) {  const event = {    name: action,    params: {      category,      label, // the visited merchant/competitor domain      value,      version: chrome.runtime.getManifest().version,      engagement_time_msec: 1,      os: getOS(),    },  };  const body = JSON.stringify({    client_id: persistentClientId, // generated once, stored in chrome.storage.local    events: [event],  });  fetch(    `https://www.google-analytics.com/mp/collect?measurement_id=G-504Y0HBTWD&api_secret=<redacted>`,    { method: "POST", body },  );}
Where the data goes
    • www.google-analytics.com

    Google's Measurement Protocol endpoint. Receives the client ID, visited merchant/competitor domain, and matched category each navigation.

What it can do

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

  • See the address and title of every tab you have open

    tabs

  • Act on the current tab, but only after you click the extension

    activeTab

  • Read and change cookies, including the ones that keep you signed in

    cookies

  • Watch every request your browser makes

    webRequest

  • Run its own code inside the pages you visit

    scripting

  • Block and redirect the requests your browser makes

    declarativeNetRequest

declarativeNetRequestWithHostAccess

Where it sends data

Destinations our analysis observed Cashback Assistant 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.

  • www.google-analytics.comwidely used

    Cashback Assistant sends data to www.google-analytics.com. A widely used service: 346 other extensions we have analysed send data here.

Updated 30 September 2026kfkddcifiihcdaaambaijmopndkgpdkh