5
votes

A component of our webapp is (more-or-less) an SPA. i.e. it runs using javascript, and doesn't generate any page views or refreshes. This can cause CSRF tokens to go stale. Particularly for mobile phone users, who might switch the browser off and open it a few days/weeks later. This SPA occasionally needs to POST updates to the server.

We see some javascript POST requests that generate a 422 error, with a warning about CSRF protection. I'm pretty sure that the CSRF token is present, but is stale. I'm trying to find the best way around it.

If I understand things correctly, and according to OWASP CSRF Cheat Sheet, XHR requests should be safe as long as CORS isn't open on the same endpoint. That is, a malicious site cannot craft a request with an XHR header without javascript. And with javascript, the request should be blocked since it's cross-origin.

The only resource I found had a rather confusingly-written example where CSRF protection is disabled for json. I couldn't work out whether it recommends doing it, or avoiding it.

Is it therefore safe/unsafe to turn off CSRF protection for XHR/json requests on rails where CORS isn't enabled?

1
I created a PR to update the Rails documentation. See github.com/rails/rails/pull/31640gingerlime

1 Answers

0
votes

The short answer is that it is safe, but you need to be careful with CORS.

Here's a snippet from the documentation changes I suggested to rails:

It is generally safe to exclude XHR requests from CSRF protection (like the code snippet above does), because XHR requests can only be made from the same origin. Note however that any cross-origin third party domain allowed via CORS will also be able to create XHR requests. Be sure to check your CORS whitelist before disabling forgery protection for XHR.

Note that I haven't yet had any feedback from the rails team about this.