Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4 skipping protect_from_forgery for API actions

An attacker could CURL at your controllers all they like, but if your API requires authentication, they wont get anywhere.

Making the API consumers send a CSRF is not really what CSRF does. To do this you'd need to implement a type of knocking mechanism where your client hits an authorization endpoint first to get the code (aka CSRF) and then submit it in the POST. this sucks for mobile clients because it uses their bandwidth, power, and is laggy.

And anyway, is it actually forgery (i.e. the F in CSRF) if its an authorized client hitting your controller after all?


Sending the CSRF token in an HTTP header is indeed a common approach. It ensures that the client has somehow obtained a valid token. For example, a crafted CSRF link will be sent with credential cookies but the header will not include the CSRF token. Your own javascript on the client will have access to domain cookies and will be able to copy the token from a cookie to the header on all XHR requests.

AngularJS follows this approach, as explained here.

As for your first two questions:

  1. This solution seems to leave the CSRF hole open...

Indeed, which is why you should not disable the CSRF token also in your API.

  1. Would checking for an API token be a reasonable substitute? ...

Probably not. Take into consideration the following (from OWASP):

CSRF tokens in GET requests are potentially leaked at several locations: browser history, HTTP log files, network appliances that make a point to log the first line of an HTTP request, and Referer headers if the protected site links to an external site.

General recommendation: Don't try to invent the wheel. OWASP has a page called REST Security Cheat Sheet as well as the one I linked to before. You can follow the Angular approach (copying the token from a cookie to a header on each XHR request) and for regular non-ajax forms, be sure to use only POST and a hidden field as is normally done in CSRF protection of static server forms.