Is HP Featured Offers safe?

High risk

HP Featured Offers is high risk. We captured GETs to wild.link/_sales/personalization-url carrying the full URL of every page visited, including search queries. It checks the URL every 3s, forwarding matches unprompted; three fired in one session with device ID 45261043.…

HP Inc.v1.0.3Chrome Web Store
75Risk

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

Publishers can request a review.

Findings

SeverityHIGH
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

URL poller forwards all browsing to wild.link on every page

We captured GETs to wild.link/_sales/personalization-url carrying the full URL of every page visited, including search queries.

It checks the URL every 3s, forwarding matches unprompted; three fired in one session with device ID 45261043.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You navigate to any page, including a Google, Bing, DuckDuckGo, or Yahoo search.

The extension did this

The extension forwards the full URL, including your search query, to wild.link/_sales/personalization-url every three seconds.

Forwarding occurs when the page matches an affiliate merchant domain, a search engine query matching a remote keyword list, or a hostname pattern configured remotely. No consent prompt is shown.

02EvidenceNETWORK CAPTURE
Captured request
GEThttps://wild.link/_sales/personalization-url?d=45261043&tc=WL-EXT-429-ABCD1234&app_version=1.1.1&url=https%3A%2F%2Ffeatured-offers.hp.com%2F%3Finstall_success%3Dtrue
200 OK, no body content captured; request is fire-and-forget.
03EvidenceFIELD TABLE
Parameters sent in each personalization-url request
FieldValueWhy it matters
Full page URL
https://www.google.com/search?q=best+laptop+deals+2024The complete address of the page you are visiting, including path, query string, and any search terms you typed.
Device ID
45261043A numeric ID assigned to your extension install. It lets the server link every request you make across sessions.
Tracking code
WL-EXT-429-ABCD1234A partner attribution code that identifies which affiliate channel referred you. Sent alongside your URL on every request.
App version
1.1.1The installed extension version included in every request.
04EvidenceCODE COMPARE
The code that does this

UrlWatcher, 3-second polling loop and URL forwarding logic (content.js)

What it actually does
const logger = new Logger('UrlWatcher');
class UrlWatcher {
  constructor() {
    this.activeDomain = null;
    this.interval = null;
    this.url = null;
    this.patterns = null;
  }

  run() {
    (async () => {
      // Ask the service worker: is this page an active affiliate merchant domain?
      const { payload: activeDomain } = await sendMessage(MessageStatus.GET_ACTIVE_DOMAIN, {
        url: window.location.href
      });
      this.activeDomain = activeDomain;

      // Download the remotely-configured URL pattern list
      const patterns = await sendMessage(MessageStatus.GET_URL_PATTERNS);
      if (patterns) this.patterns = patterns;

      // Poll every 3 seconds
      if (this.interval) clearInterval(this.interval);
      this.interval = setInterval(() => { this.start(); }, 3000);
    })();
  }

  async start() {
    if (this.url === window.location.href) return; // no navigation, skip
    this.url = window.location.href;

    // Case 1: active affiliate merchant page — send the full URL
    if (this.activeDomain) {
      return sendMessage(MessageStatus.LOG_TRACKED_URL, { url: this.url });
    }

    // Case 2: search engine — send the URL if the query matches a remote pattern
    if (this.isOnSearchEngine()) {
      const parsed = new URL(this.url);
      const query = parsed.searchParams.get('q') ?? parsed.searchParams.get('p') ?? '';
      if (!query) return;
      const matchesPattern = this.patterns?.Searches?.find(
        pattern => new RegExp(pattern, 'i').test(query)
      );
      if (!matchesPattern) return;
      return sendMessage(MessageStatus.LOG_TRACKED_URL, { url: this.url });
    }

    // Case 3: remotely-configured domain pattern match
    if (!this.patterns) return;
    const parsed = new URL(this.url);
    const domainRule = this.patterns.Domains?.find(d => parsed.hostname.includes(d.Domain));
    if (domainRule) {
      const pathMatches = domainRule.IncludePaths?.find(p => new RegExp(p).test(parsed.href));
      const excluded   = domainRule.ExcludePaths?.find(p => new RegExp(p).test(parsed.href));
      if (pathMatches && !excluded) {
        sendMessage(MessageStatus.LOG_TRACKED_URL, { url: this.url });
      }
    }
  }

