← All issues

[17] SpeechRecognition ASSERT instead of MESSAGE_CHECK for duplicate client

Severity: Medium | Component: WebKit UIProcess | 5db4d93

Rated Medium because the diff upgrades a release-stripped assertion on an IPC-supplied identifier to a MESSAGE_CHECK. The pre-fix release behaviour is silent state divergence — HashMap::add returns the existing entry on collision, so attacker-chosen parameters are dropped and requestPermissionForRequest runs against the wrong origin context.

SpeechRecognitionServer::start validated identifier uniqueness via ASSERT, compiled out in release. m_requests.add is insert-if-absent: on collision the existing entry is returned, dropping the attacker-supplied lang, continuous, origin, mainFrameIdentifier, etc.

Source/WebKit/UIProcess/SpeechRecognitionServer.cpp

- ASSERT(!m_requests.contains(clientIdentifier));
+ MESSAGE_CHECK(!m_requests.contains(clientIdentifier));

Debug-only ASSERT used to enforce an attacker-controlled IPC invariant that must hold in release builds.

The Web Speech Recognition API exposes microphone-backed speech-to-text to web content, gated by per-origin permission prompts. SpeechRecognitionServer runs in the UIProcess; m_requests is a HashMap keyed by SpeechRecognitionConnectionClientIdentifier.

A compromised renderer could re-submit a clientIdentifier already present, causing m_requests.add to silently return the existing entry. requestPermissionForRequest then runs against the stale (origin, frameIdentifier) tuple rather than the freshly-supplied one — a logic-level confusion in a privacy-sensitive code path running in the more-privileged UI process.

This vulnerability weakens the WebContent→UIProcess IPC trust boundary for speech recognition. ASSERT-where-MESSAGE_CHECK-belongs is a recurring class in WebKit.