X-CSRF-Token
in an HTTP header or token in the hidden field?I think that X-CSRF-Token
is when I'm using JavaScript / AJAX but I'm not sure.
A CSRF Token is a secret, unique and unpredictable value a server-side application generates in order to protect CSRF vulnerable resources. The tokens are generated and submitted by the server-side application in a subsequent HTTP request made by the client.
A CSRF token is a secure random token (e.g., synchronizer token or challenge token) that is used to prevent CSRF attacks. The token needs to be unique per user session and should be of large random value to make it difficult to guess. A CSRF secure application assigns a unique CSRF token for every user session.
Cross-site request forgery (also known as XSRF or CSRF) is an attack against web-hosted apps whereby a malicious web app can influence the interaction between a client browser and a web app that trusts that browser.
Storing the CSRF token in a JWT makes it possible for the back-end application to verify that it produced the token itself. Combining the CSRF token with an account identifier makes it impossible for attackers to reuse a token for another user, even they were able to replace cookies.
CSRF protection comes in a number of methods.
The traditional way (the "Synchronizer token" pattern) usually involves setting a unique valid Token value for each request and then verifying that unique value when the request is subsequently sent in. It is usually done by setting a hidden form field. The token value is usually short lived and associated to that session, so if a hacker tries to reuse a value they saw previously on the page, or tries to guess the value they will likely fail. So only requests from your application will work and forged requests from outside your application/domain (aka cross site request forgery) will fail.
The downside of that is it requires your application to set this hidden token on all HTML forms. These pages now have to be dynamically generated by an application, when perhaps previously they were static HTML. It can also break the back button (as you need to refresh the form to regenerate another unique CSRF value). You also now need to keep track of valid tokens on the server side and check any requests use a valid token. This can take quite a bit of extra effort to implement and maintain going forward.
An alternative approach (called the "Cookie-to-header token" pattern) is to set a Cookie once per session and the have JavaScript read that cookie and set a custom HTTP header (often called X-CSRF-TOKEN
or X-XSRF-TOKEN
or just XSRF-TOKEN
) with that value. Any requests will send both the header (set by Javascript) and the cookie (set by the browser as a standard HTTP header) and then the server can check that value in the X-CSRF-TOKEN
header matches the value in the cookie header. The idea being that only JavaScript run on the same domain would have access to the cookie, so JavaScript from another domain couldn't set this header to the right value (assuming the page is not vulnerable to XSS that would give access to this cookie). Even fake links (e.g. in a phishing email) would not work either, as even though they would appear to come from the right domain, only the cookie will be set but not X-CSRF-TOKEN
header.
This can be MUCH easier to implement than the Synchronizer token pattern as you don't need to set the token for each call to each form, and the check is relatively simple too (just check the cookie matches the header) rather than tracking CSRF tokens validity. All you need is to set a cookie to a random value for each session. Some front end frameworks will even automatically generate the header for you if they see the cookie (e.g. AngularJS does this for example).
The downside is that it requires JavaScript to work (but that may not be an issue if your app basically doesn't work without JavaScript anyway) and also it will only work for requests the JavaScript makes (e.g. XHR requests) - regular HTML form requests would not set the header. A variation on this (the "Double Submit Cookie" pattern) puts the X-CSRF-TOKEN
value in a hidden form field rather than in an HTTP Header to get around this but still keep the server side logic simpler than the traditional Synchronizer token pattern. It should be noted however that OWASP states some weaknesses with the Double Submit method, when the attacker is able to set the cookie (which is often easier than reading the cookie) so recommends validating the CSRF token in this case.
Additionally the Synchronizer token pattern can allow extra controls to enforce flow (e.g. the hidden field CSRF token will only be set when the application thinks you have sent a valid request in to get that form).
Oh and some security scans will pick up the fact the cookie is not set with the HTTP-Only
flag so can be read by JavaScript - but that's deliberate as it needs to be able to read by that! False alert. You'd think as long as you are using a common name like X-CSRF-TOKEN
they would know not to flag this, but have seen it flagged often.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With