Add servlet opt out steps for CSRF BREACH

Issue gh-12107
This commit is contained in:
Steve Riesenberg 2022-11-19 22:08:19 -06:00
parent 2fe2f919b7
commit 4994e67eda
No known key found for this signature in database
GPG Key ID: 5F311AB48A55D521

View File

@ -11,6 +11,7 @@ In Spring Security 6, the default is that the lookup of the `CsrfToken` will be
To opt into the new Spring Security 6 default, the following configuration can be used.
[[servlet-opt-in-defer-loading-csrf-token]]
.Defer Loading `CsrfToken`
====
.Java
@ -166,3 +167,79 @@ open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
p:csrfRequestAttributeName="_csrf"/>
----
====
[[servlet-csrf-breach-opt-out]]
=== Opt-out Steps
If configuring CSRF BREACH protection gives you trouble, take a look at these scenarios for optimal opt out behavior:
==== I am using AngularJS or another Javascript framework
If you are using AngularJS and the https://angular.io/api/common/http/HttpClientXsrfModule[HttpClientXsrfModule] (or a similar module in another framework) along with `CookieCsrfTokenRepository.withHttpOnlyFalse()`, you may find that automatic support no longer works.
In this case, you can configure Spring Security to validate the raw `CsrfToken` from the cookie while keeping CSRF BREACH protection of the response using a custom `CsrfTokenRequestHandler` with delegation, like so:
.Configure `CsrfToken` BREACH Protection to validate raw tokens
====
.Java
[source,java,role="primary"]
----
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
CookieCsrfTokenRepository tokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
XorCsrfTokenRequestAttributeHandler delegate = new XorCsrfTokenRequestAttributeHandler();
// set the name of the attribute the CsrfToken will be populated on
delegate.setCsrfRequestAttributeName("_csrf");
// Use only the handle() method of XorCsrfTokenRequestAttributeHandler and the
// default implementation of resolveCsrfTokenValue() from CsrfTokenRequestHandler
CsrfTokenRequestHandler requestHandler = delegate::handle;
http
// ...
.csrf((csrf) -> csrf
.csrfTokenRepository(tokenRepository)
.csrfTokenRequestHandler(requestHandler)
);
return http.build();
}
----
.Kotlin
[source,kotlin,role="secondary"]
----
@Bean
open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
val tokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse()
val delegate = XorCsrfTokenRequestAttributeHandler()
// set the name of the attribute the CsrfToken will be populated on
delegate.setCsrfRequestAttributeName("_csrf")
// Use only the handle() method of XorCsrfTokenRequestAttributeHandler and the
// default implementation of resolveCsrfTokenValue() from CsrfTokenRequestHandler
val requestHandler = CsrfTokenRequestHandler(delegate::handle)
http {
csrf {
csrfTokenRepository = tokenRepository
csrfTokenRequestHandler = requestHandler
}
}
return http.build()
}
----
.XML
[source,xml,role="secondary"]
----
<http>
<!-- ... -->
<csrf token-repository-ref="tokenRepository"
request-handler-ref="requestHandler"/>
</http>
<b:bean id="tokenRepository"
class="org.springframework.security.web.csrf.CookieCsrfTokenRepository"
p:cookieHttpOnly="false"/>
----
====
==== I need to opt out of CSRF BREACH protection for another reason
If CSRF BREACH protection does not work for you for another reason, you can opt out using the configuration from the <<servlet-opt-in-defer-loading-csrf-token>> section.