WebSocket wrappers do not validate the handshake, so a malformed upgrade is accepted as a live socket
Context: API Makeathon participant. Found while reviewing the generated websocket wrappers.
The generated websocket wrappers send the upgrade headers and a Sec-WebSocket-Key, but they validate only that the HTTP response is not a client or server error status, then call the generic reqwest::Response::upgrade(). They never require status 101, validate the Upgrade and Connection headers, or verify that Sec-WebSocket-Accept matches the key. reqwest::upgrade() is a generic HTTP-upgrade facility, not a WebSocket handshake validator.
Evidence
openapitor/src/functions.rs:74 (the generator) and the emitted wrappers such as kittycad/src/ml.rs.
Concrete failure
A misconfigured server or proxy returns a non-101 or otherwise malformed upgrade (for example a 200 with an unrelated body, or a 101 with an incorrect Sec-WebSocket-Accept). The SDK reports a successful WebSocket connection, and the caller only hits opaque framing or protocol errors later when it tries to use the stream.
Verify
Have a local HTTP listener return 101 Switching Protocols with an incorrect Sec-WebSocket-Accept. The generated wrapper accepts the upgraded stream, while a compliant WebSocket client rejects the handshake.
Suggested fix
After the upgrade request, require status 101, check Upgrade: websocket and Connection: Upgrade, and verify Sec-WebSocket-Accept against the sent key before returning the stream.
Environment
Reviewed against the current main of KittyCAD/kittycad.rs.
WebSocket wrappers do not validate the handshake, so a malformed upgrade is accepted as a live socket
Context: API Makeathon participant. Found while reviewing the generated websocket wrappers.
The generated websocket wrappers send the upgrade headers and a
Sec-WebSocket-Key, but they validate only that the HTTP response is not a client or server error status, then call the genericreqwest::Response::upgrade(). They never require status101, validate theUpgradeandConnectionheaders, or verify thatSec-WebSocket-Acceptmatches the key.reqwest::upgrade()is a generic HTTP-upgrade facility, not a WebSocket handshake validator.Evidence
openapitor/src/functions.rs:74(the generator) and the emitted wrappers such askittycad/src/ml.rs.Concrete failure
A misconfigured server or proxy returns a non-101 or otherwise malformed upgrade (for example a 200 with an unrelated body, or a 101 with an incorrect
Sec-WebSocket-Accept). The SDK reports a successful WebSocket connection, and the caller only hits opaque framing or protocol errors later when it tries to use the stream.Verify
Have a local HTTP listener return
101 Switching Protocolswith an incorrectSec-WebSocket-Accept. The generated wrapper accepts the upgraded stream, while a compliant WebSocket client rejects the handshake.Suggested fix
After the upgrade request, require status
101, checkUpgrade: websocketandConnection: Upgrade, and verifySec-WebSocket-Acceptagainst the sent key before returning the stream.Environment
Reviewed against the current
mainof KittyCAD/kittycad.rs.