2

If I have:

  • A web front-end on one domain.
  • A REST API on another domain.
  • The REST API server configured to only allow cross origin requests from the web front-end domain by setting header Access-Control-Allow-Origin to the web front-end domain.

Aside from more hoops to jump through, what additional security does CSRF provide? Attackers can't POST to my backend without first injecting their code into the web front-end, right?

On this question, Chris Pratt said, "[...]So, yes, I think as a rule any API view should be CSRF exempt.[...]". Is that concept valid and does it include my topology?

In my configuration, with CORS properly configured, do I need to decorate GET, POST, PUT, DELETE requests coming from the web front-end with the Cookie and the data element CSRF token?

Meta:
Enlightened individuals may see this question as a duplicate, but I have read this, this, this, this, this, this, and this, and I still need some help. Please help me flesh this idea out more.

Community
  • 1
  • 1
Ross Rogers
  • 21,332
  • 23
  • 99
  • 156
  • 1
    Does the REST API on the server side reject improper CORS requests? If not, you’re still vulnerable to CSRF. – Gumbo Mar 30 '15 at 17:38
  • I'm using [django-corsheaders](https://github.com/ottoyiu/django-cors-headers). I believe it does reject when there are invalid CORS headers, but I'm not certain. – Ross Rogers Mar 30 '15 at 17:45
  • You can test it yourself: make a simple GET or POST, which shouldn't contain any CORS headers in the request, and see if they get rejected. – Gumbo Mar 30 '15 at 17:52
  • Hmm. I used [mitmdump](https://mitmproxy.org/doc/mitmdump.html) and it does look like it is only enforced on the client side. Django + Django Rest Framework is happily sending the data. So if my users are using an ["old"](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing#Browser_support) browser, then they would be vulnerable, unless I somehow change the server configuration. – Ross Rogers Mar 30 '15 at 18:12
  • CSRF aims for triggering server side actions and/or reading their responses. At least for the former it doesn’t matter whether your users’ browsers support CORS. – Gumbo Mar 30 '15 at 18:15
  • I do mostly get how the CSRF protection works. The kicker is, how do you get that CSRF cookie value to the user who is on a different domain? They can't access `documents.cookies`, because they're on a different domain. Then, do you just give another interface on the server where than can simply ask the server what their CSRF token is? That seems rather silly. (I'm not attributing this strawman idea to you.) – Ross Rogers Mar 30 '15 at 18:20
  • Or do I just disallow non-CORS compliant browsers.. [CORS compliance on modern'ish browsers is approaching 98%](http://caniuse.com/#feat=cors) in the US (my target audience) for recent revisions of a given browser. – Ross Rogers Mar 30 '15 at 18:23

2 Answers2

4

In the context of a page loaded from a domain, CORS only controls whether a browser can read XHR responses from another domain. It does not control which domains a browser can make requests to. That is, CORS will relax the Same Origin Policy for any Origins set by your header - but nothing about the Same Origin Policy says that requests cannot be made in the first place.

Other domains can still GET and POST to your domain, it would just be that any responses generated by your site could not be read in client-side script unless allowed by CORS. The actual GET and POST is still received by your server and processed.

Therefore, you still need CSRF prevention - even for users with a CORS compliant browser.

Community
  • 1
  • 1
SilverlightFox
  • 28,804
  • 10
  • 63
  • 132
  • Thank you SilverlightFox. Your wording finally clicked for me. I'm sure it was just density on my part, but I appreciate the explanation. – Ross Rogers Apr 02 '15 at 15:50
2

In a CSRF attack, the attacker's website posts to a website or API using the still valid authentication cookies in your browser.

If you have CORS set up to only allow requests from your site, the request would fail as any modern browser would add an origin header indicating the attacker site.

But this relies on the fact that all your users use a CORS compliant browser. As CORS is still pretty new, this is not something I would assume. If using cookies for authentication, I would recommend to add CSRF protection to your API.

But a better solution is to not base your API on cookie authentication and use token based security which is not susceptible to CSRF attacks.

MvdD
  • 17,926
  • 5
  • 51
  • 83
  • The kicker on cookie/session vs token is that the web client front-end is really much like a normal website. The only difference is that the front-end and back-end are split across two domains. The user is going through a login form to submit credentials to the backend just like any other site with a login. – Ross Rogers Mar 30 '15 at 17:40
  • So your users are authenticating twice? Ones for the front-end and once for the API? That's a bit unconventional. – MvdD Mar 30 '15 at 18:27
  • No. Authenticating on the API is the authentication. The front-end does an AJAX request to the backend for authentication and it uses that authentication as both the front-end and API authentication. – Ross Rogers Mar 30 '15 at 18:31