9

I ran across this OWASP paper and was frankly confused. I thought this pattern was still one of the cornerstone strategies against CSRF but the paper seems to say it's broken. Should this pattern still be used?

https://www.owasp.org/images/3/32/David_Johansson-Double_Defeat_of_Double-Submit_Cookie.pdf

2
  • Reading the slides state there are vulnerabilities with this approach, but there are ways to mitigate it (e.g. signing the data). The author does not really propose an alternative to the double-submit cookie so much as recommend strengthening weak areas, if I read it right.
    – Joe
    Nov 6, 2019 at 18:31
  • The weakness in csurf highlighted by David Johansson hit the news after a similar find. I am not sure if anyone bothered to register a CVE for it. portswigger.net/daily-swig/…
    – eel ghEEz
    Mar 22, 2023 at 23:32

1 Answer 1

14

Double-submit cookies was always a relatively weak CSRF protection, at least as typically implemented. Any attacker who can set a cookie - either via a cookie injection vulnerability in the app or via man-in-the-middle (MitM) attack - can defeat the typical implementation of double-submit cookies; this has been known for many years. It also requires that the CSRF-protection cookie be Secure-flagged, or a MitM attacker can usually steal it.

There is actually at least one thing that changed in recent years to make double-submit cookies less insecure than before. HSTS (HTTP Strict Transport Security) is a big help; with every major browser supporting HSTS and TLS performance becoming essentially a non-issue, there's less excuse than ever for not using HSTS. HSTS prevents most ways an attacker could steal or set cookies. You can also use the SameSite flag on your session cookies (with most browsers) to block most CSRF attacks; although not directly related to double-submit cookies, these techniques can be combined for additional defense in depth.

If you want to use double-submit cookies for CSRF protection, I recommend cryptographically tying the anti-CSRF token to the session token. A really simple way to do this is just to make your anti-CSRF token (sent in the request body) be an HMAC of the session token (using a secret key stored only on the server or in a hardware security module). This avoids even setting a second cookie specifically for CSRF protection, but an attacker cannot meaningfully spoof the token because changing the session cookie will break the user out of their own session. Alternatively, you can set an anti-CSRF cookie, and then have the token value be an HMAC of the cookie and some user identity data (such as a username or user ID); this means that your users will not need to update their anti-CSRF tokens every time their session token changes (which might be frequent, if using a short-lived JWT or similar) but an attacker won't be able to log in themselves, find a valid CSRF-cookie + CSRF-token combo, and plant those values in a victim's browser session (or rather, it won't work if they do, because it will be for the wrong user). Additionally, use HSTS (on all sites, including subdomains, and add it to the preload list) and, if you can, also use at least the "lax" SameSite flag. Neither of these will protect users on IE10- (or similarly old browsers), but you probably don't have many such users.

5
  • 1
    about "tying to a session token"; Storing a token on the server is not double submit cookie, as the purpose of that pattern is to avoid DoS by exhausting storage. The trade-off is that the value must be deterministic so cannot be fully random, as it must be verified without a backend storage.
    – gcb
    Mar 20, 2023 at 19:44
  • @gcb I never said anything about storing a token on the server! You have some kind of session token in a cookie (else you don't need anti-CSRF at all!), but it doesn't have to be a server-stored value, it could be a JWT or some other kind of stateless token, and you can still use a hash/HMAC of that token as your anti-CSRF token, without needing any server-side state or slow lookups. But also, even if you do store a token server-side, you can still reduce the amount of server-side state vs. separate server-stored anti-CSRF tokens by using the one server-stored token for both things.
    – CBHacking
    Mar 21, 2023 at 8:50
  • purpose of double submit cookie is to not have a server side session.
    – gcb
    Mar 27, 2023 at 17:55
  • Sort of. It's to not have to store session state related to CSRF on the server, which is obviously important if you don't want to store any session state on the server. (In theory you could use a double-submit cookie even if you are storing some state on the server.) However, tokens that don't require server-side state (such as JWTs) can still be used to establish and track a session, and if those tokens are placed in a cookie, then a value derived from that token can be used to create an anti-CSRF token, without a second cookie or the risks inherent to double-submit cookies.
    – CBHacking
    Mar 28, 2023 at 12:35
  • Yes, everything is about tradeoffs. And yes nobody said you cannot use a more complex solution to something. But if you lack (or don't want to DoS yourself by storage exhaustion) and don't want to support JS (which actually makes things more insecure if you see the comment on the question), double submit cookies are fine, specially with modern browsers and HSTS.
    – gcb
    Mar 29, 2023 at 19:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .