mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-31 14:48:54 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			486 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			486 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| [[servlet-csrf]]
 | ||
| = Cross Site Request Forgery (CSRF) for Servlet Environments
 | ||
| 
 | ||
| This section discusses Spring Security's xref:features/exploits/csrf.adoc#csrf[Cross Site Request Forgery (CSRF)] support for servlet environments.
 | ||
| 
 | ||
| [[servlet-csrf-using]]
 | ||
| == Using Spring Security CSRF Protection
 | ||
| The steps to using Spring Security's CSRF protection are outlined below:
 | ||
| 
 | ||
| * <<servlet-csrf-idempotent,Use proper HTTP verbs>>
 | ||
| * <<servlet-csrf-configure,Configure CSRF Protection>>
 | ||
| * <<servlet-csrf-include,Include the CSRF Token>>
 | ||
| 
 | ||
| [[servlet-csrf-idempotent]]
 | ||
| === Use proper HTTP verbs
 | ||
| The first step to protecting against CSRF attacks is to ensure your website uses proper HTTP verbs.
 | ||
| This is covered in detail in xref:features/exploits/csrf.adoc#csrf-protection-idempotent[Safe Methods Must be Idempotent].
 | ||
| 
 | ||
| [[servlet-csrf-configure]]
 | ||
| === Configure CSRF Protection
 | ||
| The next step is to configure Spring Security's CSRF protection within your application.
 | ||
| Spring Security's CSRF protection is enabled by default, but you may need to customize the configuration.
 | ||
| Below are a few common customizations.
 | ||
| 
 | ||
| [[servlet-csrf-configure-custom-repository]]
 | ||
| ==== Custom CsrfTokenRepository
 | ||
| 
 | ||
| By default Spring Security stores the expected CSRF token in the `HttpSession` using `HttpSessionCsrfTokenRepository`.
 | ||
| There can be cases where users will want to configure a custom `CsrfTokenRepository`.
 | ||
| For example, it might be desirable to persist the `CsrfToken` in a cookie to <<servlet-csrf-include-ajax-auto,support a JavaScript based application>>.
 | ||
| 
 | ||
| By default the `CookieCsrfTokenRepository` will write to a cookie named `XSRF-TOKEN` and read it from a header named `X-XSRF-TOKEN` or the HTTP parameter `_csrf`.
 | ||
| These defaults come from https://docs.angularjs.org/api/ng/service/$http#cross-site-request-forgery-xsrf-protection[AngularJS]
 | ||
| 
 | ||
| You can configure `CookieCsrfTokenRepository` in XML using the following:
 | ||
| 
 | ||
| 
 | ||
| .Store CSRF Token in a Cookie with XML Configuration
 | ||
| ====
 | ||
| [source,xml]
 | ||
| ----
 | ||
| <http>
 | ||
| 	<!-- ... -->
 | ||
| 	<csrf token-repository-ref="tokenRepository"/>
 | ||
| </http>
 | ||
| <b:bean id="tokenRepository"
 | ||
| 	class="org.springframework.security.web.csrf.CookieCsrfTokenRepository"
 | ||
| 	p:cookieHttpOnly="false"/>
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| [NOTE]
 | ||
| ====
 | ||
| The sample explicitly sets `cookieHttpOnly=false`.
 | ||
| This is necessary to allow JavaScript (i.e. AngularJS) to read it.
 | ||
| If you do not need the ability to read the cookie with JavaScript directly, it is recommended to omit `cookieHttpOnly=false` to improve security.
 | ||
| ====
 | ||
| 
 | ||
| 
 | ||
| You can configure `CookieCsrfTokenRepository` in Java Configuration using:
 | ||
| 
 | ||
| .Store CSRF Token in a Cookie
 | ||
| ====
 | ||
| .Java
 | ||
| [source,java,role="primary"]
 | ||
| ----
 | ||
| @EnableWebSecurity
 | ||
| public class WebSecurityConfig {
 | ||
| 
 | ||
| 	@Bean
 | ||
| 	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 | ||
| 		http
 | ||
| 			.csrf(csrf -> csrf
 | ||
| 				.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
 | ||
| 			);
 | ||
| 		return http.build();
 | ||
| 	}
 | ||
| }
 | ||
| ----
 | ||
