CSRF / XSRF protection using Spring Security

The last few years there is an almost constant stream of news articles about some company leaking customer information one way or the other. While not all of these leaks are caused by badly protected websites themselves, a lot are caused by misconfigurations in the web/data servers, programmers still have a hard time integrating some basic protection against attacks.
I won't pretend to have knowledge of every aspect of a vigorous web attack against a website (I need to point you to Erik Hooijmeijer for this), I do know that some of the basic protections are easy to implement due to support by the underlying framework.
The same goes for a Spring MVC webapplication. With the Spring-Security framework it becomes easier to protect your (web)application. One of the threats is CSRF short for Cross Site Request Forgery. CSRF or XSRF uses an already established session with a trusted website to create a 'forged' request and execute an unwanted command to that website. This can be mitigated by requiring a unique token to be send with the request which has been generated and stored in the httpsession.
Spring has the capability to auto generate and validate the token and fields in the MVC forms. Enabling this feature is as simple as adding a library in your project, and adding a bit of configuration in your pom.xml:

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.2.5.RELEASE</version>
</dependency>
Then add the following files to your projects pom file:
<SecurityWebApplicationInitializer.java>
  
/**
  * This WebApplicationInitializer register its security filters on the Application
  *
  * @Order(2)
  public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {}
  
  
/**
  * This WebApplicationInitializer register its security filters on the Application
  *
  * @Order(2)
  */
  public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {}
  
<SecurityConfig.java>
  
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
  * Because authentication is handled outside the application we don't have to authorize any requests

  */
  @Override
  @SuppressWarnings("PMD.SignatureDeclareThrowsException")
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/**").permitAll();
  }
}
  
Notice that in the above file we don't enable csrf protection explicitly as Spring enabled this by default.
You can only explicitly disable it by writing:
  
protected void configure(HttpSecurity http) throws Exception {
  http.authorizeRequests().antMatchers("/**").permitAll().and().csrf().disable();
}
  
Now in your JSP replace the default  <form> tag with the spring-form JSP tag library version and you get auto _csrf hidden input field injected into your forms.
There are 2 gotchas!
  1. When also configuring a CharacterEncodingFilter, to make sure you have UTF-8 support all the way through your webstack, you need to make sure that this filter is loaded before the filters that the SecurityWebApplicationInitializer adds to the mix. Because the CSRF filter reads the request parameters the character encoding is already set on the request causing the CharacterEncodingFilter to be pointless. So annotate your base WebApplicationInitializer with a @Order(1) and the SecurityWebApplicationInitializer with @Order(2). This way the CharacterEncodingFilter is loaded before the other filters.
    There is a second way. You can also override beforeSpringSecurityFilterChain and add the CharacterEncodingFilter in that method.
  2. The Security configuration stores the generated token in the HttpSession on the server (to verify against the returning token). So make sure that your loadbalancers are configured with a sticky-session configuration, otherwise the post to the server can be forwarded to the wrong webserver. As the user has no valid session on that server the validation of the CSRF token will fail.
Read more on Spring Security
And other possible attacks on your website: OWASP