[[servlet-csrf]]
= Cross Site Request Forgery (CSRF)
:figures: servlet/exploits
In an application where end users can xref:servlet/authentication/index.adoc[log in], it is important to consider how to protect against xref:features/exploits/csrf.adoc#csrf[Cross Site Request Forgery (CSRF)].
Spring Security protects against CSRF attacks by default for xref:features/exploits/csrf.adoc#csrf-protection-read-only[unsafe HTTP methods], such as a POST request, so no additional code is necessary.
You can specify the default configuration explicitly using the following:
[[csrf-configuration]]
.Configure CSRF Protection
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// ...
.csrf(Customizer.withDefaults());
return http.build();
}
}
----
Kotlin::
+
[source,kotlin,role="secondary"]
----
import org.springframework.security.config.annotation.web.invoke
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
csrf { }
}
return http.build()
}
}
----
XML::
+
[source,xml,role="secondary"]
----
----
======
To learn more about CSRF protection for your application, consider the following use cases:
* I want to <>
* I need to <>
* I want to <> instead of <>
* I want to <>
* I want to <>
* I want to <>
* I need guidance integrating <> with the backend
* I need guidance integrating <> with the backend
* I need guidance integrating <> with the backend
* I need guidance on <>
* I want to <>
* I need guidance on <>
[[csrf-components]]
== Understanding CSRF Protection's Components
CSRF protection is provided by several components that are composed within the {security-api-url}org/springframework/security/web/csrf/CsrfFilter.html[`CsrfFilter`]:
.`CsrfFilter` Components
image::{figures}/csrf.png[]
CSRF protection is divided into two parts:
1. Make the {security-api-url}org/springframework/security/web/csrf/CsrfToken.html[`CsrfToken`] available to the application by delegating to the <>.
2. Determine if the request requires CSRF protection, load and validate the token, and <>.
.`CsrfFilter` Processing
image::{figures}/csrf-processing.png[]
* image:{icondir}/number_1.png[] First, the {security-api-url}org/springframework/security/web/csrf/DeferredCsrfToken.html[`DeferredCsrfToken`] is loaded, which holds a reference to the <> so that the persisted `CsrfToken` can be loaded later (in image:{icondir}/number_4.png[]).
* image:{icondir}/number_2.png[] Second, a `Supplier` (created from `DeferredCsrfToken`) is given to the <>, which is responsible for populating a request attribute to make the `CsrfToken` available to the rest of the application.
* image:{icondir}/number_3.png[] Next, the main CSRF protection processing begins and checks if the current request requires CSRF protection. If not required, the filter chain is continued and processing ends.
* image:{icondir}/number_4.png[] If CSRF protection is required, the persisted `CsrfToken` is finally loaded from the `DeferredCsrfToken`.
* image:{icondir}/number_5.png[] Continuing, the actual CSRF token provided by the client (if any) is resolved using the <>.
* image:{icondir}/number_6.png[] The actual CSRF token is compared against the persisted `CsrfToken`. If valid, the filter chain is continued and processing ends.
* image:{icondir}/number_7.png[] If the actual CSRF token is invalid (or missing), an `AccessDeniedException` is passed to the <> and processing ends.
[[migrating-to-spring-security-6]]
== Migrating to Spring Security 6
When migrating from Spring Security 5 to 6, there are a few changes that may impact your application.
The following is an overview of the aspects of CSRF protection that have changed in Spring Security 6:
* Loading of the `CsrfToken` is now <> to improve performance by no longer requiring the session to be loaded on every request.
* The `CsrfToken` now includes <> to protect the CSRF token from a https://en.wikipedia.org/wiki/BREACH[BREACH] attack.
[TIP]
====
The changes in Spring Security 6 require additional configuration for single-page applications, and as such you may find the <> section particularly useful.
====
See the https://docs.spring.io/spring-security/reference/5.8/migration/servlet/exploits.html[Exploit Protection] section of the https://docs.spring.io/spring-security/reference/5.8/migration/index.html[Migration] chapter for more information on migrating a Spring Security 5 application.
[[csrf-token-repository]]
== Persisting the `CsrfToken`
The `CsrfToken` is persisted using a `CsrfTokenRepository`.
By default, the <> is used for storing tokens in a session.
Spring Security also provides the <> for storing tokens in a cookie.
You can also specify <> to store tokens wherever you like.
[[csrf-token-repository-httpsession]]
=== Using the `HttpSessionCsrfTokenRepository`
By default, Spring Security stores the expected CSRF token in the `HttpSession` by using {security-api-url}org/springframework/security/web/csrf/HttpSessionCsrfTokenRepository.html[`HttpSessionCsrfTokenRepository`], so no additional code is necessary.
The `HttpSessionCsrfTokenRepository` reads the token from an HTTP request header named `X-CSRF-TOKEN` or the request parameter `_csrf` by default.
You can specify the default configuration explicitly using the following configuration:
[[csrf-token-repository-httpsession-configuration]]
.Configure `HttpSessionCsrfTokenRepository`
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// ...
.csrf((csrf) -> csrf
.csrfTokenRepository(new HttpSessionCsrfTokenRepository())
);
return http.build();
}
}
----
Kotlin::
+
[source,kotlin,role="secondary"]
----
import org.springframework.security.config.annotation.web.invoke
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
csrf {
csrfTokenRepository = HttpSessionCsrfTokenRepository()
}
}
return http.build()
}
}
----
XML::
+
[source,xml,role="secondary"]
----
----
======
[[csrf-token-repository-cookie]]
=== Using the `CookieCsrfTokenRepository`
You can persist the `CsrfToken` in a cookie to <> using the {security-api-url}org/springframework/security/web/csrf/CookieCsrfTokenRepository.html[`CookieCsrfTokenRepository`].
The `CookieCsrfTokenRepository` writes to a cookie named `XSRF-TOKEN` and reads it from an HTTP request header named `X-XSRF-TOKEN` or the request parameter `_csrf` by default.
These defaults come from Angular and its predecessor https://docs.angularjs.org/api/ng/service/$http#cross-site-request-forgery-xsrf-protection[AngularJS].
[TIP]
====
See the https://angular.io/guide/http-security-xsrf-protection[Cross-Site Request Forgery (XSRF) protection] guide and the https://angular.io/api/common/http/HttpClientXsrfModule[HttpClientXsrfModule] for more recent information on this topic.
====
You can configure the `CookieCsrfTokenRepository` using the following configuration:
[[csrf-token-repository-cookie-configuration]]
.Configure `CookieCsrfTokenRepository`
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// ...
.csrf((csrf) -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
);
return http.build();
}
}
----
Kotlin::
+
[source,kotlin,role="secondary"]
----
import org.springframework.security.config.annotation.web.invoke
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
csrf {
csrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse()
}
}
return http.build()
}
}
----
XML::
+
[source,xml,role="secondary"]
----
----
======
[NOTE]
====
The example explicitly sets `HttpOnly` to `false`.
This is necessary to let JavaScript frameworks (such as Angular) read it.
If you do not need the ability to read the cookie with JavaScript directly, we _recommend_ omitting `HttpOnly` (by using `new CookieCsrfTokenRepository()` instead) to improve security.
====
[[csrf-token-repository-custom]]
=== Customizing the `CsrfTokenRepository`
There can be cases where you want to implement a custom {security-api-url}org/springframework/security/web/csrf/CsrfTokenRepository.html[`CsrfTokenRepository`].
Once you've implemented the `CsrfTokenRepository` interface, you can configure Spring Security to use it with the following configuration:
[[csrf-token-repository-custom-configuration]]
.Configure Custom `CsrfTokenRepository`
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// ...
.csrf((csrf) -> csrf
.csrfTokenRepository(new CustomCsrfTokenRepository())
);
return http.build();
}
}
----
Kotlin::
+
[source,kotlin,role="secondary"]
----
import org.springframework.security.config.annotation.web.invoke
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
csrf {
csrfTokenRepository = CustomCsrfTokenRepository()
}
}
return http.build()
}
}
----
XML::
+
[source,xml,role="secondary"]
----
----
======
[[csrf-token-request-handler]]
== Handling the `CsrfToken`
The `CsrfToken` is made available to an application using a `CsrfTokenRequestHandler`.
This component is also responsible for resolving the `CsrfToken` from HTTP headers or request parameters.
By default, the <> is used for providing https://en.wikipedia.org/wiki/BREACH[BREACH] protection of the `CsrfToken`.
Spring Security also provides the <> for opting out of BREACH protection.
You can also specify <> to customize the strategy for handling and resolving tokens.
[[csrf-token-request-handler-breach]]
=== Using the `XorCsrfTokenRequestAttributeHandler` (BREACH)
The `XorCsrfTokenRequestAttributeHandler` makes the `CsrfToken` available as an `HttpServletRequest` attribute called `_csrf`, and additionally provides protection for https://en.wikipedia.org/wiki/BREACH[BREACH].
[NOTE]
====
The `CsrfToken` is also made available as a request attribute using the name `CsrfToken.class.getName()`.
This name is not configurable, but the name `_csrf` can be changed using `XorCsrfTokenRequestAttributeHandler#setCsrfRequestAttributeName`.
====
This implementation also resolves the token value from the request as either a request header (one of <> or <> by default) or a request parameter (`_csrf` by default).
[NOTE]
====
BREACH protection is provided by encoding randomness into the CSRF token value to ensure the returned `CsrfToken` changes on every request.
When the token is later resolved as a header value or request parameter, it is decoded to obtain the raw token which is then compared to the <>.
====
Spring Security protects the CSRF token from a BREACH attack by default, so no additional code is necessary.
You can specify the default configuration explicitly using the following configuration:
[[csrf-token-request-handler-breach-configuration]]
.Configure BREACH protection
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// ...
.csrf((csrf) -> csrf
.csrfTokenRequestHandler(new XorCsrfTokenRequestAttributeHandler())
);
return http.build();
}
}
----
Kotlin::
+
[source,kotlin,role="secondary"]
----
import org.springframework.security.config.annotation.web.invoke
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
csrf {
csrfTokenRequestHandler = XorCsrfTokenRequestAttributeHandler()
}
}
return http.build()
}
}
----
XML::
+
[source,xml,role="secondary"]
----
----
======
[[csrf-token-request-handler-plain]]
=== Using the `CsrfTokenRequestAttributeHandler`
The `CsrfTokenRequestAttributeHandler` makes the `CsrfToken` available as an `HttpServletRequest` attribute called `_csrf`.
[NOTE]
====
The `CsrfToken` is also made available as a request attribute using the name `CsrfToken.class.getName()`.
This name is not configurable, but the name `_csrf` can be changed using `CsrfTokenRequestAttributeHandler#setCsrfRequestAttributeName`.
====
This implementation also resolves the token value from the request as either a request header (one of <> or <> by default) or a request parameter (`_csrf` by default).
[[csrf-token-request-handler-opt-out-of-breach]]
The primary use of `CsrfTokenRequestAttributeHandler` is to opt-out of BREACH protection of the `CsrfToken`, which can be configured using the following configuration:
.Opt-out of BREACH protection
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// ...
.csrf((csrf) -> csrf
.csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler())
);
return http.build();
}
}
----
Kotlin::
+
[source,kotlin,role="secondary"]
----
import org.springframework.security.config.annotation.web.invoke
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
csrf {
csrfTokenRequestHandler = CsrfTokenRequestAttributeHandler()
}
}
return http.build()
}
}
----
XML::
+
[source,xml,role="secondary"]
----
----
======
[[csrf-token-request-handler-custom]]
=== Customizing the `CsrfTokenRequestHandler`
You can implement the `CsrfTokenRequestHandler` interface to customize the strategy for handling and resolving tokens.
[TIP]
====
The `CsrfTokenRequestHandler` interface is a `@FunctionalInterface` that can be implemented using a lambda expression to customize request handling.
You will need to implement the full interface to customize how tokens are resolved from the request.
See <> for an example that uses delegation to implement a custom strategy for handling and resolving tokens.
====
Once you've implemented the `CsrfTokenRequestHandler` interface, you can configure Spring Security to use it with the following configuration:
[[csrf-token-request-handler-custom-configuration]]
.Configure Custom `CsrfTokenRequestHandler`
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// ...
.csrf((csrf) -> csrf
.csrfTokenRequestHandler(new CustomCsrfTokenRequestHandler())
);
return http.build();
}
}
----
Kotlin::
+
[source,kotlin,role="secondary"]
----
import org.springframework.security.config.annotation.web.invoke
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
csrf {
csrfTokenRequestHandler = CustomCsrfTokenRequestHandler()
}
}
return http.build()
}
}
----
XML::
+
[source,xml,role="secondary"]
----
----
======
[[deferred-csrf-token]]
== Deferred Loading of the `CsrfToken`
By default, Spring Security defers loading of the `CsrfToken` until it is needed.
[NOTE]
====
The `CsrfToken` is needed whenever a request is made with an xref:features/exploits/csrf.adoc#csrf-protection-read-only[unsafe HTTP method], such as a POST.
Additionally, it is needed by any request that renders the token to the response, such as a web page with a `