How would you secure WebSockets communication on your project?

Technology CommunityCategory: Web SecurityHow would you secure WebSockets communication on your project?
VietMX Staff asked 3 years ago

You should strongly prefer the secure wss:// protocol over the insecure ws:// transport. Like HTTPS, WSS (WebSockets over SSL/TLS) is encrypted, thus protecting against man-in-the-middle attacks.

The WebSocket protocol doesn’t handle authorization or authentication. Practically, this means that a WebSocket opened from a page behind auth doesn’t “automatically” receive any sort of auth; you need to take steps to also secure the WebSocket connection.

Since you cannot customize WebSocket headers from JavaScript, you’re limited to the “implicit” auth (i.e. Basic or cookies) that’s sent from the browser. Further, it’s common to have the server that handles WebSockets be completely separate from the one handling “normal” HTTP requests. This can make shared authorization headers difficult or impossible.

You can use the Origin header as an advisory mechanism—one that helps differentiate WebSocket requests from different locations and hosts, but you shouldn’t rely on it as a source of authentication.

One pattern I would use that seems to solve the WebSocket authentication problem well is a “ticket”-based authentication system. Broadly speaking, it works like this:

  • When the client-side code decides to open a WebSocket, it contacts the HTTP server to obtain an authorization “ticket”.
  • The server generates this ticket. It typically contains some sort of user/account ID, the IP of the client requesting the ticket, a timestamp, and any other sort of internal record keeping you might need.
  • The server stores this ticket (i.e. in a database or cache), and also returns it to the client.
  • The client opens the WebSocket connection, and sends along this “ticket” as part of an initial handshake.
  • The server can then compare this ticket, check source IPs, verify that the ticket hasn’t been re-used and hasn’t expired, and do any other sort of permission checking. If all goes well, the WebSocket connection is now verified.