9

I'm currently considering CSRF vulnerabilities in websockets.

I've already blocked all cross-domain websocket requests, however there exist scripts (such as this python bad boy) to get around such security measures.

Is it worth including a token in the user's index.html, which must be included in the socket.io.connect() call as a query string? This way on the server we can check that the token is what we expected, and block the connection request otherwise.

Thanks for all the advice!

user1161657
  • 971
  • 2
  • 10
  • 24

2 Answers2

3

Why don't you setup an authorization handler for your socket.io connections? You can decline / accept connections in there based on information that has been gathered during the handshake.

See https://github.com/LearnBoost/socket.io/wiki/Authorizing for more detailed information about this.

3rdEden
  • 4,388
  • 1
  • 20
  • 18
  • But when authorizing, should a csrf token be included? Authorize is called when a uses calls socket.io.connect() – user1161657 Sep 03 '12 at 19:29
  • You can supply the io.connect with url parameters and add the token to there.. `io.connect('http://example.com?token=' + mytoken')` – 3rdEden Sep 04 '12 at 12:58
  • Hey 3rdEden, what would you do better? a) send _csrf token on every message to the server? or b) Send _csrf token just in `socket.io.connect()`? Just out of curiosity – Herman Junge Feb 15 '13 at 18:18
  • What are the risks of the csrf token appearing in the URL? What about "Man in the middle"? Would it be better to check csrf only in the messages and not in the first connection? – Herman Junge Feb 15 '13 at 20:48
  • 1
    In most cases it would just be enough to the token during connect. I don't see any reason why you would send it for every message as you would already have authorised the connection. – 3rdEden Feb 15 '13 at 20:51
  • @3rdEden Maybe because CSRF is all about exploiting the fact that you are already authorised in order to do malicious stuff on your behalf? – Yaron U. Mar 13 '15 at 01:34
1

I use socket.io with django. The way I handle authorization is that I first require users to login using a regular HTTP form that includes CSRF token. Upon successful login, a session cookie is set and the user is redirected to the socket.io app.

In my connection authorization code, I check the cookie and validate that the user is logged in, returning "401 Not Authorized" if the check fails.

It's also possible to set a CSRF cookie and check for that instead if you don't want to require users to login first, or you could pass the CSRF token as a URL parameter during authorization as @3rdEden pointed out.

Tony Abou-Assaleh
  • 3,000
  • 2
  • 25
  • 37
  • 2
    You may wish to pass the CSRF token during the connection, rather than simply checking the auth cookie. WebSockets send headers even cross domain, which is unlike the way CORS works with XHR. http://www.christian-schneider.net/CrossSiteWebSocketHijacking.html – tilgovi Jan 15 '15 at 15:39
  • 2
    downvote! as noted by filgovi, creating a socket.io connection to your site from an attacker's site would still send the session cookie and thus the attacker's Javascript has full access to the socket.io connection as the user. – Codebling Nov 01 '16 at 00:31