From 36291ba10d1e4d9e063ffbb887470a4326ded515 Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Mon, 18 May 2026 23:32:18 -0700 Subject: [PATCH] fix(websocket): strip whitespace from Sec-WebSocket-Protocol tokens --- tests/test_websocket.py | 14 ++++++++++++++ websockify/websocket.py | 4 +++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/test_websocket.py b/tests/test_websocket.py index 7f893126..9454de0b 100644 --- a/tests/test_websocket.py +++ b/tests/test_websocket.py @@ -87,6 +87,20 @@ def select_subprotocol(self, protocol): self.assertEqual(sock.data[:13], b'HTTP/1.1 101 ') self.assertTrue(b'\r\nSec-WebSocket-Protocol: gazonk\r\n' in sock.data) + def test_protocol_with_space_after_comma(self): + class ProtoSocket(websocket.WebSocket): + def select_subprotocol(self, protocol): + return 'gazonk' + + ws = ProtoSocket() + sock = FakeSocket() + ws.accept(sock, {'upgrade': 'websocket', + 'Sec-WebSocket-Version': '13', + 'Sec-WebSocket-Key': 'DKURYVK9cRFul1vOZVA56Q==', + 'Sec-WebSocket-Protocol': 'foobar, gazonk'}) + self.assertEqual(sock.data[:13], b'HTTP/1.1 101 ') + self.assertTrue(b'\r\nSec-WebSocket-Protocol: gazonk\r\n' in sock.data) + def test_no_protocol(self): ws = websocket.WebSocket() sock = FakeSocket() diff --git a/websockify/websocket.py b/websockify/websocket.py index 54d4ee1d..a7842e9f 100644 --- a/websockify/websocket.py +++ b/websockify/websocket.py @@ -281,7 +281,9 @@ def accept(self, socket, headers): accept = b64encode(accept).decode("ascii") self.protocol = '' - protocols = headers.get('Sec-WebSocket-Protocol', '').split(',') + # Tokens may be separated by ", " so strip whitespace per RFC 7230 + protocols = [p.strip() for p in + headers.get('Sec-WebSocket-Protocol', '').split(',')] if protocols: self.protocol = self.select_subprotocol(protocols) # We are required to choose one of the protocols