| 
 | ||
| .Kotlin
 | ||
| [source,kotlin,role="secondary"]
 | ||
| ----
 | ||
| @EnableWebSecurity
 | ||
| class SecurityConfig {
 | ||
| 
 | ||
|     @Bean
 | ||
|     open fun filterChain(http: HttpSecurity): SecurityFilterChain {
 | ||
|        http {
 | ||
|             csrf {
 | ||
|                 csrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse()
 | ||
|             }
 | ||
|         }
 | ||
|         return http.build()
 | ||
|     }
 | ||
| }
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| [NOTE]
 | ||
| ====
 | ||
| The sample explicitly sets `cookieHttpOnly=false`.
 | ||
| This is necessary to allow JavaScript (i.e. AngularJS) to read it.
 | ||
| If you do not need the ability to read the cookie with JavaScript directly, it is recommended to omit `cookieHttpOnly=false` (by using `new CookieCsrfTokenRepository()` instead) to improve security.
 | ||
| ====
 | ||
| 
 | ||
| [[servlet-csrf-configure-disable]]
 | ||
| ==== Disable CSRF Protection
 | ||
| CSRF protection is enabled by default.
 | ||
| However, it is simple to disable CSRF protection if it xref:features/exploits/csrf.adoc#csrf-when[makes sense for your application].
 | ||
| 
 | ||
| The XML configuration below will disable CSRF protection.
 | ||
| 
 | ||
| 
 | ||
| .Disable CSRF XML Configuration
 | ||
| ====
 | ||
| [source,xml]
 | ||
| ----
 | ||
| <http>
 | ||
| 	<!-- ... -->
 | ||
| 	<csrf disabled="true"/>
 | ||
| </http>
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| The Java configuration below will disable CSRF protection.
 | ||
| 
 | ||
| .Disable CSRF
 | ||
| ====
 | ||
| .Java
 | ||
| [source,java,role="primary"]
 | ||
| ----
 | ||
| @Configuration
 | ||
| @EnableWebSecurity
 | ||
| public class WebSecurityConfig {
 | ||
| 
 | ||
| 	@Bean
 | ||
| 	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 | ||
| 		http
 | ||
| 			.csrf(csrf -> csrf.disable());
 | ||
| 		return http.build();
 | ||
| 	}
 | ||
| }
 | ||
| ----
 | ||
| 
 | ||
| .Kotlin
 | ||
| [source,kotlin,role="secondary"]
 | ||
| ----
 | ||
| @Configuration
 | ||
| @EnableWebSecurity
 | ||
| class SecurityConfig {
 | ||
| 
 | ||
|     @Bean
 | ||
|     open fun filterChain(http: HttpSecurity): SecurityFilterChain {
 | ||
|        http {
 | ||
|             csrf {
 | ||
|                 disable()
 | ||
|             }
 | ||
|         }
 | ||
|         return http.build()
 | ||
|     }
 | ||
| }
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| [[servlet-csrf-include]]
 | ||
| === Include the CSRF Token
 | ||
| 
 | ||
| In order for the xref:features/exploits/csrf.adoc#csrf-protection-stp[synchronizer token pattern] to protect against CSRF attacks, we must include the actual CSRF token in the HTTP request.
 | ||
| This must be included in a part of the request (i.e. form parameter, HTTP header, etc) that is not automatically included in the HTTP request by the browser.
 | ||
| 
 | ||
| Spring Security's https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/csrf/CsrfFilter.html[CsrfFilter] exposes a https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/csrf/CsrfToken.html[CsrfToken] as an `HttpServletRequest` attribute named `_csrf`.
 | ||
| This means that any view technology can access the `CsrfToken` to expose the expected token as either a <<servlet-csrf-include-form-attr,form>> or <<servlet-csrf-include-ajax-meta-attr,meta tag>>.
 | ||
| Fortunately, there are integrations listed below that make including the token in <<servlet-csrf-include-form,form>> and <<servlet-csrf-include-ajax,ajax>> requests even easier.
 | ||
| 
 | ||
| [[servlet-csrf-include-form]]
 | ||
| ==== Form URL Encoded
 | ||
| In order to post an HTML form the CSRF token must be included in the form as a hidden input.
 | ||
| For example, the rendered HTML might look like:
 | ||
