19

From OWASP page : A CSRF attack works because browser requests automatically include all cookies including session cookies.

To prevent it, we can use double-submit cookie hash.
In some sample codes I found, basically this algorithm is found.

Victim access app:

  1. Backend : generate login cookie AND hash string related to login cookie
  2. Frontend : store the hash string into second cookie (say : CSRF-token cookie)
  3. Frontend (secured) : send request with login cookie and CSRF HTTP header, where the header value is extracted from CSRF-token cookie.

Attacker :

  1. Use some kind of social media engineering to make users click malicious link, where this malicious link use session cookie.
  2. The attacker then steal this session cookie to logged in as victim

Double submit cookie should prevent this attack since attacker also need to provide valid CSRF token in the HTTP header.

I still don't get this: If browser requests automatically include all cookies, that means on clicking malicious link, both login cookie AND CSRF-token cookie will also included, and attacker steal both of them.
So the attacker is just need to extract value from CSRF-token cookie, and create his own API access, using login cookie that he steal, and CSRF HTTP header with extracted value?

Am I missing something?

4 Answers 4

42

A few things appear to be mixed up here.

So in the original synchronizer token pattern, you would generate a random token, store it server-side for the user session, and also send that to the client. The client would then send the token back as a form value or request header, but not as a cookie, so it doesn't get sent automatically - that's the whole point. (And the server would of course compare the token from the request to the one in the session.)

In double posting, the token doesn't even need to be generated server-side, the client can also do it (or the server can send it, doesn't matter that much if we accept that crypto is good enough in Javascript).

The token will be sent as a cookie, and also as something else (form value, request header, anything not sent automatically). If the server sent it as a cookie (obviously without httpOnly), the client can read it from that and include as a non-cookie too in a request. The server will again just compare the two.

The point is that an attacker on attacker.com will not be able to access the cookie (neither read nor write) for the application domain. So if the client can read the cookie and include it as something else in the request, that client must be running on the application origin (if we are talking about unmodified browsers only), so no CSRF is being performed. The client can also create the whole token itself, because attacker.com will still not be able to create a cookie for the application domain.

So based on the above, if everything is just in cookies (nothing related to CSRF is sent as a request header or in the request body), the implementation is wrong, and does not protect against CSRF.

Sign up to request clarification or add additional context in comments.

6 Comments

The final sentence may confuse (me included) some readers that scan the answer. Here might be a better Tl;Dr: "So based on the above, if everything is just in cookies, the Double Submit Cookie implementation is wrong as the CSRF Token remains in the cookie, and is not passed manually in the header or as a form value, then it does not protect against CSRF."
@Tankcom if everything is just in a cookie, the implementation is wrong, regardless of which solution it is. A cookie gets sent automatically, and that defeats the purpose. Something must be sent in a header or the request body as well, that's the whole point. I'll try to clarify this a bit more though, thanks.
> The token will be sent as a cookie, and also as something else (form value, request header, anything not sent automatically). < It is not said on the OWASP page explaining Signed Double-Submit Cookie that the cookie needs to be send as something else, from where do you get that information?
@goulashsoup If the cookie is "signed", that (message authentication, that is) changes the requirements. The above is for unsigned double submit, which is now not recommended anymore. A signed "double submit" cookie is not even double submit, it is in fact enough to send that only once when it is associated with the session. Much has changed since the above answer, for example the SameSite attribute for cookies became widespread, which in many (but not all) cases makes all this quite unnecessary.
Thank you for you reply. > it is in fact enough to send that only once < I quite don't understand that, can you explain why this is the case? (Or do only send once together with SameSite attribute?) Would be cool if you update your answer if you are know what is outdated about it.
|
18

While Gabor has basically answered the question, I just wanted to add some emphasis on some of the important parts, since I was once also confused with this double submit cookie technique.

The main misconception here is to assume that CSRF attack happened because the attacker is able to steal the cookie from the "targetweb.com", while in fact the attacker doesn't need to know the value of the cookie at all!

For the CSRF attack to happen, the attacker only need 4 conditions:

  1. The session on the target site has already been established (user has logged in to the "targetweb.com")
  2. The attacker knows the request format of some operation (e.g transfer fund)
  3. The session token is stored in cookie.
  4. The user trigger something (e.g a button/link), that unbeknownst to him, send a request to the "targetweb.com".

