= Exploit Protection Migrations

The following steps relate to changes around how to configure CSRF.

== Defer Loading CsrfToken

In Spring Security 5, the default behavior is that the `CsrfToken` will be loaded on every request.
This means that in a typical setup, the `HttpSession` must be read for every request even if it is unnecessary.

In Spring Security 6, the default is that the lookup of the `CsrfToken` will be deferred until it is needed.

To opt into the new Spring Security 6 default, the following configuration can be used.

.Defer Loading `CsrfToken`
====
.Java
[source,java,role="primary"]
----
@Bean
DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
	CsrfTokenRequestAttributeHandler requestHandler = new CsrfTokenRequestAttributeHandler();
	// set the name of the attribute the CsrfToken will be populated on
	requestHandler.setCsrfRequestAttributeName("_csrf");
	http
		// ...
		.csrf((csrf) -> csrf
			.csrfTokenRequestHandler(requestHandler)
		);
	return http.build();
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
@Bean
open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
	val requestHandler = CsrfTokenRequestAttributeHandler()
	// set the name of the attribute the CsrfToken will be populated on
	requestHandler.setCsrfRequestAttributeName("_csrf")
	http {
		csrf {
			csrfTokenRequestHandler = requestHandler
		}
	}
	return http.build()
}
----

.XML
[source,xml,role="secondary"]
----
<http>
	<!-- ... -->
	<csrf request-handler-ref="requestHandler"/>
</http>
<b:bean id="requestHandler"
	class="org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler"
	p:csrfRequestAttributeName="_csrf"/>
----
====

If this breaks your application, then you can explicitly opt into the 5.8 defaults using the following configuration:

.Explicit Configure `CsrfToken` with 5.8 Defaults
====
.Java
[source,java,role="primary"]
----
@Bean
DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
	CsrfTokenRequestAttributeHandler requestHandler = new CsrfTokenRequestAttributeHandler();
	// set the name of the attribute the CsrfToken will be populated on
	requestHandler.setCsrfRequestAttributeName(null);
	http
		// ...
		.csrf((csrf) -> csrf
			.csrfTokenRequestHandler(requestHandler)
		);
	return http.build();
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
@Bean
open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
	val requestHandler = CsrfTokenRequestAttributeHandler()
	// set the name of the attribute the CsrfToken will be populated on
	requestHandler.setCsrfRequestAttributeName(null)
	http {
		csrf {
			csrfTokenRequestHandler = requestHandler
		}
	}
	return http.build()
}
----

.XML
[source,xml,role="secondary"]
----
<http>
	<!-- ... -->
	<csrf request-handler-ref="requestHandler"/>
</http>
<b:bean id="requestHandler"
	class="org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler">
	<b:property name="csrfRequestAttributeName">
		<b:null/>
	</b:property>
</b:bean>
----
====

== CSRF BREACH Protection

If the steps for <<Defer Loading CsrfToken>> work for you, then you can also opt into Spring Security 6's default support for BREACH protection of the `CsrfToken` using the following configuration:

.`CsrfToken` BREACH Protection
====
.Java
[source,java,role="primary"]
----
@Bean
DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
	XorCsrfTokenRequestAttributeHandler requestHandler = new XorCsrfTokenRequestAttributeHandler();
	// set the name of the attribute the CsrfToken will be populated on
	requestHandler.setCsrfRequestAttributeName("_csrf");
	http
		// ...
		.csrf((csrf) -> csrf
			.csrfTokenRequestHandler(requestHandler)
		);
	return http.build();
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
@Bean
open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
	val requestHandler = XorCsrfTokenRequestAttributeHandler()
	// set the name of the attribute the CsrfToken will be populated on
	requestHandler.setCsrfRequestAttributeName("_csrf")
	http {
		csrf {
			csrfTokenRequestHandler = requestHandler
		}
	}
	return http.build()
}
----

.XML
[source,xml,role="secondary"]
----
<http>
	<!-- ... -->
	<csrf request-handler-ref="requestHandler"/>
</http>
<b:bean id="requestHandler"
	class="org.springframework.security.web.csrf.XorCsrfTokenRequestAttributeHandler"
	p:csrfRequestAttributeName="_csrf"/>
----
====
