tungstenite-rs icon indicating copy to clipboard operation
tungstenite-rs copied to clipboard

unusual Sec-WebSocket-Key lengths and RFC 6455 4.2.1.5

Open rivkasegan opened this issue 1 year ago • 0 comments

RFC 6455 4.2.1.5 says WebSocket servers are supposed to stop processing a client's handshake if the Sec-WebSocket-Key header doesn't have 16 bytes after decoding. It's one of the 4.2.1 "client did not send a handshake that matches the description below" constraints. Perhaps confusingly, RFC 6455 also says "It is not necessary for the server to base64-decode the |Sec-WebSocket-Key| value." Today, tungstenite doesn't check the length. A client that sends an empty Sec-WebSocket-Key header always gets sec-websocket-accept with Kfh9QIsMVZcl6xEPYxPHzW8SZ8w= (equivalent to the "echo -n 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 | openssl dgst -binary -sha1 | openssl base64" result). Clients that send millions of characters also get a sec-websocket-accept response header. The millions case is separately relevant because of https://github.com/snapview/tungstenite-rs/issues/376 but also causes tungstenite to do SHA-1 and base64 encoding computations on much more data than the RFC requires.

This could be resolved if tungstenite refuses to do "upgrade: websocket" unless a reasonable number of characters is used for the Sec-WebSocket-Key value (e.g., it's often, or maybe always, 24 characters).

I don't know of any applications that are seeing any performance or security consequences from tungstenite's acceptance of arbitrary lengths. This is just a side issue that I'm putting in after finding the https://github.com/snapview/tungstenite-rs/issues/376 one.

rivkasegan avatar Sep 18 '23 02:09 rivkasegan