Auth & authIf the resources are not public, you need to handle authentication & authorization by yourself - the protocol gives you nothing by default (apart from cookies & HTTP Auth, which have some issues themselves).
Don't trust the clientServer cannot blindly trust the client. Your application-level protocol should be bullet-proof as the client can be hijacked and/or spoofed. It's best to assume that your protocol will be fuzzed by someone in the future. You need to handle:
- data format issues
- charset & encoding issues
- linebreak issues
- denial of service attacks
and make extensive input validation in the server. Basically, you need to write the Apache equivalent for WebSockets application or trust that someone did it correctly. Good luck!
For example: Socket.IO, the most popular WebSockets server I encountered, in it's short history has used at least 2 incompatible message formats and 2 months ago it could be crashed with trivial payload (it's now fixed). And you need to write an application for Socket.IO with your own invented protocol.
It's beta time!WebSockets protocol is evolving - handshake 76 is currently used in browsers, but the standard will change in the next few months - browsers and WebSocket servers need to keep up.
As an example, Socket.IO still handles old handshake protocol for backwards compatibility. While this is understandable from user's perspective, basically it's a rarely tested branch of code that allows attackers to skip some of the security checks introduced in handshake 76 for a reason.
PlaintextThe communications in ws:// protocol in handled in plaintext, so consider using only it's encrypted wss:// version. We don't need another Firesheep in two years. With SSL, you protect the clients from connecting to a spoofed server and you're not giving the plaintext version of your conversation to anyone listening.
Check the OriginUnless you want to speak with the whole world, validate the Origin of your clients.
By default, Socket.IO allows all origins, which means that you could establish a connection from any domain. Use origins config parameter to narrow that.
XSS can hijack the clientIf the client website has a XSS flaw, it has access to your connection and it can:
- log all messages, both sent and received
- DoS the server
- send arbitrary messages
What is important - don't assume the
WebSockets client is a browser, with it's Same Origin Policy, cookies,
the attacker is determined. Don't take my word for it and check for
yourself - I wrote a simple malicious Socket.IO client in Python. It can:
It's not only browsers
- Handshake with a Socket.IO server
- Ignore all Origin restrictions
- Transparently handle all socket.io heartbeats
- Send arbitrary messages - from a prompt or an input file
- Messages could be raw or properly formatted according to socket.io protocol
- Receive/log all server messages
I also included a few exemplary payloads which can crash servers I encountered. You can test the client against my vulnerable chat application (try XSS).
- Connect (with Chrome or other browser supporting websockets) to http://vuln.nodester.com/chat.html
- Run the command line client
1./socket_io_client.py vuln.nodester.com 80
- Start conversation
- Try to inject XSS from the command line client
You could also use my prepared payloads like so:
./socket_io_client.py vuln.nodester.com 80 < payloads.txt
Or save all server reponses like so:
./socket_io_client.py vuln.nodester.com 80 > output.txt
Just watch this Youtube video for a quick demo:
Socket_io_client is freely downloadable from github.