Is Pixdownify Image Downloader safe?

Medium risk

Pixdownify Image Downloader sends hourly Google Analytics heartbeat events with a persistent extension client ID.

At startup and once every hour, the service worker posts a run event to Google Analytics using a UUID saved in local extension storage. The request includes the client ID, a session ID, and engagement timing; Google also receives network metadata for that request.

Pixdownify Image Downloaderv1.0.8Chrome Web Store
48Risk

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

Publishers can request a review.

Findings

Pixdownify sends an hourly analytics heartbeat with a persistent tracking ID

Every time the service worker starts, and again every 60 minutes, Pixdownify Image Downloader sends a persistent installation ID to Google Analytics.

No page content, browsing history, or credentials are included in this telemetry.

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

The background service worker starts on install, browser launch, or a 60 minute timer.

A chrome.alarms task named after the Google Analytics measurement ID refires this every hour.

The extension did this

It posts a persistent installation ID to Google Analytics.

The request carries a stable client ID created once and stored locally, plus a session ID and the event name run.

When this fires

Every 1 hour

Fires once when the service worker starts, then every 60 minutes via a chrome.alarms timer for as long as the extension stays installed.

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

204 No Content, the standard empty acknowledgement for Measurement Protocol.

Body
{  "client_id": "c7e59fed-ecc4-42ae-ae9a-b712a8a5f3c0",  "events": [    {      "name": "run",      "params": {        "session_id": "1725800000000",        "engagement_time_msec": 100      }    }  ]}
What each heartbeat reports
  • Installation ID
    c7e59fed-ecc4-42ae-ae9a-b712a8a5f3c0

    A random ID generated once and stored locally, then reused on every future analytics event.

  • Session ID
    1725800000000

    A timestamp based ID marking when the current browsing session began.

  • Event name
    run

    The action being reported. Every heartbeat is logged as run.

  • Engagement time
    100

    How long the service worker reports being active, in milliseconds.

Where the heartbeat goes
    • www.google-analytics.com

    Receives the installation ID and heartbeat event under a Google Analytics 4 property; Google's standard analytics retention applies.

The code that does this

The analytics client and its hourly alarm

Readable version

Renamed equivalent

class Analytics {  constructor(measurementId, apiSecret, debug = false) {    this.measurement_id = measurementId;    this.api_secret = apiSecret;    this.debug = debug;  }  async getOrCreateClientId() {    const stored = await chrome.storage.local.get('cid');    let clientId = stored.cid;    if (!clientId) {      clientId = uuidv4();      await chrome.storage.local.set({ cid: clientId });    }    return clientId;  }  async fireEvent(name, params = {}) {    if (!params.session_id) params.session_id = await this.getOrCreateSessionId();    if (!params.engagement_time_msec) params.engagement_time_msec = 100;    await fetch(`https://www.google-analytics.com/mp/collect?measurement_id=${this.measurement_id}&api_secret=${this.api_secret}`, {      method: 'POST',      body: JSON.stringify({ client_id: await this.getOrCreateClientId(), events: [{ name, params }] })    });  }}function startAnalytics(measurementId, apiSecret) {  const analytics = new Analytics(measurementId, apiSecret);  analytics.fireEvent('run');  chrome.alarms.create(measurementId, { periodInMinutes: 60 });  chrome.alarms.onAlarm.addListener(() => analytics.fireEvent('run'));}startAnalytics('G-CP734HTL3Y', '<redacted>');

What it can do

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

  • Run its own code inside the pages you visit

    scripting

  • Schedule its own background tasks

    alarms

  • Start, monitor and manage your downloads

    downloads

  • Store data in your browser

    storage

  • Block and redirect the requests your browser makes

    declarativeNetRequest

Where it sends data

Destinations our analysis observed Pixdownify Image Downloader 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

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

Updated 30 September 2026kjeimdncknielhlilmlgbclmkbogfkpo