| 
 | ||
| .CSRF Token HTML
 | ||
| ====
 | ||
| [source,html]
 | ||
| ----
 | ||
| <input type="hidden"
 | ||
| 	name="_csrf"
 | ||
| 	value="4bfd1575-3ad1-4d21-96c7-4ef2d9f86721"/>
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| Next we will discuss various ways of including the CSRF token in a form as a hidden input.
 | ||
| 
 | ||
| [[servlet-csrf-include-form-auto]]
 | ||
| ===== Automatic CSRF Token Inclusion
 | ||
| 
 | ||
| Spring Security's CSRF support provides integration with Spring's https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/support/RequestDataValueProcessor.html[RequestDataValueProcessor] via its https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/servlet/support/csrf/CsrfRequestDataValueProcessor.html[CsrfRequestDataValueProcessor].
 | ||
| This means that if you leverage https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-view-jsp-formtaglib[Spring’s form tag library], https://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#integration-with-requestdatavalueprocessor[Thymeleaf], or any other view technology that integrates with `RequestDataValueProcessor`, then forms that have an unsafe HTTP method (i.e. post) will automatically include the actual CSRF token.
 | ||
| 
 | ||
| [[servlet-csrf-include-form-tag]]
 | ||
| ===== csrfInput Tag
 | ||
| 
 | ||
| If you are using JSPs, then you can use https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-view-jsp-formtaglib[Spring’s form tag library].
 | ||
| However, if that is not an option, you can also easily include the token with the xref:servlet/integrations/jsp-taglibs.adoc#taglibs-csrfinput[csrfInput] tag.
 | ||
| 
 | ||
| [[servlet-csrf-include-form-attr]]
 | ||
| ===== CsrfToken Request Attribute
 | ||
| 
 | ||
| If the <<servlet-csrf-include,other options>> for including the actual CSRF token in the request do not work, you can take advantage of the fact that the `CsrfToken` <<servlet-csrf-include,is exposed>> as an `HttpServletRequest` attribute named `_csrf`.
 | ||
| 
 | ||
| An example of doing this with a JSP is shown below:
 | ||
| 
 | ||
| .CSRF Token in Form with Request Attribute
 | ||
| ====
 | ||
| [source,xml]
 | ||
| ----
 | ||
| <c:url var="logoutUrl" value="/logout"/>
 | ||
| <form action="${logoutUrl}"
 | ||
| 	method="post">
 | ||
| <input type="submit"
 | ||
| 	value="Log out" />
 | ||
| <input type="hidden"
 | ||
| 	name="${_csrf.parameterName}"
 | ||
| 	value="${_csrf.token}"/>
 | ||
| </form>
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| [[servlet-csrf-include-ajax]]
 | ||
| ==== Ajax and JSON Requests
 | ||
| If you are using JSON, then it is not possible to submit the CSRF token within an HTTP parameter.
 | ||
| Instead you can submit the token within a HTTP header.
 | ||
| 
 | ||
| In the following sections we will discuss various ways of including the CSRF token as an HTTP request header in JavaScript based applications.
 | ||
| 
 | ||
| [[servlet-csrf-include-ajax-auto]]
 | ||
| ===== Automatic Inclusion
 | ||
| 
 | ||
| Spring Security can easily be <<servlet-csrf-configure-custom-repository,configured>> to store the expected CSRF token in a cookie.
 | ||
| By storing the expected CSRF in a cookie, JavaScript frameworks like https://docs.angularjs.org/api/ng/service/$http#cross-site-request-forgery-xsrf-protection[AngularJS] will automatically include the actual CSRF token in the HTTP request headers.
 | ||
| 
 | ||
| [[servlet-csrf-include-ajax-meta]]
 | ||
| ===== Meta tags
 | ||
| 
 | ||
| An alternative pattern to <<servlet-csrf-include-form-auto,exposing the CSRF in a cookie>> is to include the CSRF token within your `meta` tags.
 | ||
| The HTML might look something like this:
 | ||
| 
 | ||
| .CSRF meta tag HTML
 | ||
| ====
 | ||
| [source,html]
 | ||
| ----
 | ||
| <html>
 | ||
| <head>
 | ||
| 	<meta name="_csrf" content="4bfd1575-3ad1-4d21-96c7-4ef2d9f86721"/>
 | ||
