The common way to prevent CSRF requests: Each time the user loads a page that contains a form to be POSTed, the user is issued a CSRF token that it supposed to be unknown to potentially malicious third-party sites. The token is issued both as a cookie and as a hidden <form> field. The client is supposed to authenticate each POST request by putting a valid CSRF token in the request's body and by presenting a valid cookie.

Let's say the user is logged in to example.com and, on another tab, browses to evil.com; and evil.com wants to attack example.com/form.html. I understand that evil.com can issue a POST request to a example.com/form.html and this site will interpret this malicious POST request as a valid request coming from the user. CSRF tokens prevent this scenario, because they are supposed to be unknown to evil.com; it cannot send the correct token with its maliocious POST request, so the example.com server will reject that request.

And here comes the part I fail to understand. The CSRF token is issued both as a cookie and as a hidden form field. For the cookie part, this is trivial: IIUC every request to example.com automatically contains all cookies that come from example.com; so, assuming that on another tab the user is logged in to example.com, the malicious POST request will contain the valid CSRF cookie. Is this correct?

For the hidden form field part, this get slightly more complicated, but not much. Evil.com can issue a GET XMLHttpRequest to example.com/form.html and that request will succeed, because the user is logged in to this site on another tab and because GET requests aren't protected by CSRF. In response, evil.com gets example.com/form.html HTML source, which contains the <form> in question, which in turn contains the hidden <input> field with the CSRF token. Evil.com can now parse the received document, extract the token and bundle it with its subsequent malicious POST request to example.com/form.html, theferore succesfully completing a CSRF attack.

What is wrong in my above reasoning? What am I failing to understand?


You are correct that the browser will send the CSRF-cookie from example.com with the request. However, because of the Cross Origin Resource Sharing the script on evil.com can not read the CSRF-token embedded in the webpage on example.com/form.html.

So the script on evil.com can not access the cookie, since it belongs to another domain. And it can not read the token in the form, because the browser won't allow it to read the content of the page.

The script on evil.com could read the token in the form if example.com allowed the domain in its Access-Control-Allow-Origin-header. This would mean example.com has explicitly whitelisted evil.com to be able to read the response content.

  • 2
    ACAO with a wildcard wouldn't even help here because the request would be unauthenticated (sent without cookies) and the form token be useless. – Arminius May 18 '18 at 13:23
  • @Arminius That is indeed correct, I will correct this in my answer. – Eelke May 18 '18 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.