Is Audio to Text + Translation in WhatsApp Web using ChatGPT safe?

Medium risk

🎤 -> 📝 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.

adminv0.90.1Chrome Web Store
45Risk
Who publishes it

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.

Publisher
admin
Registered address
3149 Jazz St, Round Rock, TX 78664-7218, US
Registered contact
Cristian Pereyra

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.

api.kaptionai.com
Also called by 2 other listings
app.kaptionai.com
Also called by 2 other listings
cdn.kaptionai.com
Also called by 2 other listings
flags.kaptionai.com
Also called by 2 other listings
info.kaptionai.com
Also called by 2 other listings
kaptionai.com
Also called by 2 other listings
mcp-ext.kaptionai.com
Also called by 2 other listings
metadata.kaptionai.com
Also called by 2 other listings
news.kaptionai.com
Also called by 2 other listings
payments.kaptionai.com
Also called by 2 other listings, including Audio to Text for WhatsApp Web
schedule.kaptionai.com
Also called by 2 other listings, including Audio to Text for WhatsApp Web
selectors.kaptionai.com
Also called by 2 other listings, including Audio to Text for WhatsApp Web
share.kaptionai.com
Also called by 2 other listings, including Audio to Text for WhatsApp Web

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

MediumunwantedCWE-200Dynamic sandbox

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 did this

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 did this

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 extensions
    cjpalhdlnbpafiamejdnhcphjbkeiagm

    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 found
    1

    A count of other extensions detected on the page in that scan.

  • Where each ID was found
    script

    Whether the extension showed up in a script tag, a stylesheet, or an iframe on the page.

Captured request

POSThttps://api.kaptionai.com/api/v4/report-feedback
Headers
Content-Type
application/json
Body
{  "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 version

Readable: scanning the page for other extensions

chunks/ExtensionDetector-BlWmeVJg.js
scanDomForExtensions() {  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.js
async 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

Updated 2 November 2026iinbhdejcemjafkabjokgeaffgnmijbh