All the attacker need to do is to make the user trigger the request that had been forged by the attacker without the user knowing (and the important part is, the forged request doesn't need to contains the session cookie, since it will be added automatically by the browser later when it is sent -- thus the attacker doesn't need its value).

Now, with the double submit cookie technique, the server send additional value in the cookie. The attacker doesn't know its value. And when a request is made, this value need to be also appended to, say, a request header (which not automatically added). The server is then compare this header value with the cookie value and only proceed when the value match.

What's different from the attacker point of view is now he need to append the value to the header also to make the request valid. And he doesn't know the value, thus CSRF is prevented.

3 Comments

> this value need to be also appended to, say, a request header < This is not mentioned in on the OWASP site explaining Signed Double-Submit Cookie at all. Where do you get the information, that the created cookie needs to be send as a HTTP header in the next request?
Hi @goulashsoup, it is actually mentioned in the "Naive Double-Cookie Pattern" section, which says "Since an attacker is unable to access the cookie value during a cross-site request, they cannot include a matching value in the hidden form value or as a request parameter/header." Although the approach is discouraged in favor for signed double-submit cookie approach, but the only thing that's different is the signing.
this page may remove confusion for those who read OWASP page (it is indeed incomplete - it does not mention comparison to request header or hidden form param) - en.wikipedia.org/wiki/…
0

CSRF protection with double submit cookie is not secure. Therefore, in the OWASP documentation, the double submit cookie is classified as one of defense in depth.

The reason is that cookies can be set by a third party with MITM attack.

HTTPS requests and responses cannot be eavesdropped or modified. However, MITM attack can modify the HTTP response(plain text). An attacker could direct the victim to http://example.com/ (Target site) to send a plaintext http request. Then, in response, the attacker can use MITM to return a Set-Cookie header.

HTTP / 1.1 200 OK
Set-Cookie: CSRFTOKEN=XXXXXXXXXXXXXXXXXXXXXXX;

This CSRFTOKEN is set in the victim's browser. Next, the attacker sets up a CSRF trap page below.

<form action="https://example.com/target" method="POST">
<input type="hidden" name="mail" value="[email protected]">
<input type="hidden" name="token" value="XXXXXXXXXXXXXXXXXXXXXXX">
<input type="submit">
</form>

The destination of the above form is a https page, but the cookie set by http response is also valid on https requests. So the cookie and hidden parameter will be sent the same value, bypassing CSRF protection.

6 Comments

There is middleware for nodejs called csurf. It can be configured to send the csrf secret in the cookie while the token is sent in the header. One can argue that MITM attack here can tamper the cookie with the csrf secret. However, if I sign the part that goes in the cookie (server side) then any tampering with it in the middle will be detected on the server and the CSRF validation will fail. Is this good enough to say we hardened the "inherently" insecure "double submit" pattern?
Yes. Signed tokens are safe because external attackers cannot generate valid tokens.
@ockeghem can't attackers just create their own valid signed token and append their second token in the header and preform a request on behalf of an authenticated user?
@Victor I think the signature is verified server-side, so the attacker signed token is not valid
MITM can be easily mitigated by using encrypted/signed cookies and setting Secure to true. This way cookies are only sent over HTTPS.
|
0

Based what I've read so far, the way double submit cookie works is validate on client. Based on OWASP

When a user visits (even before authenticating to prevent login CSRF), the site should generate a (ideally cryptographically strong) random value and set it as a cookie on the user's machine separate from the session identifier. The site then requires that every transaction request includes this random value as a hidden form value, or in the request header. If both of them match at server side, the server accepts it as legitimate request and if they don't, it would reject the request.

So why it's safe? because

In a nutshell, an attacker is unable to access the cookie value during a cross-site request. This prevents them from including a matching value in the hidden form value or as a request parameter/header.

So, as far as I concern, the value of the csrf token should generate from server to make it safer. I know you've read OWASP. FYI, there are 2 types of double submit cookie:

  1. Naive Double Submit Cookie
  2. Signed Double Submit Cookie

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.