You could just set the X-Requested-With
header and then check for this server side. Many frameworks, like JQuery, add this automatically to AJAX requests.
X-Requested-With
is a de-facto standard for indicating that the request is made via AJAX.
You do not need a random token as it is not possible for this header to be sent cross domain without the server opting in via CORS.
Therefore, setting and checking a non-standard header is a valid way to protect against CSRF.
The OWASP CSRF Prevention Cheat Sheet does not mention it, however it does mention checking the Origin
header. However, the logic for this is not straightforward as many browsers do not send Origin
for same origin requests.
Also this only works for AJAX requests. With a normal form POST it is not possible to add extra headers. Also, in the past there have been bugs with plugins like Flash that allowed any header to be set enabling an attacker to use Flash to make a cross-domain request. However, issues like these have long since been patched.
If you want a token as well as part of a defence in depth strategy, you could adapt X-Requested-With
to include a random token that you then check. e.g. X-Requested-With: XMLHttpRequest;0123456789ABCDEF
.
Then token could simply be a cookie value created just for CSRF prevention purposes (generated with a cryptographically secure algorithm and entropy source of course).