In this post, we will see what is CSRF – Cross-Site Request Forgery attack, How to enable and disable CSRF in spring Boot Security. Cross-Site Request Forgery attack is an attack executes unwanted calls on a web application without intervention of the end user.The end user is forced to execute these calls that corrupt the users data in the database or show unwanted information in the browser.
What is CSRF attack?
CSRF – Cross-Site Request Forgery attack is an attack that forces the end user to make an unwanted calls to the web application servers where the end user is already authenticated. When a user is authenticated with a website, the session information is created and stored in both server and browser. If any call is made in the browser to the website, all calls will be executed without any validation. This is called CSRF attack.
What is CSRF Token?
A CSRF token is a unique, secret, unpredictable value created by the server-side application and transmitted to the client for subsequent HTTP request made by the client application. The server-side application validates the CSRF token in the subsequence request, and rejects the request if the token is missing or invalid.
CSRF tokens are strong and unpredictable, generated as session tokens with the some properties, the attacker can not determine or predict the value
Steps to enable CSRF in Spring Boot Security
There are three steps to enable CSRF in spring boot security application. Spring boot security module enables CSRF by default. The following steps are recommended to enable CSRF in Spring Boot Security
1. Add Spring Security taglibs
In the spring boot application, add spring boot security and spring boot security tag library dependency in the pom.xml file. These dependency adds the spring boot security module and spring boot security tag libraries.
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
</dependency>
2. Add CSRF token in Jsp / template files
The CSRF token must be included in all the post forms in the jsp or template files. If it is a json calls, add the token in the header. The following example shows how to add CSRF toke in jsp file
login.jsp
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> <center> <h1>Welcome to Spring Boot Security</h1> <h2>Login Page</h2> <form method="POST" action="/login"> User Name : <input type="text" name="username" value="user"/><br><br> Password : <input type="password" name="password" value="password"/><br><br> <sec:csrfInput /> <input type="submit" name="submit"/> </form> </center>
The output html looks like as below.
<form method="POST" action="/login">
............
<input type="hidden" name="_csrf" value="d919ab77-0668-4a7b-a7ca-2de42c94a8de"/>
............
</form>
The CSRF token can be added directly using input tag as shown below.
login.jsp
<center> <h1>Welcome to Spring Boot Security</h1> <h2>Login Page</h2> <form method="POST" action="/login"> User Name : <input type="text" name="username" value="user"/><br><br> Password : <input type="password" name="password" value="password"/><br><br> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> <input type="submit" name="submit"/> </form> </center>
3. Remove the CSRF disable code
If any csrf disable code added in the spring boot security configuration, remove all the csrf disable code. The example below shows the commented csrf disable code.
package com.yawintutor; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration public class SpringBootSecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user").password("{noop}password").roles("USER"); }@Override public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**").hasAnyRole("USER")
.and()
.formLogin().loginPage("/login").permitAll();
//http.csrf().disable();
}
}
Steps to disable CSRF in Spring Boot Security
There are two ways to disable CSRF in the spring boot security application. The reason to disable CSRF is that the spring boot application is open to the public or it is cumbersome when you are in under development or testing phase.
1. Disable using security configuration code
The spring boot security application allows to configure the security details in a customized class that extends WebSecurityConfigurerAdapter class. The CSRF feature can be disabled using the code “http.csrf().disable
()”.
package com.yawintutor;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class SpringBootSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER");
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**").hasAnyRole("USER")
.and()
.formLogin().loginPage("/login").permitAll();
http.csrf().disable();
}
}
2. Disable using application.properties file
There is no direct way to disable the csrf feature by configuring in application.properties. There are work around to configure in application.properties file. The example below shows how to configure using application.properties file.
application.properties
security.enable.csrf=false
SpringBootSecurityConfiguration.java
package com.yawintutor;
@Configuration
public class SpringBootSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Value("${security.enable-csrf}")
private boolean csrfEnabled;
................
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**").hasAnyRole("USER")
.and()
.formLogin().loginPage("/login").permitAll();
if(csrfEnabled){
http.csrf().disable();
}
}
}