Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I am in the process of writing a thick client web app using Angular.js (single page app) and was wondering what are the best practices for securing the app using a CSRF token.

Should I send a CSRF token when the app is first loaded then re use that token on every request? Should I have a mechanism to refresh the token? Are there other protections rather than a CSRF token that would make more sense for a single page app?

share|improve this question

2 Answers 2

up vote 4 down vote accepted

Well here is how I ended up implementing CSRF:

On the first request, sets a CSRF token as a cookie. Every subsequent AJAX requests include the CSRF token as a X-CSRF-Token HTTP header.

Django has some nice documentation on how to do this cleanly with jQuery: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

Edit: Apparently. an easier technique would be to whitelist requests that contain the X-Requested-With header. It seems that's what Rails does. I wonder if that's really safe though? Isn't it possible for other domains to fake headers?

share|improve this answer
    
Maybe it's just me, but you probably should have mentioned that you're using Django. Also, the X-Requested-With depends on your same-origin policy. If you've configured your server to allow any form of cross-origin requests, then it can be exploited. –  Adnan May 26 '13 at 5:46
    
I'm not using Django but I re-used the jQuery code in their documentation (I use Node.js). Is it safe to just use X-Requested-With if CORS is disabled? Also, is there a case where you would want to protect against cross origin requests if you explicitly allow them in your same-origin policy? –  Olivier Lalonde May 26 '13 at 7:20
    
This is how the Angular.js team suggest you handle crsf tokens and they automatically extract the token from the cookie and add it to the request. –  BenCr Sep 10 '13 at 18:04

You're in luck! Just about 2 weeks ago I was asked the same question, and after a bit of head-scratching, I came up with the following. Please keep in mind that this is not well peer-reviewed, so we'll see how the comments and voting goes. Personally, I think it's a good technique.

1. First request

Once you receive the first request to load your application, generate a secure random identifier and store it in a session variable on the server, then send it to the client. I'd embed it in the page just before </body>.

<script>setToken('<% print SESSION[TOKEN] %>');</script>
</body>

Your setToken() would assign the token value to the variable in which you'd keep the token.

2. Subsequent requests

With each request you'd add that token to the list of parameters, like token=TOKEN, and the serve would check it against the one stored in the session variable.

3. Refreshing the token

It's not really mandatory, but it's a good idea to refresh the token every once in a while, say 15 minutes. When you get a request after the token expires (you have the expiry time in the session variable), you respond to it normally (act optimistically) but in the response you tell the client that the old token has expired and it should start using the new one.

The client reacts to that by telling the server that it now knows the new token, once the server gets that request it starts using the new token and responds to the client with an OK message, once client receives 200 OK it means that they're both in sync and the client starts using the new token.

Note: A key element in the process is HTTPS usage. You don't want a Man in the Middle to sniff the token. But then again, an MitM would be able to sniff the cookies and hijack the session anyway.

share|improve this answer
    
Thanks for the answer. I am wondering though why it is recommended to have an expiry on tokens. I was under the impression that refreshing tokens was only a means to prevent accidental double form submits. –  Olivier Lalonde May 26 '13 at 3:44
    
@OlivierLalonde Token expiry and refresh is part of a security-in-depth policy. You'd assume that somehow somebody was able to predict the token, or somehow the old token was compromised, so you'd want to limit the access window. –  Adnan May 26 '13 at 5:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.