Is GHL Cloner safe?
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.
Who publishes itExtpose - 11 other listings from the same operator, 1 of them carrying a finding
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.
Same store account
11 other listings published from this account, 2.0M+ users between them. 1 of them carries a finding.
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
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 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.
- Installation IDa3c5d552-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 address187.40.254.11
Your current public IP, looked up separately right before each beacon and attached as an override field.
- Event namerun
A fixed label marking the beacon as a heartbeat check-in rather than a specific user action.
{ "client_id": "a3c5d552-7ee6-4161-8195-3500f76e8782", "events": [ { "name": "run" } ], "ip_override": "187.40.254.11"}The analytics module and its call site
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'));- 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.