5

As far as I understand there are two approaches to perform CSRF protection:

1) CSRF token per session - the token is generated once per session. This is the easiest way;

2) CSRF token per request - the new token is generated on each request, and the old one becomes invalid. This is more secure but the webapp might be broken when tabbing and clicking "back" button in the browser.

A few days ago I started to analyze how Node.js Connect framework implements CSRF protection and noticed that it uses the third approach:

New CSRF token is generated on each request, but the old one doesn't become invalid. So there are multiple valid CSRF tokens for the user at once.

My question is: What are advantages of multiple valid CSRF tokens?

Thank you very much.

P.S. I'm not very strong in English so please explain as simply as possible. Thank you again

EDIT (rephrasing my question):

The main benefit of generating new token on each request (and making old one invalid) is that token becomes short term and even if attacker steals the token, it will expire very fast. But with Connect an old token doesn't expire, which makes this approach the same as using single token per session.

So why did Connect developers decide to generate a new token on each request? Am I missing something?

  • Hi Zub, welcome to Information Security! It seems you are basing your question on faulty information and unreliable sources. Can you try to rephrase your question (or maybe just trim it down) to make it clear the specific, practical relevant part of your question? – AviD Feb 9 '14 at 9:25
  • @AviD thank you for your remark. I edited my question – Oleg Feb 9 '14 at 9:58
4

My question is: What are advantages of multiple valid CSRF tokens?

In general, there's no particular security advantage... the important bit about a token is when and how it becomes invalid (as in the previous discussion about whether a token becomes invalid after a single request or not). When and how many tokens are generated is more of an implementation detail:

If you implement CSRF tokens as random values stored persistently (the 'synchroniser token' pattern), you don't really want to store more than one token per session, as it will take more and more database bandwidth to do so. So it's natural in this model to have just a single token stored as an attribute on the session.

If you implement CSRF tokens as a signature (typically: HMAC) over the session assertion then you're validating that token by checking the signature with your application's secret key, so you don't need to store the token at the server side at all. In this model it is cheap to generate/sign a new token every time, and as the tokens typically include a timestamp and a random salt, they'll be different each time.

The usual advantage of the signature method is that you don't need storage, so it can potentially be part of a session-less access control scheme. The disadvantage is you need to manage the secret key safely. (But often you already have that burden anyway.)

However...

So why did Connect developers decide to generate a new token on each request

Unclear. Judging by the code on the linked page Connect has a random value stored on the session, but then the tokens it issues are signatures over this random value and another per-token random value.

This doesn't appear to have any advantages over plain synchroniser-token: you still have to store session attributes, and the issued tokens aren't limited by any other signed restrictions (eg expiry timestamp or revokability). So knowledge of the issued token grants the same access as knowledge of the stored random value. They are fully equivalent, so there's no obvious point in having the varying issued tokens at all, you could just issue the stored random value with no security downside.

3

According to OWASP and per my personal opinion, generating CSRF tokens per session is a much more viable option than generating a token per request.

This can be attributed to a few main reasons:

  • Generating a token per session increases useability, as doing it per request whilst ensuring a higher level of security in doing so, would require to expire the previous token.
  • Generating tokens per request and keeping the old tokens as valid would only reduce security as, the more tokens generated, the more likely it is to brute force one of them. (whilst unlikely to occur if tokens are complex enough, this statement is still true)

In my opinion, creating multiple CSRF tokens on a request basis only makes guessing a valid CSRF token slightly easier. If the tokens themselves are of high entropy and contain a moderate level of randomness - whilst being linked to sessions, it is likely that CSRF protection has been implemented correctly.

The only advantage that I see with this is that users will be able to press the back button, but even if that is the case, why not just use session based CSRF tokens only?

1

Almost all websites - including online banking - should use per-session tokens. If your app launches nuclear weapons, then maybe you'd want per-request tokens, but I doubt you would use a web app for that purpose.

You see a lot of focus on per-request tokens in security guides, but there is no good reason for this. If an attacker is able to steal a CSRF token then you have more to worry about than CSRF. They are likely to be able to steal the session cookie as well, and making your CSRF token per-request does not help with that.

There is no security benefit to the approach Node Connect has taken. I expect they have just read some of these secure development guides that bang on about per-request tokens, found the back button problem, and ended up with a silly kludge.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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