| 	<meta name="_csrf_header" content="X-CSRF-TOKEN"/>
 | ||
| 	<!-- ... -->
 | ||
| </head>
 | ||
| <!-- ... -->
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| Once the meta tags contained the CSRF token, the JavaScript code would read the meta tags and include the CSRF token as a header.
 | ||
| If you were using jQuery, this could be done with the following:
 | ||
| 
 | ||
| .AJAX send CSRF Token
 | ||
| ====
 | ||
| [source,javascript]
 | ||
| ----
 | ||
| $(function () {
 | ||
| 	var token = $("meta[name='_csrf']").attr("content");
 | ||
| 	var header = $("meta[name='_csrf_header']").attr("content");
 | ||
| 	$(document).ajaxSend(function(e, xhr, options) {
 | ||
| 		xhr.setRequestHeader(header, token);
 | ||
| 	});
 | ||
| });
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| [[servlet-csrf-include-ajax-meta-tag]]
 | ||
| ====== csrfMeta tag
 | ||
| 
 | ||
| If you are using JSPs a simple way to write the CSRF token to the `meta` tags is by leveraging the xref:servlet/integrations/jsp-taglibs.adoc#taglibs-csrfmeta[csrfMeta] tag.
 | ||
| 
 | ||
| [[servlet-csrf-include-ajax-meta-attr]]
 | ||
| ====== CsrfToken Request Attribute
 | ||
| 
 | ||
| If the <<servlet-csrf-include,other options>> for including the actual CSRF token in the request do not work, you can take advantage of the fact that the `CsrfToken` <<servlet-csrf-include,is exposed>> as an `HttpServletRequest` attribute named `_csrf`.
 | ||
| An example of doing this with a JSP is shown below:
 | ||
| 
 | ||
| .CSRF meta tag JSP
 | ||
| ====
 | ||
| [source,html]
 | ||
| ----
 | ||
| <html>
 | ||
| <head>
 | ||
| 	<meta name="_csrf" content="${_csrf.token}"/>
 | ||
| 	<!-- default header name is X-CSRF-TOKEN -->
 | ||
| 	<meta name="_csrf_header" content="${_csrf.headerName}"/>
 | ||
| 	<!-- ... -->
 | ||
| </head>
 | ||
| <!-- ... -->
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| [[servlet-csrf-considerations]]
 | ||
| == CSRF Considerations
 | ||
| There are a few special considerations to consider when implementing protection against CSRF attacks.
 | ||
| This section discusses those considerations as it pertains to servlet environments.
 | ||
| Refer to xref:features/exploits/csrf.adoc#csrf-considerations[CSRF Considerations] for a more general discussion.
 | ||
| 
 | ||
| 
 | ||
| [[servlet-considerations-csrf-login]]
 | ||
| === Logging In
 | ||
| 
 | ||
| It is important to xref:features/exploits/csrf.adoc#csrf-considerations-login[require CSRF for log in] requests to protect against forging log in attempts.
 | ||
| Spring Security's servlet support does this out of the box.
 | ||
| 
 | ||
| [[servlet-considerations-csrf-logout]]
 | ||
| === Logging Out
 | ||
| 
 | ||
| It is important to xref:features/exploits/csrf.adoc#csrf-considerations-logout[require CSRF for log out] requests to protect against forging log out attempts.
 | ||
| If CSRF protection is enabled (default), Spring Security's `LogoutFilter` to only process HTTP POST.
 | ||
| This ensures that log out requires a CSRF token and that a malicious user cannot forcibly log out your users.
 | ||
| 
 | ||
| The easiest approach is to use a form to log out.
 | ||
| If you really want a link, you can use JavaScript to have the link perform a POST (i.e. maybe on a hidden form).
 | ||
| For browsers with JavaScript that is disabled, you can optionally have the link take the user to a log out confirmation page that will perform the POST.
 | ||
| 
 | ||
| If you really want to use HTTP GET with logout you can do so, but remember this is generally not recommended.
 | ||
| For example, the following Java Configuration will perform logout with the URL `/logout` is requested with any HTTP method:
 | ||
| 
 | ||
| .Log out with HTTP GET
 | ||
| ====
 | ||
| .Java
 | ||
