15

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
  • 251
  • 2
  • 5

1 Answers1

17

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
  • 283
  • 2
  • 11
SilverlightFox
  • 33,408
  • 6
  • 67
  • 178
  • 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