Preventing CSRF for websockets
Asked Answered
V

2

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!

Valerlan answered 3/9, 2012 at 8:33 Comment(0)
O
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.

Orcein answered 3/9, 2012 at 19:9 Comment(6)
But when authorizing, should a csrf token be included? Authorize is called when a uses calls socket.io.connect()Valerlan
You can supply the io.connect with url parameters and add the token to there.. io.connect('http://example.com?token=' + mytoken')Orcein
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 curiosityLees
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?Lees
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.Orcein
@Orcein Maybe because CSRF is all about exploiting the fact that you are already authorised in order to do malicious stuff on your behalf?Autocephalous
G
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.

Gorga answered 7/9, 2012 at 4:40 Comment(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. christian-schneider.net/CrossSiteWebSocketHijacking.htmlScandic
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.Lindquist

© 2022 - 2024 — McMap. All rights reserved.