Summary

I want to disable the CSRF security by setting to falsethe property security.enable-csrf in a active applicaton .properties file.

Actual Behavior

Based on the official documentation by default this security is enabled. To disable it you must specify it in org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity) with

http.csrf().disable();

or its equivalent in xml configuration.

Expected Behavior

The variable security.enable-csrf is acknowledged as one of the common properties by Spring Boot, yet setting it to false doesn't solve anything.

Configuration

In my application.yml I have this section

---
spring:
  profiles: dev

security.enable-csrf: false

But setting the profile to dev won't disable the CRSF Security

Version

I am using spring-security-config-4.2.2.RELEASE

Possible solution

I solved this issue easily by specifying in my implementation of WebSecurityConfigurerAdapter the following code:

@Order(FRONTEND_SECURITY_ORDER)
@EnableAspectJAutoProxy
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    public static final int FRONTEND_SECURITY_ORDER
            = SecurityProperties.ACCESS_OVERRIDE_ORDER + 3;

    @Value("${security.enable-csrf}")
    private boolean csrfEnabled;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        if (!csrfEnabled) {
            http.csrf().disable();
        }

        http
                .httpBasic()
                //..... etc
    }
}

This will disable the csrf security if the property security.enable-csrf is set to false. An equivalent approach could be solved.

Comment From: mbhave

@EliuX what version of Spring Boot are you using? For 2.0, we have made several changes to how the security configuration can be customized by users. To turn off Spring Boot's default security configuration, you need to add your own WebSecurityConfigurerAdapter and disable csrf there.

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: shenxiusi

@mbhave

I use springboot v1.4.2.RELEASE and also met this problem. Set "security.enable-csrf: false" in applicaton .properties won't help.

After add my own WebSecurityConfigurerAdapter like @EliuX, I got exception org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter' available: expected single matching bean but found 2: webSecurityConfig,defaultWebSecurityConfigurer

Could you give a tip on that? Thanks for the help.

Comment From: wilkinsona

@shenxiusi If you have a question of your own, please ask on Stack Overflow.

Comment From: membersound

Same for me on spring-boot 1.5.9

Comment From: mbhave

I'm unable to reproduce this issue on 1.5.9. By default, csrf is disabled in SecurityProperties. To enable it, security.enable_csrf can be set to true.

Note that in 1.5.x, actuator endpoints had separate security configuration and the above flag will not affect CSRF for the actuators.

If the issue needs to be reopened, please provide a small sample that reproduces it.

Comment From: EliuX

Sorry for the late response. I am using Spring Boot 1.5.2.RELEASE. And @shenxiusi probably you have 2 beans that inherits from org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter, you should keep only one, thats it. Based on what @mbhave said, for versions like 1.5.9 this is fixed already. So csrf is disabled by default and activating it by the property security.enable_csrf is valid. So migrating to new versions will solve this issue.

Comment From: lanoxx

Just stumbled on this issue. I am confused about whether CSRF is disabled in 1.5.9 by default or not. The documentation for 1.5.9 explicitly mentions that it is enabled by default:

Common low-level features (HSTS, XSS, CSRF, caching) provided by Spring Security are on by default.

https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/

However further down we find:

security.enable-csrf=false # Enable Cross Site Request Forgery support.

Which seems to imply that the csrf setting is set to false by default.

According to @mbhave's comment it is disabled which also matches my experience? Please clarify in this issue and possibly update the documentation for 1.5.9?

Thank you.

Comment From: mbhave

This discrepancy doesn't exist in the latest 1.5.11 snapshot because the default for security.enable-csrf has been changed to true to match the Spring Security defaults.

Comment From: lanoxx

Thanks for clarifying. Is changing the default not considered a breaking change and is that no problem for a patch level release such as .11? When I stumbled across this issue it was because of failing tests when I switched from Spring Boot's autoconfiguration to a manually configured Spring Security Configuration. The Spring Boot had CSRF default to false, but Spring security was enabling it by default, so my tests initially failed until I added csrf().disabled() to the configuration.

If you are going forward with this change, please consider adding a big warning somewhere in the test, so that when people search for CSRF in the Spring Boot docu they can find that easily (there are only a couple of occurences in the documentation anyway).

Comment From: mbhave

It is a breaking change but it's done to tighten security. It makes sense for Boot to stick to Spring Security's defaults in this case and it's pretty easy to flip it back if people want that with a flag.

because of failing tests when I switched from Spring Boot's autoconfiguration to a manually configured Spring Security Configuration. The Spring Boot had CSRF default to false, but Spring security was enabling it by default

That shouldn't be the case with 1.5.11.BUILD-SNAPSHOTS because Spring Boot and Spring Security's defaults for CSRF are the same there.

For the documentation part of it, I've added a new issue here.

Comment From: emmysteven

.csrf.disable() not working spring boot 3.0.4

below is my security config

package meetona.infrastructure.config;

import lombok.extern.slf4j.Slf4j;
import meetona.infrastructure.security.AuthEntryPoint;
import meetona.infrastructure.security.AuthenticationManager;
import meetona.infrastructure.security.JwtAuthFilter;
import meetona.infrastructure.security.SecurityContextRepository;
import org.springframework.boot.autoconfigure.security.reactive.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.cors.reactive.CorsConfigurationSource;

@Slf4j
@EnableWebFluxSecurity
@Configuration
@EnableReactiveMethodSecurity
public class SecurityConfig {

    protected static final String[] ACTUATOR_WHITELIST = {
            "/actuator/**",
            "/health/**",
            "/health"
    };

    protected static final String[] SWAGGER_WHITELIST = {
            "/v3/api-docs/**",
            "/swagger-ui/**",
            "/swagger-ui.html",
    };

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(
            ServerHttpSecurity http,
            JwtAuthFilter jwtAuthFilter,
            AuthEntryPoint authEntryPoint,
            AuthenticationManager authenticationManager,
            SecurityContextRepository securityContextRepository,
            CorsConfigurationSource corsConfigurationSource
    ) {
        return http
                .exceptionHandling()
                .authenticationEntryPoint(authEntryPoint)
                .and().csrf().disable()
                .authenticationManager(authenticationManager)
                .securityContextRepository(securityContextRepository)
                .authorizeExchange(auth -> auth
                        .matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
                        .pathMatchers("/auth/**").permitAll()
                        .pathMatchers(SWAGGER_WHITELIST).permitAll()
                        .pathMatchers(ACTUATOR_WHITELIST).permitAll()
                        .anyExchange().authenticated()
                )
                .addFilterAt(jwtAuthFilter, SecurityWebFiltersOrder.AUTHENTICATION)
                .cors().configurationSource(corsConfigurationSource)
                .and()
                .build();
    }
}

Comment From: philwebb

@emmysteven Since this issue is quite old and already has a lot of comments, could you please open a new one. Please provide a sample application that we can run to diagnose the problem.