connectd: treat websocket handshake headers as case-insensitive#9308
Open
coreyphillips wants to merge 1 commit into
Open
connectd: treat websocket handshake headers as case-insensitive#9308coreyphillips wants to merge 1 commit into
coreyphillips wants to merge 1 commit into
Conversation
HTTP header field names are case-insensitive (RFC 9110 section 5.1) and RFC 6455 says the Upgrade and Connection values are treated as ASCII case-insensitive, as the comment in websocketd.c already quotes. The handshake parser matched header names byte-exactly and the values with case-sensitive strstr, so any client that normalizes header casing got 400: notably Node.js's built-in WebSocket (undici) lowercases all request headers and can never connect to a bind-addr=ws: listener, while browsers happen to send RFC casing and work. Match header names case-insensitively in get_http_hdr and use a case-insensitive search for the Upgrade and Connection values. The Sec-WebSocket-Version value comparison stays exact and the key is base64 data, unchanged. Extends the unit test with a lowercased handshake as sent by Node. Fixes ElementsProject#9307 Changelog-Fixed: connectd: the WebSocket port now accepts handshakes from clients that send lowercase HTTP header names, such as Node.js's built-in WebSocket. Signed-off-by: Corey Phillips <corey.lyle.phillips@proton.me>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #9307.
The websocket handshake parser matches header names byte-exactly (get_http_hdr) and the Upgrade/Connection values with case-sensitive strstr. Header field names are case-insensitive per RFC 9110 section 5.1, and RFC 6455 says the Upgrade and Connection values are "treated as an ASCII case-insensitive value" (already quoted in the comment above http_respond).
Practical impact: Node.js's built-in WebSocket (undici) lowercases all request headers, so it can never connect to a bind-addr=ws: listener and gets "400 I only speak websocket". Browsers happen to send RFC casing and work.
Changes:
Verified the failure mode against a live v26.06.1 bind-addr=ws: listener with raw replays (lowercased names rejected before, accepted with this change per the unit test vector).