| [source,java,role="primary"]
 | ||
| ----
 | ||
| @EnableWebSecurity
 | ||
| public class WebSecurityConfig {
 | ||
| 
 | ||
| 	@Bean
 | ||
| 	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 | ||
| 		http
 | ||
| 			.logout(logout -> logout
 | ||
| 				.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
 | ||
| 			);
 | ||
| 		return http.build();
 | ||
| 	}
 | ||
| }
 | ||
| ----
 | ||
| 
 | ||
| .Kotlin
 | ||
| [source,kotlin,role="secondary"]
 | ||
| ----
 | ||
| @EnableWebSecurity
 | ||
| class SecurityConfig {
 | ||
| 
 | ||
|     @Bean
 | ||
|     open fun filterChain(http: HttpSecurity): SecurityFilterChain {
 | ||
|        http {
 | ||
|             logout {
 | ||
|                 logoutRequestMatcher = AntPathRequestMatcher("/logout")
 | ||
|             }
 | ||
|         }
 | ||
|         return http.build()
 | ||
|     }
 | ||
| }
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| 
 | ||
| [[servlet-considerations-csrf-timeouts]]
 | ||
| === CSRF and Session Timeouts
 | ||
| 
 | ||
| By default Spring Security stores the CSRF token in the `HttpSession`.
 | ||
| This can lead to a situation where the session expires which means there is not an expected CSRF token to validate against.
 | ||
| 
 | ||
| We've already discussed xref:features/exploits/csrf.adoc#csrf-considerations-login[general solutions] to session timeouts.
 | ||
| This section discusses the specifics of CSRF timeouts as it pertains to the servlet support.
 | ||
| 
 | ||
| It is simple to change storage of the expected CSRF token to be in a cookie.
 | ||
| For details, refer to the <<servlet-csrf-configure-custom-repository>> section.
 | ||
| 
 | ||
| If a token does expire, you might want to customize how it is handled by specifying a custom `AccessDeniedHandler`.
 | ||
| The custom `AccessDeniedHandler` can process the `InvalidCsrfTokenException` any way you like.
 | ||
| For an example of how to customize the `AccessDeniedHandler` refer to the provided links for both xref:servlet/appendix/namespace/http.adoc#nsa-access-denied-handler[xml] and {gh-url}/config/src/test/java/org/springframework/security/config/annotation/web/configurers/NamespaceHttpServerAccessDeniedHandlerTests.java#L64[Java configuration].
 | ||
| // FIXME: We should add a custom AccessDeniedHandler section in the reference and update the links above
 | ||
| 
 | ||
| 
 | ||
| [[servlet-csrf-considerations-multipart]]
 | ||
| === Multipart (file upload)
 | ||
| We have xref:features/exploits/csrf.adoc#csrf-considerations-multipart[already discussed] how protecting multipart requests (file uploads) from CSRF attacks causes a https://en.wikipedia.org/wiki/Chicken_or_the_egg[chicken and the egg] problem.
 | ||
| This section discusses how to implement placing the CSRF token in the <<servlet-csrf-considerations-multipart-body,body>> and <<servlet-csrf-considerations-multipart-url,url>> within a servlet application.
 | ||
| 
 | ||
| [NOTE]
 | ||
| ====
 | ||
| More information about using multipart forms with Spring can be found within the https://docs.spring.io/spring/docs/5.2.x/spring-framework-reference/web.html#mvc-multipart[1.1.11. Multipart Resolver] section of the Spring reference and the https://docs.spring.io/spring/docs/5.2.x/javadoc-api/org/springframework/web/multipart/support/MultipartFilter.html[MultipartFilter javadoc].
 | ||
| ====
 | ||
| 
 | ||
| [[servlet-csrf-considerations-multipart-body]]
 | ||
| ==== Place CSRF Token in the Body
 | ||
| 
 | ||
| We have xref:features/exploits/csrf.adoc#csrf-considerations-multipart-body[already discussed] the tradeoffs of placing the CSRF token in the body.
 | ||
| In this section we will discuss how to configure Spring Security to read the CSRF from the body.
 | ||
| 
 | ||
| In order to read the CSRF token from the body, the `MultipartFilter` is specified before the Spring Security filter.
 | ||
