2

I'm not sure if I am describing something that has already been proposed. If not, I would like to coin this "Signed Double Submit Cookies" as a method to improve the Double Submit Cookies technique that attempts to prevent CSRF attacks.

Here is the concept:

  1. Before outputting a web page, the server sets a cookie in the header where the value includes two values:

    • token value generated from a strong random number, and

    • signature value which is the signature of the token (or maybe simply a hash of it that has been salted).

  2. When the client makes subsequent requests, it reads the cookie and includes the token+signature in the POST or GET requests (along with the cookie being automatically in the request headers).

  3. When the server receives the request, it authenticates by:

    • checking if the token+signature included in the POST or GET requests matches the cookie value in the request header, and

    • taking the (cookie/query string) token value and signs it again and compares if the resulting signature matches the (cookie/query string) signature value. If matches, it proves that the cookie has not been blindly written by a subdomain or something else.

For the sake of argument, let's assume that XSS attack preventions have been properly implemented and SSL only is true.

Has this method been used before? Does it properly prevent the attack where a subdomain writes cookies to the parent domain?

[EDIT: Originally I had the token and signature in two separate cookies, but to simplify as suggested by @SteffenUllrich, I have edited the question to reflect both the token and signature in one cookie.]

Joseph Shih
  • 123
  • 6
  • Why use two cookies and not simply a signed cookie, i.e. value and signature inside the same cookie? That is a common way to protect cookies against tampering or guessing. – Steffen Ullrich Apr 25 '16 at 05:02
  • Good point. That also works too. Just putting the signature there. Still maintaining the statelessness of this defence. – Joseph Shih Apr 25 '16 at 05:27
  • Thanks @SteffenUllrich, I edited the question and included your suggestion. – Joseph Shih Apr 25 '16 at 05:33

2 Answers2

2

The problem with naive double submit is that if the attacker could insert an attacker controlled cookie he could also set the CSRF token to this cookie and this way defeat the CSRF protection - because token and cookie match.

This can be defeated if the attacker is not able to create a CSRF token and guess the matching verification cookie. This can be achieved by having some server side secret which is used in creating the verification cookie from the CSRF token, i.e. some signature using a server side private key, a hash of secret+token or similar. In this case it does not matter if the signature is a separate cookie, is included in the verification cookie or if you only use the signature as the verification cookie.

Thus in this case I think your solution might help against the problems with native double submit but is unnecessary complex: you don't need two cookies but you could simply use the signature as the verification cookie. For verification just try to sign the CSRF token and if it matches the signature everything is fine. And the attacker is not able to create a token and a matching signature because he does not know the server side secret needed for the signature.
EDIT: Note that the signature should also include information regarding the current user, e.g. the session id. Otherwise it would be possible for some other user to obtain a valid token+signature pair and reuse it.

Note that none of this helps if the attacker gets access to both the CSRF token and the verification cookie because in this case this could be used for reusing this pair. But this is not the attack scenario double submit cares about, i.e. it assumes that reading the cookie is protected by using httpOnly cookies and a protected connection (https) and no way for XSS either.

Steffen Ullrich
  • 184,332
  • 29
  • 363
  • 424
  • Hmm, what do you think about the comments from @Daisetsu answer? http://security.stackexchange.com/a/121442/108663 – Joseph Shih Apr 25 '16 at 06:24
  • The linked question @JosephShih mentioned in his question was using the assumption that only part of the website was secured via https, and that a insecure sub-domain could be used to write a cookie for the entire domain (thus allowing a force of the cookie value). You're right that this is a moot point if everything is covered by https. – Daisetsu Apr 25 '16 at 06:30
  • @JosephShih: these are good comments which show that it is not enough to have a single server wide secret but that you need to take the session in account, i.e. some cookie like `hash(csrf-token+session-id+secret)`. The session-id must of course change with each change. But if this is not the case you also have attacks like session fixation. I've edited my answer accordingly. – Steffen Ullrich Apr 25 '16 at 06:51
  • @Daisetsu: the signature protects against cookie submission using a problem of the subdomain. This problem might be insecure transport but could also be XSS. The https protection I refer to is only relevant for the domain where the proper signed cookie is used because if the attacker is able to *read* the cookie (instead of only write a cookie) then all this protection is useless. But this is the case with all kinds of CSRF tokens, session IDs etc. – Steffen Ullrich Apr 25 '16 at 07:19
1

I don't believe this would provide any more protection then the normal double submit cookies.

If an attacker can overwrite one cookie using an unsecured (https) subdomain, they could just as easily overwrite 2 cookies.

The attacker in the senario would get a legitimate token and signed token value, they would embed both of those in the request, and write those two cookies to the browsers cache using the subdomain vulnerability.

Daisetsu
  • 5,110
  • 1
  • 14
  • 24
  • But how would the attacker be able to sign it without the proper private key on the server? – Joseph Shih Apr 25 '16 at 06:08
  • The attacker doesn't need to sign the original token. The attacker requests a token and signed token when they load the log in page. The attacker DOESN'T login themselves, but sends both the legitimate tokens (original and signed) to the victim using the previously mentioned subdomain vulnerability. – Daisetsu Apr 25 '16 at 06:13
  • They're essentially acting as a man in the middle. – Daisetsu Apr 25 '16 at 06:14
  • So you're saying that the attacker gets his own set of token+signature from the server directly first, and then uses that set and exploits the subdomain attack. After that, he can forge requests. Is that correct? – Joseph Shih Apr 25 '16 at 06:20
  • Yes, it's exactly the same scenario as the one described in the other security.stackexchange thread you linked. – Daisetsu Apr 25 '16 at 06:21