Search code examples
javascriptwebcsrf

CSRF prevention for GET requests


From what I've read, CSRF prevention seems to focus on (1) making GET requests side-effect-free and (2) using only POST requests with CSRF tokens to alter state. It seems to me, though, that this assumes that the only objective an attacker might have would be to maliciously update the victim website. What if the attacker just wants information which can be retrieved via a GET request? Couldn't someone embed a sensitive resource from the victim site into the attacking site and interact with it via Javascript?

So my questions are (1) is that possible, and (2) how do you prevent it?


Solution

  • An attacker could include the following script on their page:

    $.get('http://vulnerable.example.com/json')
    

    However, due to the Same Origin Policy, the JavaScript on the attacker's domain couldn't read the response. The same origin policy checks whether the domain, protocol and port match - if they don't the JavaScript will encounter a security error when trying to read the response. For example, this is the warning Chrome gives when trying to access an IFrame from another domain - this is exactly the same mechanism that will protect the JavaScript response.

    Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': blocked a frame with origin "http://evil.com" from accessing a frame with origin "http://vulnerable.example.com". Protocols, domains, and ports must match.
    

    So in summary, POST requests must use a CSRF token as the POST request will still be made even though the response cannot be read and GET requests are not normally a cause for concern as the response cannot be read and they are non destructive. There was the issue with JSON Hijacking, but you have to go back as far as Firefox 3 to find a browser vulnerable to this. See Is JSON Hijacking still an issue in modern browsers?