tungstenite-rs
tungstenite-rs copied to clipboard
unusual Sec-WebSocket-Key lengths and RFC 6455 4.2.1.5
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.