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?