  isOnSearchEngine() {
    return !![
      'google.com/search',
      'bing.com/search',
      'duckduckgo.com/',
      'search.yahoo.com/search'
    ].find(pattern => window.location.href.includes(pattern));
  }
}
05EvidenceCODE COMPARE
The code that does this

logTrackedUrl, service worker sends the GET request (worker.js)

What it actually does
async logTrackedUrl(payload, extraParams) {
  try {
    // Base URL: this.getURL('/personalization-url')
    // expands to loggingUrl + '/personalization-url'
    // loggingUrl is hardcoded to 'https://wild.link/_sales' (worker.js:42721)
    const endpoint = new URL(this.getURL('/personalization-url'));

    endpoint.searchParams.append('d',   this._client.getDeviceId().toString()); // installation device ID
    endpoint.searchParams.append('tc',  this.getTrackingCode());                 // affiliate tracking code
    endpoint.searchParams.append('app_version', this._client.wildlinkConfig.packageVersion);
    endpoint.searchParams.append('url', payload.url);                            // full visited URL

    if (extraParams) {
      Object.entries(extraParams).forEach(([k, v]) => endpoint.searchParams.append(k, v));
    }

    fetch(endpoint.toString()); // fire-and-forget
  } catch (err) {
    logger.error(err);
  }
}
06EvidenceTHIRD PARTY LIST
Domains receiving URL data
  • wild.link

    Receives the visited URL, device ID, and tracking code via GET /personalization/url. Operated by Wildlink (Cartera Commerce / Rakuten) for affiliate-attribution personalization.

  • www.wildlink.me

    Serves the remote URL-pattern list used to decide which pages trigger forwarding. Changes to this list immediately affect what's reported, no extension update needed.

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-829
SourceAI SANDBOX

Server-Controlled Behavior via Remote Config Feeds at Startup

On startup, HP Featured Offers' worker fetches seven JSON feeds from wildlink.me and storage.googleapis.com, deciding which sites get link rewrites, AI page injection, coupon targets, and search changes, no update needed.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You install or start the extension, no further interaction needed.

The extension did this

The service worker fetches seven remote JSON feeds that govern which sites get affiliate-link rewrites, coupon popups, AI-assistant injections, and search-result modifications.

Responses are cached locally and reloaded every 2-4 hours. The operator can change the extension's behavior across all installations without publishing an update.

02EvidenceFIELD TABLE
The seven remote feeds fetched at startup and what each controls:
FieldValueWhy it matters
URL tracking patterns
https://www.wildlink.me/data/429/url-pattern/1A list of domains and search patterns the extension monitors for affiliate-eligible links. Changing it adds or removes intercepted sites.
Affiliate extension selectors
https://www.wildlink.me/data/429/affiliate-extension-selector/1Selectors that identify other browser extensions present, used to adjust behavior based on competing affiliate tools.
AI injection permissions
https://storage.googleapis.com/ai-injection-control-dvhqwctt/feed/1/429/ai-injection-controlA bitmask enabling script injection into AI-assistant sites (ChatGPT, Claude, Perplexity, Copilot, Gemini); server toggles per service.
Remote variant config manifest
https://storage.googleapis.com/wildlink/cloud-db/1/429/application-experience-remote-config-manifest.jsonFeature flags (e.g. miniEma A/B bucket, activationReassurance) that control UI behaviour and which users see which offer variants.
Coupon targets
https://storage.googleapis.com/wildlink/cloud-db/1/coupon-target/default-coupon-target.jsonJSON lists of merchants and coupon codes to inject into checkout pages. The default and per-domain lists are both fetched remotely.
SERP config
https://www.wildlink.me/data/429/serp-config/1Controls how Google search results are modified: which merchant rates show and how offers are injected.
Conquest campaigns
https://www.wildlink.me/webservice/v1/conquest/campaigns?application_id=429&device_id=8f3a-...&tracking_code=TC-00429Active campaigns with URL patterns and search phrases that trigger full-page overlays. Includes device ID and tracking code as query params.
03EvidenceNETWORK CAPTURE
Captured request
GEThttps://www.wildlink.me/data/429/url-pattern/1
JSON object with Searches[] and Domains[] arrays listing affiliate-eligible site patterns. Cached for 2 hours in chrome.storage.local under key 'urlTrackingPatterns'.
04EvidenceCODE COMPARE
The code that does this

