Is Savings add-on safe?

Medium risk

Savings add-on sends merchant names and interaction events to Google Analytics using a persistent identifier, without prompting Chrome users for consent.

On Chrome, the extension enables Google Analytics tracking by default and never shows the consent notification that Firefox users see. Each session is tied to a persistent UUID stored in local storage, which is sent alongside events such as installs, logins, and merchant page visits. Merchant names from search and success pages are included in the event labels transmitted to Google Analytics.

Inspiring Benefitsv1.0.28Chrome Web Store
45Risk

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

Publishers can request a review.

Findings

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

Chrome sends merchant activity to Google Analytics by default

Dynamic analysis observed a Google Analytics request from Savings add-on.

Installs start with analytics enabled, prompt disabled; the request used tracking ID UA-173466035-1.

It logs install, login, search, success events with merchant.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You install the extension or interact with merchant-related pages on Chrome.

The extension did this

The extension sends Google Analytics events using a persistent client ID before showing a Google Analytics consent prompt on Chrome.

The code turns that prompt off for Chrome while leaving analytics enabled by default.

02EvidenceNETWORK CAPTURE
Captured request
GEThttps://www.google-analytics.com/collect?tid=UA-173466035-1&cid=980dcb08-f35d-426a-b91a-7bf3b7f4d981
GET request observed during dynamic analysis; no request body was recorded.
03EvidenceFIELD TABLE
Fields sent or constructed for the Google Analytics event
FieldValueWhy it matters
Analytics property
UA-173466035-1Identifies which Google Analytics property receives the extension event.
Client identifier
980dcb08-f35d-426a-b91a-7bf3b7f4d981Lets repeated extension events be tied to the same browser profile over time.
Event category
SERPShows which part of the extension generated the event.
Event action
SERP showDescribes what happened in the extension, such as showing or clicking a merchant result.
Merchant label
AmazonCan reveal which merchant or shopping context was active when the extension event fired.
04EvidenceCODE COMPARE
The code that does this

Analytics defaults, persistent ID storage, and event forwarding

What it actually does
Readable analytics senderbg.js:390-423
class c {
  constructor({
    tid: t,
    cid: e
  }) {
    this.data = {
      v: 1,
      tid: t,
      t: "event",
      cid: e || c.uuidv4(),
      ec: null,
      ea: null,
      el: null,
      ev: null,
      z: null
    }
  }
  static uuidv4() {
    return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, t => {
      const e = 16 * Math.random() | 0;
      return ("x" == t ? e : 3 & e | 8).toString(16)
    })
  }
  static random(t = 1e7, e = 2147483647) {
    return t + Math.floor(Math.random() * (e - t))
  }
  send(t) {
    const e = {
      ...this.data,
      ...t,
      z: c.random()
    };
    return fetch("https://www.google-analytics.com/collect?" + new URLSearchParams(e).toString())
  }
}
Readable Chrome defaultsbg.js:2058-2069
this.isChrome = "chrome" === Object(h.a)();
var r = Object(h.c)(null === (e = chrome) || void 0 === e || null === (e = e.i18n) || void 0 === e ? void 0 : e.getUILanguage());
this.data = {
  locale: r,
  showGuide: !0,
  isAnalyticsEnabled: this.isChrome,
  analyticsClientId: null,
  isNotificationEnabled: !0,
  showGa: !this.isChrome,
  token: null,
  isLocaleChanged: !1
}, this.isReady = !1, this.init()
Readable stored client ID initializationbg.js:2137-2151
case 0:
  return t.next = 1, this.getSettings();
case 1:
  if (e = t.sent, n = e.analyticsClientId) {
    t.next = 2;
    break
  }
  return n = Object(m.e)(), t.next = 2, this.setSettings({
    analyticsClientId: n
  });
case 2:
  Object.assign(this.data, {
    tid: b.f,
    cid: n,
    ev: 1
  }), this.isReady = !0;
Readable sendAnalytics gatebg.js:2998-3003
key: "sendAnalytics",
value: function(t) {
  var e = t.data,
    n = t.sendResponse;
  this.settings.data.isAnalyticsEnabled && this.analytics.send(e), n && n(!0)
}
05EvidenceCODE COMPARE
The code that does this

Merchant names become analytics event labels

What it actually does
Readable search-result event labelscontent/bundle.js:564-579
key: "createSERP",
value: function(A) {
  var B = this;
  Object(j.c)({
    ec: "SERP",
    ea: "SERP show",
    el: A.name
  });
  var E = document.createElement("span");
  return E.className = this.className, E.innerHTML = this.template(A), E.addEventListener("click", (function(w) {
    w.stopPropagation(), w.preventDefault(), B.constructor.onClick({
      el: E,
      merchant: A
    })
  })), E
}
Readable click event labelscontent/bundle.js:609-618
key: "onClick",
value: function(A) {
  var B = A.el,
    E = A.merchant;
  B.parentNode.querySelector("a").click(), Object(j.c)({
    ec: "SERP",
    ea: "SERP click",
    el: E.name
  })
}
Readable success-window event labelscontent/bundle.js:235-265
methods: {
  close: function(A) {
    this.$store.commit("update", {
      merchant: h(h({}, this.$store.state.merchant), {}, {
        showNotification: !1
      })
    }), Object(j.c)({
      ec: "Success Window",
      ea: "Click ".concat(A),
      el: this.merchant.name
    })
  }
},
mounted: function() {
  var A = this;
  return s()(F.a.mark((function B() {
    var E;
    return F.a.wrap((function(B) {
      for (;;) switch (B.prev = B.next) {
        case 0:
          return B.next = 1, Object(M.b)({
            action: "getHtmlContent",
            data: {
              mid: A.merchant.id
            }
          });
        case 1:
          E = B.sent, A.htmlContent = JSON.parse(JSON.stringify(E)), Object(j.c)({
            ec: "Success Window",
            ea: "Show",
            el: A.merchant.name
          });
        case 2:
        case "end":
          return B.stop()
      }
    }), B)
  })))()
}
06EvidenceTHIRD PARTY LIST
External analytics destination
  • www.google-analytics.com

    Receives extension Google Analytics collect events with the tracking ID, client ID, event names, and merchant labels.

Data recipients

www.google-analytics.com
Updated 17 September 2026ldfdohgfoolmacfbdekmbpoofhahcfgg