11

According to https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Double_Submit_Cookies:

When a user authenticates to a site, the site should generate a (cryptographically strong) pseudorandom value and set it as a cookie on the user's machine separate from the session id.

(emphasis mine)

Why does the CSRF token need to be stored in a separate cookie if the session id is:

  • a random value (a value the attacker cannot guess)
  • stored in a cookie (a value the attacker cannot read)
  • generated by the server (a value the attacker cannot write)

Why not simply use the session id as the CSRF token? You'd still submit the value twice (once in the cookie, once in the form) and compare the values, but wouldn't use a separate cookie for the CSRF token.

Gili
  • 2,149
  • 3
  • 23
  • 41

2 Answers2

15

The reason is that this allows the main session cookie to be marked HttpOnly (so it won't be accessible to Javascript). There is some debate about how much value this adds, but HttpOnly seems to make some kinds of attacks harder so is arguably a useful hardening measure.

If you didn't use a separate cookie, but just re-used the session ID for these purposes, then Javascript would need the ability to read the session cookie, and we wouldn't be able to mark the session cookie HttpOnly. By using a separate value, it becomes possible to mark the session cookie HttpOnly.

This is why they recommend using a separate value.

D.W.
  • 98,420
  • 30
  • 267
  • 572
3

There are a couple of reasons I can think of:

  • If the CSRF token is leaked, it doesn't leak the authentication cookie.
  • It allows you to set the authentication token as HTTP-only and still have a CSRF value that can be read by JavaScript to build AJAX Requests

Personally, I don't believe the double-submit cookies technique is very effective. While it's not a general CSRF, if I can MITM plain-text traffic of the user, I can then perform CSRF against https-only sites. This is done by injecting an iframe or img with the origin of the site under attack, then responding to the iframe or img with a CSRF cookie of my own, and finally by generating the cross-site request. (Yes, it requires a MITM of the user, but allows to perform a plaintext MITM attack on a site that's served over SSL only without HSTS. Using HSTS mitigates this attack, as pointed out by Gili.)

David
  • 15,814
  • 3
  • 48
  • 73
  • 3
    Aren't all CSRF protections vulnerable to MiTM attacks? Secondly, as I covered at http://security.stackexchange.com/a/61039/5002 using HTTPS with the HSTS header should protect against such attacks. – Gili Jun 16 '14 at 04:18
  • 1
    HSTS absolutely does protect against this attack (didn't see your other post), but since HSTS adoption is not widespread, it's worth noting. And assuming that the MITM is not against SSL and the site never serves the CSRF token over HTTP, then most CSRF protections are not MITM vulnerable. – David Jun 16 '14 at 04:25
  • I'm a little confused. Which CSRF techniques do not "serve the CSRF token over HTTP"? – Gili Jun 16 '14 at 04:35
  • 1
    I was differentiating HTTP vs HTTPS. Unless there's an SSL MITM, not serving the token over plaintext protects the token from the attacker. If an attacker has an SSL MITM, they don't need a CSRF, they can just steal the auth token. The double-submit pattern allows an attacker to set their own CSRF token, other patterns need a token validated against something server-side. – David Jun 16 '14 at 04:41
  • Two questions: 1. What CSRF protection works without "serving the token over plaintext"? Everything under https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet#General_Recommendation:_Synchronizer_Token_Pattern seems to do so. 2. Why do you need the cookie value to be read by JS? I believe AJAX calls automatically submit cookies that match the domain/path. The only thing that AJAX would need to submit is the hidden form field. – Gili Jun 17 '14 at 00:14
  • 1
    @Gili, David is talking about a SSL strippiung attack (the MITM redirects you to HTTP, even though the site actually uses HTTPS). If the site uses HTTPS and puts CSRF tokens in hidden form fields or in URL parameters, it'll be safe against that kind of CSRF attack -- but if the site uses HTTPS (but not HSTS) and uses cookie double-submission, it'll be vulnerable. A valid defense is to put the `secure` flag on all cookies: the session cookie, and also any cookies that are used for CSRF (and ideally use HSTS too). – D.W. Jun 27 '14 at 17:46
  • @D.W. Two clarifications about your last comment. 1. MiTM is like XSS, it invalidates **all** CSRF protections, not just double-cookies. A MiTM can read/write your session cookie. 2. Setting `secure` only helps if you change session id on login, otherwise a MiTM can delete the cookie, recreate it with the flag removed, wait for you to login, and hijack your credentials. – Gili Jun 27 '14 at 18:30
  • @Gili, thanks for the comments. 1. That depends upon the details. A SSL stripping attack is a special kind of attack. It doesn't give the attacker a way to read your session cookie if the session cookie has the `secure` flag set and if the site normally uses only HTTPS. Now consider a scenario where we use one cookie for the session ID and a separate cookie for deriving CSRF values (as you suggested), and imagine that the session cookie has the `secure` flag set but the latter cookie doesn't. I realize this is a narrow case and David's answer would benefit from elaboration. 2. Agreed. – D.W. Jun 27 '14 at 18:44
  • @D.W. 1. Does anything prevent us from setting the double-submit cookie to `secure`? 2. Actually, I think I was wrong. If an attacker uses SSL stripping, what prevents him from reading the new session id we return on login and stripping the secure flag while he's at it? – Gili Jun 27 '14 at 19:27