I\'m trying to understand CSRF tokens and one thing isn\'t making sense to me. F
ID: 655864 • Letter: I
Question
I'm trying to understand CSRF tokens and one thing isn't making sense to me.
For a web API, you can provide a CSRF token just once, on authentication, and expect the client to remember that token (using local storage or some other means) throughout the course of its use of the application. It can be submitted with every request so that we know those requests are genuine, as an attacker cannot know the token without the submitting the user's credentials.
In the browser/HTML, though, the recommendation is to include the CSRF token in a hidden form field. In that scenario, though, the attacker's script can submit a GET request to get the form, grab the token from the response, and use it to submit a POST of the form (and potentially any other form they so desire). Sure, they have to do two things instead of one, but it's still entirely possible as far as I can tell.
When this scenario is mentioned, the replies seem to be something like "you have to rely on the same-origin policy to prevent this." But isn't the entire premise of using these CSRF tokens that we can't rely on the proper implementation of the same-origin policy in user agents? If we're relying on the same-origin policy, why bother with CSRF tokens in hidden form fields in the first place?
Explanation / Answer
You seem to misunderstand both the same-origin policy and CSRF.
The same-origin policy is crucial for any kind of browser security. It makes sure that client-side scripts from one website cannot access information from another site. Without this, we'd have much bigger problems than CSRF: Any website could read our e-mails with our webmail account (while we're logged in), make transactions with our PayPal account, buy products with our shop accounts etc.
So we have to rely on the same-origin policy. If it breaks down, we essentially lose all security, including the CSRF protection.
However, the same-origin policy alone isn't enough. An HTML form may very well point to a different site, so I could prepare a form on my site, use your site as the target and then wait for one of your users to submit the data. If you only check the session ID of the submitter and then accept the request, I've successfully performed a CSRF attack.
That's why we need anti-CSRF tokens: To prevent other websites from