16

What I know about CSRF is that a malicious website tricks a normal user into issuing a request to a trusted website using a form.

I understand that is possible because we can post forms to different domains. However, I see posts of Stackoverflow that say that one should also protect AJAX requests using a token.

Doesn't the Same-origin policy force an AJAX request to be issued only to the domain that the script was loaded from?

I have heard of Cross-origin resource sharing, but if my understanding is correct it needs the web server to enable it, so a normal server shouldn't allow such request.

Songo
  • 261
  • 2
  • 5

1 Answers1

18

The request can still be sent, just not read:

  • Cross-origin writes are typically allowed. Examples are links, redirects and form sumissions [sic].
  • Cross-origin reads are typically not allowed.

So only the reading of the response is protected by the Same Origin Policy, not the making of the request itself, although only certain headers can be used cross origin without CORS. For example, only the following headers are allowed:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type

Others, such as X-Requested-With are not allowed so the presence of a custom header could be checked as validation that the request wasn't made cross origin or from a non-AJAX form.

Be aware that an old version of flash included a vulnerability that allowed headers to be set that would usually be restricted by the browser, and there was another vulnerability that allowed cross-origin requests to be made without a valid crossdomain.xml to allow the request, so a token based approach may still be the most secure method of preventing CSRF.

jub0bs
  • 307
  • 2
  • 12
SilverlightFox
  • 33,698
  • 6
  • 69
  • 185
  • Can you send a link of a description about this "only read is blocked" feature? (haven't found it with google) Is this really true, that processing POSTs coming from an unknown domain, are not blocked? – inf3rno May 27 '14 at 10:45
  • @inf3rno Sure - I've just added it to my answer. – SilverlightFox May 27 '14 at 11:05
  • Okay, so CORS does not block the requests, just showing the responses to the attacker domain? (aka SOP) So for example I can send an XSS POST, and the server processes the command, I just don't get the response. (When I don't use [these headers](https://www.owasp.org/index.php/List_of_useful_HTTP_headers) ofc.) Am I correct? What is the preflight for, does not it prevent sending the requests? – inf3rno May 27 '14 at 11:11
  • 2
    @inf3rno: If its a simple request (simple method and no custom headers) then the request is sent, but the response cannot be read (unless there's a matching `access-control-allow-origin` for the request Origin). If not a simple request, then it is pre-flighted so the server can let the browser know what methods, domains and headers can be sent and read. [See here for more info on the specifics of CORS](http://www.html5rocks.com/en/tutorials/cors/). – SilverlightFox May 27 '14 at 12:11
  • But if the server needs a session to process the POST request how will the AJAX post succeed? Surely the hacker's script will not be able to access users' session id? – kargirwar Oct 19 '22 at 10:20
  • @kargirwar This is a client-side attack and relies on the user being logged into the target application whilst clicking the attacker's link. As the user will then be logged in, session cookies would be sent with that POST request. – SilverlightFox Oct 20 '22 at 10:15
  • @SilverlightFox But the AJAX is going from hacker's site, right? How will that request have access to user's session cookie? The session cookie would be only available with the original page. – kargirwar Oct 20 '22 at 11:10
  • @kargirwar The hacker's site sends the request, but as it goes through the _user's browser_, the session cookie is sent as the target domain is the vulnerable website, therefore the browser sends any applicable cookies. – SilverlightFox Oct 21 '22 at 08:17