How to disable csrf in Spring using application.properties?
Asked Answered
L

6

34

The following property exists:

security.enable-csrf=false

BUT csrf protection is still on if I add the property to application.properties.

What works is to disable it programatically.

But I'd prefer properties configuration. Why could it not be working?

@Configuration
public class AuthConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.csrf().disable();

    }
}
Laing answered 29/6, 2017 at 11:51 Comment(9)
That will only work if Spring Boot is allowed to configure security, if you are messing around with Security yourself, that property won't do anything. Also make sure you are on a version of Spring Boot that supports that property.Tadio
I'm on newest -1.5.4 and I only added the configure() method to disable the csrf. If I remove that method completely, the property is still not taken into account. The only custom security config is with configure(AuthenticationManagerBuilder auth) that I use to set BCryptPasswordEncoder. But that should not impact the csrf.Laing
That depends, if you have @EnableWebMvc on it that will disable auto configuration.Tadio
@SpringBootApplication is my only annotation. And I'm extending WebSecurityConfigurerAdapter. Maybe that's the cause?Laing
Are you using Spring Boot? As that isn't really clear from your question...Tadio
Yes, added spring-boot to tags.Laing
Did you enable basic authentication (which is the default) or did you disable that... Also the default is to disable csrf protection so you must have some additional security configuration (properties or classes) that disables the default setup.Tadio
I have security.basic.enabled=true and using maven spring-boot-starter-security.Laing
Then I'm out of ideas. There is too little information too help you. imho you have something in the code that disables the default configuration (could be something you have or additional dependencies) however with the little information in the question that is hard to tell.Tadio
C
35

As the WebSecurityConfigurerAdapter uses an imperative approach you can inject the value of the security.enable-csrf variable and disable CSRF when it be false. You are right, I think this should work out of the box.

@Configuration
public class AuthConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

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

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       super.configure(http);

       if(!csrfEnabled)
       {
         http.csrf().disable();
       }
    }
}

What I did was to set that variable to false in my application.yml for when I had a dev spring profile active, although you could create a profile called nosecurity for such purposes too. It eases this process a lot:

--- application.yml ---

# Production configuration
server:
  port: ${server.web.port}
admin.email: ${admin.email}
#etc
---
spring:
  profiles: dev

security.enable-csrf: false

#other Development configurations

I hope it suits your needs

Update on Dec 17th of 2017

Based on a comment of a Spring Boot member this issue is fixed on new versions of Spring: I had it on version 1.5.2.RELEASE but it seems that in version 1.5.9.RELEASE (the latest stable one to the date before version 2) its already fixed and by default csrf is disabled and it can be enabled with security.enable_csrf: true. Therefore a possible solution could be just upgrading to version 1.5.9.RELEASE, before making a major one to version 2 where the architecture might be quite more different.

Update on Jun 02nd of 2023

The method http.csrf requires now a customizer of type Customizer<CsrfConfigurer<HttpSecurity>> to configure csrf. Therefore, instead of:

http.csrf().disable();

you should use

http.csrf(AbstractHttpConfigurer::disable);
Calculating answered 28/7, 2017 at 22:15 Comment(5)
Thanks, that's a great idea. Though it still not explains why the crsf configuration is not entirely disabled by just setting the configuration property.Laing
An issue should be raised in their Spring github and/or jiraCalculating
In the Spring Security documenation for CSRF it says that by default its on and to disable it you must do it by Java or xml code. The .properties attribute is something that should be implemented by Spring Boot: An issue opened in Spring BootCalculating
CSRF is enabled by default as of Spring Security 4.0. docs.spring.io/spring-security/site/docs/4.2.1.RELEASE/…Radiothorium
Suppose I kept it "disable" via external configuration & I am running my app. Now at some point of time I want to "enable" CSRF so I changed property to TRUE and hit the /refresh end point, but does that mean that Spring container will again call "configure" method of "AuthConfig" ? If not then I need to either re-stage my app or restart my app so new configuration is loaded by spring container.Salley
T
7

For Spring Boot 3.1.0 (spring-boot-starter-web) use the code snippet below

http.csrf(AbstractHttpConfigurer::disable);

For Spring Boot 3.1.0 (spring-boot-starter-webflux) use the code snippet below

http.csrf(ServerHttpSecurity.CsrfSpec::disable);
Truism answered 6/6, 2023 at 12:0 Comment(0)
N
6

An update:

Looks like there is an issue with disabling CSRF using application.properties on spring-boot 1.x (and thanks to Eliux for openning this case).

So my solution for spring-boot 1.5.7 with an embedded tomcat is disabling CSRF via SecurityConfig class (note that this way I keep the tomcat ootb basic authentication):

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Note: 
        // Use this to enable the tomcat basic authentication (tomcat popup rather than spring login page)
        // Note that the CSRf token is disabled for all requests (change it as you wish...)
        http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        // Add here any custom code you need in order to get the credentials from the user...  
        auth.inMemoryAuthentication()
            .withUser("myUserName")
            .password("myPassword")
            .roles("USER");
    }
} 
Norfolk answered 6/12, 2017 at 9:45 Comment(1)
It seems that for versions like 1.5.9 or superior this is fixed.Calculating
M
5

For Spring Boot 3. It helped me:

http.csrf(csrf -> csrf.disable());
Mcfadden answered 4/9, 2023 at 9:23 Comment(0)
M
2

I guess: spring-security 6.1.4

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // ...
            .csrf((csrf) -> csrf
                .ignoringRequestMatchers("/api/*")
            );
        return http.build();
    }
}

Or

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // ...
            .csrf((csrf) -> csrf.disable());
        return http.build();
    }
}

See: Disable CSRF Protection

Maible answered 16/10, 2023 at 13:52 Comment(0)
V
1

Was able to disable it with the following line in the spring-security.xml file:

<security:csrf disabled="true"/>

Villainage answered 7/5, 2022 at 14:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.