Expected Behavior
Documentation can state that if you have a multi-page app like one that mounts React components where the API requests are handled by the JavaScript, you can keep deferred loading and breach protection via HttpSessionCsrfTokenRepository and using X-CSRF-TOKEN (not X-XSRF-TOKEN) header. You don't need to use CookieCsrfTokenRepository in those cases and you can have the default CSRF configuration without any customization.
The only thing you need to do is to put the CSRF token inside the page in a global JS variable or a meta tag and configure your HTTP library to send it with the X-CSRF-TOKEN header which is already recognized by the HttpSessionCsrfTokenRepository;
Current Behavior
Documentation is not clear for such scenarios and I had to check the source code to find my way out of it.
Context
This applies to applications that send CSRF tokens to REST APIs via JavaScript and want to get all the benefits of deferred loading and BREACH protection.
Example code:
Spring security config:
public DefaultSecurityFilterChain myFilterChain(
HttpSecurity http) throws Exception {
return http
.csrf()
// ... other settings
.build()
}
JavaScript API with AXIOS
const http = axios.create({
// ... any axios config settings
headers: {
'X-CSRF-TOKEN': window.CSRF_TOKEN;
},
})
Thyemeleaf layout
<script th:inline="javascript">
window.CSRF_TOKEN = '[(${_csrf.token})]',
</script>
Comment From: sjohnr
@ckalan thanks for this input in improving the CSRF documentation!
I have updated the main CSRF chapter of the reference documentation for the 6.1 release. You can preview it here: https://docs.spring.io/spring-security/reference/6.1-SNAPSHOT/servlet/exploits/csrf.html
You may note that the old docs actually did have an example of using meta tags to access the CSRF token and include it in a header, but I think it was not very clear. I have completely reworked the page to flow through numerous examples including the use of meta tags, and actually used your suggestion to capture this option under the heading "Multi-Page Applications" which feels like a helpful way to organize it!
I did not incorporate your suggestion of using a global variable, as I felt that was a bit too specific for our reference docs, as the existing example (organized and elaborated more thoroughly) should hopefully lead users in the right direction. I could be wrong of course, and if you still feel the docs need improvement, let me know.
In the meantime, I'll close this as a duplicate of gh-13089, but this was valuable for the docs refresh, thanks!
Comment From: ckalan
@sjohnr Thanks for the changes. I think that's perfect now. Global variable was just an example. I think it is much better to have the examples with the meta tags as you've done.
Comment From: JurrianFahner
Unfortunately this documentation is not applied to the 6.0.x version. I was able to apply the directions from 6.1.x on the 6.0.x based spring-security. Not everyone can upgrade to 6.1.x yet, for example due to the use of spring-cloud.
Comment From: sjohnr
Understood @JurrianFahner, sorry you didn't find the documentation in the version you needed. We generally apply enhancements (including documentation) on our main branch, so it will only apply to the most recent version when the docs were updated. I believe the 6.1 docs should cover you just fine on the 6.0 release. You can check What's New in 6.1 and our releases for information on what's changed. You can see that the CSRF feature did not change in 6.1.
Comment From: JurrianFahner
@sjohnr The problem is in version 6.0 that there breaking changes were introduced in version 6.0 (because of semantic versioning) and that's fine. For people that are implementing stuff based on this version would read documentation for version 6.0. It would be convenient if improvement of documentation in the later version is retrofit in the earlier versions (when applicable and e.g. only for one minor patch version before).
I created an issue #13910 to raise attention to this (small) problem. The reason that I commented on a closed issue, is to help the community to mention the applicability of 6.1 on the 6.0 delivery on this subject.
Comment From: sjohnr
Thanks for opening an issue on this. The CSRF docs improvements are now backported to 6.0.