Skip to content

Commit db3bf99

Browse files
committed
fix: check WebSocket MASK bit before reading masking key (RFC 6455 §5.2)
1 parent 43aec6f commit db3bf99

1 file changed

Lines changed: 15 additions & 5 deletions

File tree

code/default/lib/noarch/simple_http_server.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -281,15 +281,25 @@ def WebSocket_receive_worker(self):
281281
if h is None or len(h) == 0:
282282
break
283283

284-
length = ord(h[1]) & 127
284+
# RFC 6455 §5.2: bit 7 of byte 2 is the MASK flag.
285+
# If MASK=1 a 4-byte masking key follows the (extended) length;
286+
# if MASK=0 the payload begins immediately — no key is present.
287+
is_masked = bool(ord(h[1]) & 0x80)
288+
length = ord(h[1]) & 0x7F
285289
if length == 126:
286290
length = struct.unpack(">H", self.rfile.read(2))[0]
287291
elif length == 127:
288292
length = struct.unpack(">Q", self.rfile.read(8))[0]
289-
masks = [ord(byte) for byte in self.rfile.read(4)]
290-
decoded = ""
291-
for char in self.rfile.read(length):
292-
decoded += chr(ord(char) ^ masks[len(decoded) % 4])
293+
294+
if is_masked:
295+
masks = [ord(byte) for byte in self.rfile.read(4)]
296+
decoded = "".join(
297+
chr(ord(char) ^ masks[i % 4])
298+
for i, char in enumerate(self.rfile.read(length))
299+
)
300+
else:
301+
decoded = "".join(chr(ord(c)) for c in self.rfile.read(length))
302+
293303
try:
294304
self.WebSocket_on_message(decoded)
295305
except Exception as e:

0 commit comments

Comments
 (0)