1

I've asked a question regarding an ASP.NET WebAPI implementation of CSRF protection:

https://stackoverflow.com/questions/45389512/the-anti-forgery-cookie-token-and-form-field-token-do-not-match-when-using-webap/45569019#45569019

Though there's an answer saying that, with default CORS policies, that kind of XSRF token validation with AJAX calls is useless. Is this true, and if so, why?

  • Seems like the definition of "asked and answered." From the answer you accepted in your referenced question: > If an attacker tries to host a malicious AJAX query on his own server it will fail if your back-end server has no CORS policy allowing him to do so (which is the case by default). Unless you specifically allow a remote server to fulfill ajax requests on your behalf (create a CORS policy for them), modern browsers will return null on the request. CSRF by definition, is "cross site" or "cross origin". – DrDamnit Aug 8 '17 at 13:30
  • 3
    You need CSRF protection if you use implicit authentication (typically cookies) but not if you use explicit authentication (a header added by javascript). – CodesInChaos Aug 8 '17 at 13:49
  • You absolutely need a csrf header. The value of the token itself howewer is useless, for now ... I'll eleaborate my answer later, if nobody does before. – Xavier59 Aug 8 '17 at 14:51
  • ajax can't make spoof-able POST calls, without XSS as well, but defense in depth still indicates it. – dandavis Aug 8 '17 at 18:34
3

Yes, you very probably need to run some check to ensure the authenticity of the request.

Basically, what is it possible from a third party website ?

  • Send cross site request from html form with either GET or POST method. It is not possible to set custom headers via html forms. It is not possible to use others methods such as PUT or DELETE. See this question or the RFC.
  • Send cross site request with ajax for whatever method you want (if there is an Access-Control-Allow-Origin and Access-Control-Allow-Methods headers sent by your server) and set custom headers. Please note that GET and POST request are not possible with ajax without those headers while they are with html form !

The different scenarii are as follow :

  • You use the basic javascript XMLHttpRequest object to do GET or POST request. You are vulnerable since this is possible to do the equivalent request from a cross site using html form ! You can protect your site from csrf adding an extra header such as X-CSRF-HEADER and checking for it server side.

  • You use $.ajax from jQuery library for a GET or POST request. Your are vulnerable if you don't do any server side check ! jQuery automatically add an header, X-REQUESTED-WITH, while performing $.ajax request, that you can check server side.

  • You use another method than GET or POST, you are not vulnerable since you can't send cross site request with another method without additional autorization from your website. Still, this is really thine ice (a bug in the browser or HTTP sepcs could change) so you should also protect it against csrf.

The value of the header X-XSRF-TOKEN in your example is at the time I write useless. The most important thing is the presence of the header itself because you can only add a cutstom header with ajax which itself isn't cross site natively possible. Howewer, note that this may change in the future depending of how HTTP specs evolute so that I would advice to check the token value.

  • This is a good answer. Not sure why somebody downvoted it. +1 – stanko Aug 8 '17 at 21:00
0

That answer is not entirely correct. CORS does not apply if the attacker is not using ajax. For example, if your website does not block IFrame usage with the X-FRAME-OPTIONS header, an attacker could simply hide an iframe on their malicious page, and use javascript to do a form.submit().

As CodesInChaos mentioned in his/her comment, the scenario I just mentioned will only work if the request does not have any authorization (The controller action has an [AllowAnonymous] attribute, in the case of ASP.net), or the authentication token is passed in automatically by the browser (As is done with cookies.)

Please note that if you store the session token in javascript, which you must do if you are using a request header, XSS attacks can become much more devastating, since an attacker will then be able to access the session token and impersonate the victims's session. You may want to consider using traditional cookies with the HTTPOnly flag set for storing the authorization token, and adding an anti-CSRF token via javascript.

  • 1
    how would the attacker call form.submit() from the top frame on an off-domain iframe? – dandavis Aug 8 '17 at 18:21
  • 1
    See this answer: stackoverflow.com/questions/17940811/… – user52472 Aug 8 '17 at 18:51
  • that form wouldn't have the token, and thus the request would not work, by design. Neat, but the OP was specifically asking about ajax, so other "attacks" are not germane. XSS info is apropos. – dandavis Aug 8 '17 at 19:01

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.