0

I sometimes run into sites with CSRF bugs and I want to know the simplest way to recommend for the developer to fix it. (i.e., if I tell them "Switch to a framework that has anti-CSRF protection", they won't listen.)

Anecdotally, it looks like most sites mitigate CSRF by including a random token as a hidden form field, and then rejecting the form submission of the token isn't present. (And it usually looks hand-crafted, not inserted by the framework.)

I'm wondering why it isn't much simpler (and hence, much more common practice) to do "double-submit cookie" -- where you take the session id cookie and put it in a hidden form field, and then reject the form submission if the hidden field value doesn't match the session id cookie.

First, the problems with the "random token" approach, if your framework doesn't have it built-in: You have to generate a random value and store it server-side, and in your storage table it must be associated with the user it was served to. When the form is posted, you have to check that the value is there, check it's associated with the logged-in user, and then delete it so it can't be re-used. If you screw up any part of this, you've potentially created a security hole. And, you might need to create a new database table for your tokens, which is just more cruft. (Yes, I know you can do it using hashes and secret values, but that's also error-prone.)

By contrast, consider the ease of using the session cookie. (You don't want to use an authentication cookie, because if the authentication cookie is stored in a hidden form field, an xss bug might be able to read it. But session-id cookie is probably safe.) ALL you have to do is store it in a hidden form field, and then check the value when the form is submitted.

So, I contend that IF the website in question has a framework that uses session cookies, I can tell them that the easiest way to fix it is by using double-submit-cookie with the "session-id" cookie, and to ignore all the webpages which usually start out by talking about how to protection against CSRF by using random tokens.

Am I missing something? Does double-submit-cookie have some disadvantage?

Anders
  • 64,406
  • 24
  • 178
  • 215
Bennett
  • 653
  • 3
  • 9

1 Answers1

2

I can't tell if you independently re-invented double-submit cookies and didn't think anybody'd thought of it before, or just didn't do any research on a well-known topic. https://duckduckgo.com/?q=double+submit+cookie+weakness&ia=web has no lack of results, including some from this very site (see Double Submit Cookies vulnerabilities and Is the double submit cookie pattern still effective?).

Your approach is slightly novel in using the session cookie (which you seem to think is distinct from an "authentication" cookie; I'm sure there exists a site that separates those but they're generally the same thing). The problem is, then you're exposing the session cookie to script (either via the DOM or by making the cookie non-httponly). This isn't the end of the world; indeed, it's pretty common to pass your session token as an HTTP Authorization: bearer header value that is set by script and avoid cookies altogether (this has the added advantage of being inherently secure against CSRF, since the browser won't automatically forward any authorization data; the attacker would need to already know it in which case they could submit the request directly). Also, by the time the attacker can read your DOM or document.cookie, there's a ton of other nasty stuff they can do; the httponly flag is a really minor patch.

A refinement of this pattern is to use a cryptographic hash of the session token, stored either in the DOM (usually in a hidden form field) or in script-accessible data somewhere. It can be a keyed hash (such as an HMAC), but honestly it doesn't need to be; the attacker won't be able to reverse the hash anyhow, and if they have the session token already they don't need to generate the hashed value because they can just send a GET request and the server will send the value back.

Normal double-submit cookies are weak as a CSRF mitigation because there are ways to plant a cookie, especially if the target site doesn't use HSTS. If the attacker can plant their own anti-CSRF cookie value, then they can successfully forge requests from the victim's browser by including that cookie value in the body, too. Using the session cookie works around this - the attacker can still overwrite it, but then they've de-authorized the victim's browser which kind of defeats the point of CSRF - but adding a single round of SHA-256 or similar on top of the session cookie lets the actual session cookie value remain invisible to script.

CBHacking
  • 40,303
  • 3
  • 74
  • 98
  • I used the term "double-submit cookie" in my question, so obviously I did look it up first. But many of the commonly objections to double-submit cookie either didn't make sense, or applied equally to the token approach. For example, yes, a session cookie is often separate from (and generally less secure than) an authentication cookie. (By an "authentication cookie", I mean a cookie that if an attacker steals it, they can splice it into their browser and impersonate you.) For example my amazon.com "session-id" cookie is 132-5768540-8092851. Can you do anything with that? – Bennett Jan 31 '20 at 18:45
  • Also, you are correct that the double-submit cookie can be defeated if "the attacker can read your DOM or document.cookie" or "If the attacker can plant their own anti-CSRF cookie value". But my point is that under these assumptions, an anti-CSRF token seems just as vulnerable. If they can read the DOM, they can get the CSRF token. And if the attacker "can plant their own CSRF cookie value" -- well, the ability to do that (by injecting script, or inserting arbitrary HTTP headers) would generally also imply the ability to read the DOM and hence the CSRF token. – Bennett Jan 31 '20 at 18:59
  • However, I think you are right that using a one-way hash of the session id is more secure than using the session id. It guards against the possibility of harm when all of the following are true: (a) the session id by itself can be used to do harm; (b) the attacker gains access to the DOM or source code of the page but, for whatever reason, they don't also have access to the session id cookie. – Bennett Jan 31 '20 at 19:02
  • The standard term for what you're calling an "authentication cookie" is in fact "session cookie", in the sense that it ties your client to an (authenticated) session. I don't know what Amazon's doing, but it doesn't matter what they name the cookies. I never said that CSRF protection is what you're bypassing if the attacker can read the DOM, I said that you're exposing the session cookie (the thing an attacker uses to hijack your session) in the case of XSS or a few less-common attack vectors. – CBHacking Jan 31 '20 at 21:35
  • As for planting a cookie, that doesn't require either script or header injection (although those are ways to do it). The easiest, if you can MitM the victim, is just to inject an invisible request to the site via HTTP into some other HTTP page's response, and then intercept the HTTP request to the target site and forge the response (including cookie). Cookies set via HTTP are still transmitted over HTTPS, sometimes even overriding a cookie that was set via HTTPS (implementation-specific, but the attacker can tune the attack to the user's client). HSTS blocks this, but it's still uncommon. – CBHacking Jan 31 '20 at 21:38
  • OK, I didn't realize that secure cookies could be set from an insecure connection ( https://security.stackexchange.com/questions/140940/can-a-secure-cookie-be-set-from-an-insecure-http-connection-if-so-why-is-it-al says this is actually what the RFC says to do ). That, combined with a MitM attack, is what I was looking for: a scenario that defeats double-submit-cookie but does not defeat CSRF-token, even holding all other assumptions constant. – Bennett Jan 31 '20 at 23:30