The synchronizer token pattern is the most effective protection against CSRF attacks. I understand the theory and implementation, but I do not understand why it can't be circumvented.

Generally, the process requires you to visit a malicious site that has a hidden URL that will perform an action against the authenticated site (via img tags, for example). To prevent this, "real" URLs on the site require a token parameter to be passed with them, and this token is compared with a token stored on the session for validity. The assumption here is that the malicious site does not know the token.

What is stopping the malicious site from sending a GET request to the form-submission page and simply reading the token and modifying the hidden link?


If the malicious site sends such a request directly, its request will not be in the session of the victim of the attack, therefore it will receive a different token to the one it would need to successfully attack the victim.

If instead it attempts to trick the victim into making such a request, the received data will be protected by the same origin policy, and it will not be able to read the token from the response.

| improve this answer | |
  • Wouldn't the malicious site be able to use the victim's session (since the browser will pass along the cookie)? Also, I don't understand why the SOP would block the data. If I make a GET AJAX request from the malicious site to the victim's site just to see what the page looks like (and steal the token) - I will get an error/no response? All the malicious site needs to see is the rendered HTML. – WannabeCoder Mar 10 '16 at 21:53
  • 1
    @WannabeCoder The browser won't allow you to access the response to that cross-site request. (except under certain, hopefully harmless, circumstances) – CodesInChaos Mar 10 '16 at 22:00
  • @WannabeCoder Cookies are generally bound to a domain, and are not broadcast on all requests. So to get access to the session cookie, an attacker would have to be on the same domain as the target site. And the SOP blocks Ajax requests before they are sent, so you don't get any HTML response from the target site at all, not even a HTTP response from the target site. – amon Mar 10 '16 at 22:03

Because a remote server does not have access to the user session, and a hardcoded URL cannot rewrite itself to discover and include a token, and because you should prefer POST requests over GET requests for security-sensitive operations. Let's look at a possible sequence of actions.

  • user requests pages from bob.example.com
  • server generates a CSRF token and returns it in a response:

    <a href="/pay-money?to=bob;csrf=s3cr1t">Pay money</a>
  • Eve has injected an image with the malicious URL https://bob.example.com/pay-money?to=eve;csrf=???? into the page. When the user requests this, the link will not work because Eve does not know the correct token beforehand.

  • Eve instead injects a link to her own server. When her server retrieves Bob's page, she gets a different token because it's a completely separate session. She cannot get access to the user's session unless her site uses the same domain as Bob's page.

  • Eve renders a page which embeds Bob's page in an <iframe>. She tries to pick the CSRF token from the DOM, but the security model of the browser prevents this.

  • Eve renders a page which does an Ajax request to Bob's page. She tries to parse it to find the CSRF token, but the browser prevents the request due to the same-origin policy.

So whatever Eve tries, it will fail. This is even more difficult because CSRF tokens are often not just per-session, but per-request. Each request creates a new CSRF token and invalidates any previous tokens. This effectively makes the token a nonce that can be used at most once. Any additional requests would therefore be immediately noticed by the user because their token has expired. To get around the same-origin policy, an attacker will have to inject a script into the site (XSS attack).

| improve this answer | |
  • So it seems like the Same Origin Policy is the explanation... you're saying it will deny the malicious site's AJAX request from viewing any response, even though the browser will pass the victim's session cookie along with the request? – WannabeCoder Mar 10 '16 at 21:57

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.