| Specifying the `MultipartFilter` before the Spring Security filter means that there is no authorization for invoking the `MultipartFilter` which means anyone can place temporary files on your server.
 | ||
| However, only authorized users will be able to submit a File that is processed by your application.
 | ||
| In general, this is the recommended approach because the temporary file upload should have a negligible impact on most servers.
 | ||
| 
 | ||
| // FIXME: Document Spring Boot
 | ||
| 
 | ||
| To ensure `MultipartFilter` is specified before the Spring Security filter with java configuration, users can override beforeSpringSecurityFilterChain as shown below:
 | ||
| 
 | ||
| .Initializer MultipartFilter
 | ||
| ====
 | ||
| .Java
 | ||
| [source,java,role="primary"]
 | ||
| ----
 | ||
| public class SecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
 | ||
| 
 | ||
| 	@Override
 | ||
| 	protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
 | ||
| 		insertFilters(servletContext, new MultipartFilter());
 | ||
| 	}
 | ||
| }
 | ||
| ----
 | ||
| 
 | ||
| .Kotlin
 | ||
| [source,kotlin,role="secondary"]
 | ||
| ----
 | ||
| class SecurityApplicationInitializer : AbstractSecurityWebApplicationInitializer() {
 | ||
|     override fun beforeSpringSecurityFilterChain(servletContext: ServletContext?) {
 | ||
|         insertFilters(servletContext, MultipartFilter())
 | ||
|     }
 | ||
| }
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| To ensure `MultipartFilter` is specified before the Spring Security filter with XML configuration, users can ensure the <filter-mapping> element of the `MultipartFilter` is placed before the springSecurityFilterChain within the web.xml as shown below:
 | ||
| 
 | ||
| .web.xml - MultipartFilter
 | ||
| ====
 | ||
| [source,xml]
 | ||
| ----
 | ||
| <filter>
 | ||
| 	<filter-name>MultipartFilter</filter-name>
 | ||
| 	<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
 | ||
| </filter>
 | ||
| <filter>
 | ||
| 	<filter-name>springSecurityFilterChain</filter-name>
 | ||
| 	<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 | ||
| </filter>
 | ||
| <filter-mapping>
 | ||
| 	<filter-name>MultipartFilter</filter-name>
 | ||
| 	<url-pattern>/*</url-pattern>
 | ||
| </filter-mapping>
 | ||
| <filter-mapping>
 | ||
| 	<filter-name>springSecurityFilterChain</filter-name>
 | ||
| 	<url-pattern>/*</url-pattern>
 | ||
| </filter-mapping>
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| [[servlet-csrf-considerations-multipart-url]]
 | ||
| ==== Include CSRF Token in URL
 | ||
| 
 | ||
| If allowing unauthorized users to upload temporary files is not acceptable, an alternative is to place the `MultipartFilter` after the Spring Security filter and include the CSRF as a query parameter in the action attribute of the form.
 | ||
| Since the `CsrfToken` is exposed as an `HttpServletRequest` <<servlet-csrf-include,request attribute>>, we can use that to create an `action` with the CSRF token in it.
 | ||
| An example with a jsp is shown below
 | ||
| 
 | ||
| .CSRF Token in Action
 | ||
| ====
 | ||
| [source,html]
 | ||
| ----
 | ||
| <form method="post"
 | ||
| 	action="./upload?${_csrf.parameterName}=${_csrf.token}"
 | ||
| 	enctype="multipart/form-data">
 | ||
| ----
 | ||
| ====
 | ||
| 
 | ||
| [[servlet-csrf-considerations-override-method]]
 | ||
| === HiddenHttpMethodFilter
 | ||
| We have xref:features/exploits/csrf.adoc#csrf-considerations-multipart-body[already discussed] the trade-offs of placing the CSRF token in the body.
 | ||
| 
 | ||
| In Spring's Servlet support, overriding the HTTP method is done using https://docs.spring.io/spring-framework/docs/5.2.x/javadoc-api/org/springframework/web/filter/reactive/HiddenHttpMethodFilter.html[HiddenHttpMethodFilter].
 | ||
| More information can be found in https://docs.spring.io/spring/docs/5.2.x/spring-framework-reference/web.html#mvc-rest-method-conversion[HTTP Method Conversion] section of the reference documentation.
 |