UrlTracking.fetchPatterns(), the URL-pattern feed fetch from worker.js

What it actually does
UrlTracking.fetchPatterns — readable form
// Fetches the list of sites and search phrases the extension monitors.
// Called on startup if cache is expired (2 h TTL).
async fetchPatterns() {
  if (!this._FEED_URL) throw new Error('FEED_URL is not set');
  try {
    const response = await fetch(this._FEED_URL, { method: 'GET' });
    if (!response.ok) throw new Error('Could not fetch url tracking patterns');
    return await response.json();  // { Searches: [...], Domains: [...] }
  } catch (err) {
    return { Searches: [], Domains: [] };  // fail-safe empty
  }
}
Feed URL resolved at build time — app ID 429 baked in
// wildlinkConfig object (worker.js:42724)
const wildlinkConfig = {
  // ...
  urlTrackingFeedUrl: 'https://www.wildlink.me/data/429/url-pattern/1',
  affiliateExtensionsFeedUrl: 'https://www.wildlink.me/data/429/affiliate-extension-selector/1',
  aiServicePermissionsUrl: 'https://storage.googleapis.com/ai-injection-control-dvhqwctt/feed/1/429/ai-injection-control',
  remoteVariantConfig: {
    manifestEndpoint: 'https://storage.googleapis.com/wildlink/cloud-db/1/429/application-experience-remote-config-manifest.json',
    flags: { miniEma: true, activationReassurance: true }
  },
  couponUrlBase: 'https://storage.googleapis.com/wildlink/cloud-db/1/coupon-target/',
  remoteSerpConfigUrl: 'https://www.wildlink.me/data/429/serp-config/1',
  genericConquestUrl: 'https://www.wildlink.me/webservice/v1/conquest/campaigns?application_id=429'
};
05EvidenceSTORAGE DUMP
What's stored on your device

All seven configs are cached and reapplied on every page load; the operator changes behavior via server responses, no store review needed.

Locationchrome.storage.local, config cache keys
Contents (JSON)
{
  "serpConfig": {
    "enabled": true,
    "merchants": []
  },
  "conquestCampaigns": {
    "all": [],
    "campaignsWithUrlPatterns": {},
    "campaignsWithSearchPhrases": {}
  },
  "remoteVariantConfig": {
    "miniEma": 1,
    "miniEmaSettings": {
      "maxPopLimit": 3,
      "maxPopLimitCooldownMinutes": 60
    },
    "activationReassurance": 0
  },
  "serpConfigExpiresAt": "2026-06-08T15:23:37.000Z",
  "urlTrackingPatterns": {
    "Domains": [
      "amazon.com",
      "target.com",
      "bestbuy.com"
    ],
    "Searches": [
      "amazon",
      "ebay"
    ]
  },
  "aiServicePermissions": 7,
  "conquestCampaignsExpiresAt": "2026-06-08T17:08:37.000Z",
  "remoteVariantConfigExpiresAt": "2026-06-08T17:08:37.000Z",
  "urlTrackingPatternsExpiresAt": "2026-06-08T15:08:37.000Z",
  "aiServicePermissionsExpiresAt": "2026-06-08T17:08:37.000Z"
}
06EvidenceTHIRD PARTY LIST
Domains receiving startup config requests:
  • www.wildlink.me

    Wildlink (Wildfire Systems) API. Delivers URL tracking patterns, affiliate selectors, campaign data, and SERP config; the white-label affiliate SDK behind this extension.

  • storage.googleapis.com

    Google Cloud Storage bucket operated by Wildfire Systems, serves AI injection permissions feed, remote variant config manifest, and coupon target JSON files.

Updated 17 September 2026gipgngmeehfjmholacajopgiicmjlddc