Search code examples
websocket

Why does the server in a websocket request have to answer a challenge?


I'm reading the websocket specification and it says:

Finally, the server has to prove to the client that it received the client's WebSocket handshake, so that the server doesn't accept connections that are not WebSocket connections. This prevents an attacker from tricking a WebSocket server by sending it carefully- crafted packets using |XMLHttpRequest| or a |form| submission.

I've read it several times, but it's still not clear to me as to why this is necessary.


Solution

  • The challenge-response mechanism forces the server to make sure that the client is a legit WebSocket client, and not a script doing funny stuff.

    The challenge is sent in a "Sec-WebSocket-Key" HTTP header. Since browsers make sure that scripts cannot set "Sec-*" headers, this prevents a script from opening a WebSocket connection through an XMLHttpRequest.

    If the server did not have to answer the challenge, it is possible that some lazy servers would ignore the "Sec-WebSocket-*" headers completely, leaving clients unprotected from rogue scripts.

    It may also be a way of allowing the client to verify that it is talking to a WebSocket server, but I think that is not the main reason, since the server has to send a 101 Switching Protocols status code anyway, along with an "Upgrade: websocket" header.