Compromised renderer can forge WebSocket Origin header via IPC, bypassing server-side origin allowlists
Categories
(Core :: Networking: WebSockets, defect)
Tracking
()
People
(Reporter: pakhunov.anton.n, Unassigned)
Details
(Keywords: ai-involved, reporter-external, Whiteboard: [client-bounty-form])
Attachments
(1 file)
|
6.51 KB,
text/markdown
|
Details |
Found by: manual code review of IPC principal validation at component boundaries
Files:
netwerk/protocol/websocket/WebSocketChannelParent.cpp ~line 53
netwerk/protocol/websocket/WebSocketChannel.cpp ~lines 3496, 2824
netwerk/protocol/websocket/PWebSocket.ipdl
Firefox version: mozilla-central (trunk)
OS: all platforms
RecvAsyncOpen accepts aOrigin as a separate nsCString IPC parameter
(defined in PWebSocket.ipdl alongside LoadInfoArgs). The parent passes
aOrigin directly to AsyncOpenNative() without comparing it to the
triggeringPrincipal embedded in the LoadInfoArgs. AsyncOpenNative stores
aOrigin as mOrigin (line 3496), which is then set verbatim as the HTTP
"Origin:" request header during the WebSocket upgrade handshake (line 2825):
rv = mHttpChannel->SetRequestHeader("Origin"_ns, mOrigin, false);
LoadInfoArgsToLoadInfo is called with GetRemoteType() but only uses it to
overwrite the triggeringRemoteType metadata field (lines 726-729) - it does
not validate the principal fields against the sending process's authorized
origins.
Attack (compromised renderer for evil.com targeting bank.com):
- Send RecvAsyncOpen with aURI = wss://bank.com/api,
aOrigin = "https://bank.com" (forged). - Parent sets Origin: https://bank.com in the WebSocket HTTP upgrade request.
- Firefox's HTTP stack automatically attaches bank.com's session cookies
to the request (cookies are sent based on request URI domain, not Origin). - bank.com's server sees: correct session cookies + Origin: https://bank.com
→ accepts connection as legitimate same-origin WebSocket. - Compromised renderer reads all WebSocket frames: account data, API
responses, real-time session events.
Server-side Origin allowlists (the standard CSRF defence for WebSockets)
are completely bypassed.
Impact: cross-origin WebSocket hijacking with full session credentials.
Requires compromised renderer (not triggerable from JavaScript alone).
Updated•7 months ago
|
Updated•7 months ago
|
Updated•7 months ago
|
Updated•2 months ago
|
Description
•