Is Audio to Text in WhatsApp Web using ChatGPT safe?

Low risk

🎤 -> 📝 in Wpp™ is low 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.68.2Chrome Web Store
20Risk

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

Publishers can request a review.

Findings

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

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.

01EvidenceCAUSE EFFECT
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.

02EvidenceFIELD TABLE
What gets sent when the scan finds another extension
FieldValueWhy it matters
IDs of your other browser extensions
cjpalhdlnbpafiamejdnhcphjbkeiagmAny other extension that visibly injects into the WhatsApp Web page gets its store ID read and sent to Kaption.
Your WhatsApp phone number
+15551234567Sent alongside the extension list so the report can be tied back to your specific account.
How many extensions were found
1A count of other extensions detected on the page in that scan.
Where each ID was found
scriptWhether the extension showed up in a script tag, a stylesheet, or an iframe on the page.
03EvidenceNETWORK CAPTURE
Captured request
POSThttps://api.kaptionai.com/api/v4/report-feedback
Headers
Content-Typeapplication/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\"}]}"
}
04EvidenceCODE COMPARE
The code that does this

The DOM scan and the report it triggers

What it actually does
Readable: scanning the page for other extensionschunks/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 resultschunks/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")
  }
}
05EvidenceTHIRD PARTY LIST
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).

Updated 17 September 2026iinbhdejcemjafkabjokgeaffgnmijbh