Is GHL Cloner safe?

Medium risk

GHL Cloner sends a persistent client ID and public IP address to Google Analytics on startup and hourly alarms.

The background service worker creates or reuses a stored client ID, looks up the browser's public IP address, and sends both in Google Analytics Measurement Protocol events. It sends a run event when the extension starts and repeats the same event every hour.

Extposev1.0.2Chrome Web Store
45Risk
Who publishes it

Extpose - 11 other listings from the same operator, 1 of them carrying a finding

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
Extpose

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

Publishers can request a review.

Findings

GHL Cloner sends your public IP and a persistent ID to Google Analytics hourly

Every time GHL Cloner's background service starts, and again every 60 minutes, it sends your public IP address and a persistent UUID to Google Analytics.

This is not mentioned anywhere in the store listing.

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

You install GHL Cloner, or Chrome restarts while it's installed.

The extension's background service worker starts automatically, with no action needed from you.

The extension did this

The extension looks up your public IP address and sends it, together with a persistent installation ID, to Google Analytics.

It repeats this on its own every 60 minutes for as long as the extension stays installed.

Data included in each Google Analytics beacon
  • Installation ID
    a3c5d552-7ee6-4161-8195-3500f76e8782

    A UUID created once and stored locally. The same value is sent every time, tying every beacon back to one installation.

  • Public IP address
    187.40.254.11

    Your current public IP, looked up separately right before each beacon and attached as an override field.

  • Event name
    run

    A fixed label marking the beacon as a heartbeat check-in rather than a specific user action.

Captured request
POSThttps://www.google-analytics.com/mp/collect?measurement_id=G-WJBWMH18Z0&api_secret=<redacted>
Body
{  "client_id": "a3c5d552-7ee6-4161-8195-3500f76e8782",  "events": [    {      "name": "run"    }  ],  "ip_override": "187.40.254.11"}
The code that does this

The analytics module and its call site

Readable version

Readable equivalent

class Analytics {  constructor(measurementId, apiSecret) {    this.measurementId = measurementId;    this.apiSecret = apiSecret;  }  static async getOrCreateClientId() {    const stored = await chrome.storage.local.get('cid');    let clientId = stored.cid;    if (!clientId) {      clientId = crypto.randomUUID();      await chrome.storage.local.set({ cid: clientId });    }    return clientId; // same value forever, once created  }  async getIp() {    const resp = await fetch('https://checkip.amazonaws.com');    return (await resp.text()).trim();  }  async fireEvent(name, params = {}) {    const ip = await this.getIp();    const event = {      client_id: await Analytics.getOrCreateClientId(),      events: [{ name, params }],      ip_override: ip,    };    await fetch(      `https://www.google-analytics.com/mp/collect?measurement_id=${this.measurementId}&api_secret=${this.apiSecret}`,      { method: 'POST', body: JSON.stringify(event) }    );  }}// Entry point: runs on every service worker start// (api_secret redacted; a real value ships in the extension)const tracker = new Analytics('G-WJBWMH18Z0', apiSecret);tracker.fireEvent('run');chrome.alarms.create('G-WJBWMH18Z0', { periodInMinutes: 60 });chrome.alarms.onAlarm.addListener(() => tracker.fireEvent('run'));
Where the data goes
    • www.google-analytics.com

    Google's Measurement Protocol collection endpoint; receives the persistent client ID and your IP address with every beacon.

    • checkip.amazonaws.com

    An Amazon Web Services IP-echo service, queried only so the extension can learn its own public IP before reporting it to Google Analytics.

What it can do

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

    https://*.gohighlevel.com/*

  • Read and change your data on leadconnectorhq.com

    https://*.leadconnectorhq.com/*

  • Read and change your data on api.ghlcloner.com

    https://api.ghlcloner.com/*

  • Read and change your data on localhost:8080

    http://localhost:8080/*

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

    activeTab

  • Schedule its own background tasks

    alarms

  • Run its own code inside the pages you visit

    scripting

  • Store data in your browser

    storage

  • Sign you in with your Google account

    identity

Where it sends data

Destinations our analysis observed GHL Cloner 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

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

Updated 30 September 2026ibnkfeekkcfadfmhmgoddppejlencnfc