It is enough presently to check
X-Requested-With HTTP headers to protect against CSRF ?
All CSRF protections that only relies on putting a predictable value in a HTTP header has the same basic problems:
If you enable CORS with
Access-Control-Allow-Headers, you may suddenly be allowing the
X-Requested-Withheader to be set cross origin. Off course, you can solve this by just not setting a bad CORS policy. (The
Refererheader is "forbidden", and can't be set no matter your CORS policy.)
There have been Flash exploits (and if history is any guide, there will be more) that allows headers to be set in cross origin requests. Sure, Flash is dying, but it's not dead yet.
Refererheader might be blank for loads of legitimate reasons (e.g. stripped away by a proxy). To make this check secure you would have to block requests with a blank header, but that would on the same time block many legitimate requests.
So I'm afraid you still need to rely on setting a header (or some other variable) to a value that an attacker can not predict. In practice, this leaves you with a couple of options, such as a classical token, double submit cookie, or using a bearer token in the auth header.
As always, reading OWASP gives a lot of guidance.
OWASP has recommendations on this topic. In short, you should have two-pronged checks:
- Ensure that the source origin is same as target origin. Use either the 'Origin' or the 'Referer' header, in that order of preference. And if neither is present, reject.
- Make use of CSRF token
BTW, you might also want to check out Same site cookie as a means of protecting against CSRF.