1

So I essentially went on an epic voyage to figure out how to implement CSRF tokens. 20 years later - and now I feel like I just wasted my life. haha

So basically after making malicious test-clients and doing some re-reading it looks like it's virtually not a problem if:

1) You don't allow outdated browsers(they don't enforce CORS)

2) You don't allow CORS by setting the "Access-Control-Allow-Origin" on the resources.

3) You use a JSON API(all requests-responses is sending JSON).

4) You take care of XSS(they can inject code that will run from same origin ).

So as long as you take care of XSS(Reactjs! Holla) - all of the above(minus the old browser part I guess) is basically common practice and an out-of-the-box setup - so it seems like a waste of time to worry about csrf tokens.

Question:

So in order to avoid throwing my laptop under a moving car - is there any reason that I did all that work adding CSRF tokens if I am already adhering to the 4 prevention strategies mentioned above?


Just Fun Info - wanted to share one juicy find my tests came across:

The only ify thing I found with my tests is "GET" requests and an image tag

e.g.

<img src="http://localhost:8080/posts" onload={this.doTheHackerDance} />

The above will pass your cookie, and therefore access the endpoint successfully, but apparently since it is expecting an image - it returns nothing - so you don't get to do the hacker dance. :)

BUUUUT if that endpoint does other things besides return data like a good little "GET" request(like update data) - a hacker can still hit a "dab!" on ya (sorry for viral dance move reference).


Nick Pineda
  • 5,464
  • 11
  • 39
  • 60

2 Answers2

1

tl;dr - Requiring JSON requests mitigates CSRF, as long as this is checked server-side using the content-type header.

Do we need to use them in most cases?

In most other cases, yes, although there are workarounds for AJAX requests.


1) You don't allow outdated browsers(they don't enforce CORS)

2) You don't allow CORS by setting the "Access-Control-Allow-Origin" on the resources.

CORS is not required to exploit a CSRF vulnerability.

If Bob has cookies stored for your site, CORS allows your site to allow other sites to read from it, using Bob's browser and cookies.

  • CORS weakens the Same Origin Policy - it does not add additional security.
  • The Same Origin Policy (generally - see below for caveat) does not prevent the request from being made to the server, it just stops the response being read.
  • The Same Origin Policy does not restrict non-Javascript requests in any way (e.g. POSTs made by <form> or <img> HTML directives).
  • Browsers that do not support CORS, also do not support AJAX cross-origin requests at all.

Therefore while not outputting CORS headers from your site is good for other reasons (other sites cannot access Bob's session), it is not enough to prevent CSRF.

3) You use a JSON API(all requests-responses is sending JSON).

Actually, if you are setting the content-type to application/json and verifying this server-side, you are mitigating CSRF (this is the caveat mentioned above).

Cross-origin AJAX requests can only use the following content-types:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

and these requests are the only ones that can be made using HTML (form tags or otherwise).

4) You take care of XSS(they can inject code that will run from same origin ).

Definitely. XSS is almost always a worse vulnerability than CSRF. So if you're vulnerable to XSS you have other problems.

BUUUUT if that endpoint does other things besides return data like a good little "GET" request(like update data) - a hacker can still hit a "dab!" on ya (sorry for viral dance move reference).

This is why GET is designated as a safe method. It should not make changes to your application state. Either use POST as per the standard (recommended), or protect these GETs with CSRF tokens.

Community
  • 1
  • 1
SilverlightFox
  • 28,804
  • 10
  • 63
  • 132
  • "Cross-origin AJAX requests can only use the following content-types" assuming Adobe never screws up again :) – Neil McGuigan May 04 '16 at 17:35
  • You can further mitigate this by [combining it with a token](http://stackoverflow.com/a/30054341/413180). Yes, everything has a caveat in this dynamic web world. Who's to say Adobe don't screw up in a different say, by accidentally enabling cross-domain reads under certain circumstances perhaps? – SilverlightFox May 05 '16 at 08:47
0

Please just follow OWASP's guidelines: "General Recommendation: Synchronizer Token Pattern". They know what they're doing.

CSRF counter-measures are not hard if you're using a framework. It's dead simple with Spring Security for example. If you're not using a security framework, you're screwing up big time. Keep it simple. Use one general method to protect against CSRF which you can use on many types of projects

  1. CSRF is orthogonal to CORS . You are vulnerable even if you disallow CORS on your server and your users use the latest Chrome. You can CSRF with HTML forms and some JavaScript.
  2. CSRF is orthogonal to XSS . You are vulnerable even if you have no XSS holes on your server and your users use the latest Chrome
  3. CSRF can happen against JSON APIs. Rely on Adobe keeping Flash secure at your own peril

The new SAMESITE cookie attribute will help, but you need anti-CSRF tokens until then.

Keep reading

Neil McGuigan
  • 41,314
  • 10
  • 106
  • 137
  • @NickPineda CORS is about allowing *reading* data. CSRF is about *sending* data. CORS doesn't deal with *sending* data – Neil McGuigan May 03 '16 at 19:38
  • I thought CSRF was about exploiting how cookies work with the browser to make unintended authorized requests(both POST and GET). XHR and libraries built on top of it (AJAX) won't allow POST requests(sending data) without CORS enabled on the server. – Nick Pineda May 03 '16 at 20:40
  • @NickPineda you don't need AJAX to do CSRF . Also, are you going to rely on Adobe to not screw up Flash in the future? – Neil McGuigan May 03 '16 at 21:33
  • All the caveats of security on the web - the biggest headache of building good web applications. – Nick Pineda May 03 '16 at 22:03