Is Vetted AI: Your Shopping Agent safe?

Medium risk

Vetted AI: Your Shopping Agent is medium risk. Clicking the Vetted shopping control can send the current page URL to api.vetted.ai to request an affiliate redirect. If the server returns a different URL, the worker opens it inactive and removes it about seven seconds after loading.

yahoo.commerce.browser.extensionv5.4.0Chrome Web Store
45Risk

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

Publishers can request a review.

Findings

Affiliate redirect opens in an inactive tab after a shopping click

Clicking the Vetted shopping control can send the current page URL to api.vetted.ai to request an affiliate redirect.

If the server returns a different URL, the worker opens it inactive and removes it about seven seconds after loading.

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

You click a Vetted shopping control on a retail page.

The code path is tied to the dog-ear panel and the Vet This Product button.

The extension did this

The extension requests an affiliate redirect and can open it in an inactive tab.

If the returned URL differs from your current page, the tab is removed about seven seconds after it loads.

Fields used for the affiliate redirect lookup
  • Current shopping URL
    https://www.amazon.com/Sony-WH-1000XM5-Canceling-Headphones-Hands-Free/dp/B09XS7JWHH?th=1

    Shows the product page where you used the Vetted shopping control.

  • Context URL
    https://vetted.ai

    Adds browsing context for the affiliate redirect request.

  • Click source
    Product Button

    Indicates which shopping control led to the redirect request.

Captured request
POSThttps://api.vetted.ai/queries
Headers
Content-Type
application/json
Body
{  "queries": {    "storePageInfo": {      "0d19bd9994e96770": {        "url": "https://www.amazon.com/Sony-WH-1000XM5-Canceling-Headphones-Hands-Free/dp/B09XS7JWHH?th=1"      }    }  }}
The code that does this

Click handlers that trigger the affiliate-cookie message

Readable version

Dog-ear click path with readable formatting

dogEar/dogEar.js
let L;const R = a => ({    clientY: o  }) => {    document.addEventListener("mouseup", N(a), {      once: !0    }), L = o  },  N = a => ({    clientY: o  }) => {    null !== L && Math.abs(o - L) > f.minDragDistance || (_ && (0, k.openSidePanel)({      url: _,      type: S    }), null == a || a(), (0, m.default)("set_affiliate_cookie", {}), (0, l.default)("dog ear clicked", Object.assign({      category: "dog ear",      label: _,      url: location.href,      targetUrl: _,      type: S    }, E)))  }

Product button click path with readable formatting

dogEar/dogEar.js
o.default = ({  styles: a}) => {  const o = (0, r.default)("button", {    styles: a,    attributes: {      class: "lux-root lux-ProductPageButton lux-unstyledButton"    }  }, [(0, r.default)("img", {    attributes: {      class: "lux-ProductPageButton-Icon",      src: n.default.runtime.getURL("/assets/images/icons/logo.svg")    }  }), (0, r.default)("div", {    attributes: {      class: "lux-ProductPageButton-Copy"    }  }, ["Vet This Product"])]);  return o.addEventListener("click", () => (0, i.default)("set_affiliate_cookie", {    source: "Product Button"  })), o}
The code that does this

Background handler that opens and removes the inactive tab

Readable version

Readable setAffiliateCookie handler

background/background.js
e.setAffiliateCookie = (o, e) => c(void 0, void 0, void 0, function*() {  var a, c, t, l, p, d;  const h = null !== (a = o.url) && void 0 !== a ? a : null === (c = e.tab) || void 0 === c ? void 0 : c.url,    g = null !== (t = o.source) && void 0 !== t ? t : void 0,    {      FEATURE_TOGGLES: {        AFFILIATE_MONETIZATION: b      }    } = yield(0, i.getFullConfig)();  if (b && (null === (l = e.tab) || void 0 === l ? void 0 : l.id) && h) {    const a = s.default.get(new URL(h).hostname),      {        isCookieSet: c,        isStandingDown: t,        targetDomain: l      } = null !== (p = yield(0, r.getAffiliateStatus)(e.tab.id)) && void 0 !== p ? p : {};    if (!(c || t && a === l)) {      const {        SITE_HOSTNAME: c      } = yield(0, i.getEnvConfig)(), {        url: t      } = yield(0, u.default)("affiliateLinkV2", {        url: h,        contextUrl: null !== (d = o.contextUrl) && void 0 !== d ? d : c,        source: "extension"      });      if (t !== h) {        const o = yield m.default.tabs.create({          url: t,          active: !1        });        if (void 0 !== o.id) {          const c = (e, a) => {            e === o.id && "complete" === a.status && (m.default.tabs.onUpdated.removeListener(c), setTimeout(() => {              m.default.tabs.remove(e).catch(() => null)            }, 7e3))          };          return m.default.tabs.onUpdated.addListener(c), yield(0, r.setAffiliateStatus)(e.tab.id, {            isCookieSet: !0,            isStandingDown: !1,            targetDomain: a          }), yield(0, n.track)("affiliate cookie set", {            url: h,            source: g          }), !0        }      }    }  }  return !1})
Hosts involved in the observed and code-backed flow
    • api.vetted.ai

    Receives extension query requests, including the observed product-page query and the code-backed affiliate redirect lookup.

    • vetted.ai

    Loads the Vetted shopping panel and is the default context URL used by the affiliate redirect handler.

Updated 30 September 2026cjmfiochlaffhnellbhffgnjocahinnh