2012-10-30

For a REST-api it seems that it is sufficient to check the presence of a custom header to protect against CSRF attacks, e.g. client sends

"X-Requested-By: whatever"

and the server checks the presence of "X-Requested-By" and drops the request if the header isn't found. The value of the header is irrelevant. This is how Jersey 1.9's CsrfProtectionFilter works and it is described in this blog post: http://blog.alutam.com/2011/09/14/jersey-and-cross-site-request-forgery-csrf/. The blog post also links to NSA and Stanford papers stating that the custom header itself is sufficient protection:

The first method involves setting custom headers for each REST request
such as X-XSRF-Header. The value of this header does not matter;
simply the presence should prevent CSRF attacks. If a request comes
into a REST endpoint without the custom header then the request
should be dropped.

HTTP requests from a web browser performed via form, image, iframe,
etc are unable to set custom HTTP headers. The only way to create a
HTTP request from a browser with a custom HTTP header is to use a
technology such as Javascript XMLHttpRequest or Flash. These
technologies can set custom HTTP headers, but have security policies
built in to prevent web sites from sending requests to each other
unless specifically allowed by policy. This means that a website
www.bad.com cannot send a request to http://bank.example.com with the
custom header X-XSRFHeader unless they use a technology such as a
XMLHttpRequest. That technology would prevent such a request from
being made unless the bank.example.com domain specifically allowed
it. This then results in a REST endpoint that can only be called via
XMLHttpRequest (or similar technology).

It is important to note that this method also prevents any direct
access from a web browser to that REST endpoint. Web applications
using this approach will need to interface with their REST endpoints
via XMLHttpRequest or similar technology.

Source: Guidelines for implementing REST

It seems however, that most other approaches suggest that you should generate a token and also validate this on the server. Is this over-engineering? When would a "presence of" approach be secure, and when is also token validation required?

Show more