Is Audio to Text + Translation in WhatsApp Web using ChatGPT safe?
🎤 -> 📝 in Wpp™ is medium risk. Once a day on web.whatsapp.com, the extension scans the page for other browser extensions you have installed and sends their IDs, plus your WhatsApp phone number, to Kaption's servers.
Who publishes itadmin - 2 other listings from the same operator, none carrying a finding
admin - 2 other listings from the same operator, none carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same store account
2 other listings published from this account, 1k+ users between them, none of them carrying a finding.
Shared hosts - 13 hostnames
Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
This WhatsApp extension reports your other browser extensions to its server
Once a day on web.whatsapp.com, the extension scans the page for other browser extensions you have installed and sends their IDs, plus your WhatsApp phone number, to Kaption's servers.
What actually happens
You browse web.whatsapp.com while another extension that injects a script, iframe, or stylesheet into the page is installed.
No WhatsApp AI-transcription feature needs to run for this to happen.
The extension reads the other extension's ID off the page and sends it, with your WhatsApp phone number, to Kaption's server.
This runs automatically once a day; there is no setting to turn it off.
What gets sent when the scan finds another extension
- IDs of your other browser extensionscjpalhdlnbpafiamejdnhcphjbkeiagm
Any other extension that visibly injects into the WhatsApp Web page gets its store ID read and sent to Kaption.
- Your WhatsApp phone number+15551234567
Sent alongside the extension list so the report can be tied back to your specific account.
- How many extensions were found1
A count of other extensions detected on the page in that scan.
- Where each ID was foundscript
Whether the extension showed up in a script tag, a stylesheet, or an iframe on the page.
Captured request
- Content-Type
- application/json
{ "user": "+15551234567", "userPlan": "FREE", "userTier": "unknown", "userDays": 42, "userLanguage": "en", "eventSource": "extension", "feedbackType": "extension-detection", "feedbackComment": "{\"scanTimestamp\": 1757296800000, \"extensionCount\": 1, \"extensions\": [{\"id\": \"cjpalhdlnbpafiamejdnhcphjbkeiagm\", \"name\": \"uBlock Origin\", \"source\": \"script\", \"urlScheme\": \"chrome-extension\"}]}"}The code that does this
The DOM scan and the report it triggers
Readable: scanning the page for other extensions
chunks/ExtensionDetector-BlWmeVJg.jsscanDomForExtensions() { const e = new Map; return document.querySelectorAll("script[src]").forEach(t => { const s = t.getAttribute("src") || ""; this.extractExtensionId(s, "script", e) }), document.querySelectorAll('link[href][rel="stylesheet"]').forEach(t => { const s = t.getAttribute("href") || ""; this.extractExtensionId(s, "stylesheet", e) }), document.querySelectorAll("iframe[src]").forEach(t => { const s = t.getAttribute("src") || ""; this.extractExtensionId(s, "iframe", e) }), document.querySelectorAll("style").forEach(t => { const s = t.textContent || "", l = Array.from(s.matchAll(/url\(['"]?(chrome-extension|moz-extension):\/\/[^'")\s]+['"]?\)/g)); for (const u of l) this.extractExtensionId(u[0], "stylesheet", e) }), e}extractExtensionId(e, n, a) { const c = e.match(p.chrome); if (c) { const s = c[1]; s !== this.ownExtensionId && !a.has(s) && a.set(s, { source: n, urlScheme: "chrome-extension", url: e }); return } const o = e.match(p.firefox); if (o) { const s = o[1]; a.has(s) || a.set(s, { source: n, urlScheme: "moz-extension", url: e }); return } const t = e.match(p.safari); if (t) { const s = t[1]; a.has(s) || a.set(s, { source: n, urlScheme: "safari-extension", url: e }) }}Readable: reporting the results
chunks/ExtensionDetector-BlWmeVJg.jsasync reportResults(e) { try { const n = this.getProxy(); globalThis?.reportKpi?.("extension-detection-complete"), e.extensionCount > 0 && globalThis?.reportKpi?.(`extension-detection-count-${Math.min(e.extensionCount,10)}`); const a = { scanTimestamp: e.scanTimestamp, extensionCount: e.extensionCount, extensions: e.extensions.map(t => ({ id: t.id, name: t.name, source: t.source, urlScheme: t.urlScheme })) }, { UserData: c } = await g(async () => { const { UserData: t } = await import("./page-only-DoGME4AX.js").then(s => s.aB); return { UserData: t } }, __vite__mapDeps([0, 1, 2]), import.meta.url), o = c.getInstance(); await n.reportFeedback({ user: "+" + (o?.getUserPhone?.() || "unknown"), userPlan: o?.getUserPlan?.() || "unknown", userTier: o?.getUserTier?.() || "unknown", userDays: o?.getTotalUserDays?.() || 0, userLanguage: o?.getLanguage?.() || "unknown", eventSource: "extension", feedbackType: "extension-detection", feedbackComment: JSON.stringify(a) }), r.debug("Results reported successfully") } catch (n) { r.error("Error reporting results:", n), globalThis?.reportKpi?.("extension-detection-error") }}Where the scan results go
- info.kaptionai.com
Looks up the name, description, and user count for each detected extension ID (Kaption AI's own backend).
- api.kaptionai.com
Receives the full report: the detected extension list plus your WhatsApp phone number (Kaption AI's own backend).
What it can do
Permissions this extension asks for, as declared in version 0.80.2. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to. The current listed version is 0.90.1, which we have not unpacked yet.
Read and change your data on huggingface.co
https://huggingface.co/*
Read and change your data on cdn-lfs.huggingface.co
https://cdn-lfs.huggingface.co/*
Read and change your data on cas-bridge.xethub.hf.co
https://cas-bridge.xethub.hf.co/*
Store data in your browser
storage
Run hidden pages in the background
offscreen
Store an unlimited amount of data in your browser
unlimitedStorage