浏览代码

SEC-2543: Logout with CSRF enabled requires POST by default

Rob Winch 11 年之前
父节点
当前提交
f73b579ad9

+ 3 - 1
config/src/main/java/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.java

@@ -294,7 +294,9 @@ public final class LogoutConfigurer<H extends HttpSecurityBuilder<H>> extends Ab
         }
         if(http.getConfigurer(CsrfConfigurer.class) != null) {
             this.logoutRequestMatcher = new AntPathRequestMatcher(this.logoutUrl, "POST");
+        } else {
+            this.logoutRequestMatcher = new AntPathRequestMatcher(this.logoutUrl);
         }
-        return new AntPathRequestMatcher(this.logoutUrl);
+        return this.logoutRequestMatcher;
     }
 }

+ 40 - 0
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/CsrfConfigurerTests.groovy

@@ -15,6 +15,8 @@
  */
 package org.springframework.security.config.annotation.web.configurers
 
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher
+
 import javax.servlet.http.HttpServletResponse
 
 import org.springframework.context.annotation.Configuration
@@ -336,6 +338,18 @@ class CsrfConfigurerTests extends BaseSpringSpec {
             currentAuthentication != null
     }
 
+    def "SEC-2543: CSRF means logout requires POST"() {
+        setup:
+            loadConfig(LogoutConfig)
+            login()
+            request.servletPath = "/logout"
+            request.method = "GET"
+        when:
+            springSecurityFilterChain.doFilter(request,response,chain)
+        then: "logout with GET is not performed"
+            currentAuthentication != null
+    }
+
     @Configuration
     @EnableWebSecurity
     static class LogoutConfig extends WebSecurityConfigurerAdapter {
@@ -348,6 +362,32 @@ class CsrfConfigurerTests extends BaseSpringSpec {
         }
     }
 
+    def "CSRF can explicitly enable GET for logout"() {
+        setup:
+            loadConfig(LogoutAllowsGetConfig)
+            login()
+            request.servletPath = "/logout"
+            request.method = "GET"
+        when:
+            springSecurityFilterChain.doFilter(request,response,chain)
+        then: "logout with GET is not performed"
+            currentAuthentication == null
+    }
+
+    @Configuration
+    @EnableWebSecurity
+    static class LogoutAllowsGetConfig extends WebSecurityConfigurerAdapter {
+        static AccessDeniedHandler deniedHandler
+
+        @Override
+        protected void configure(HttpSecurity http) throws Exception {
+            http
+                .formLogin().and()
+                .logout()
+                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
+        }
+    }
+
     def "csrf disables POST requests from RequestCache"() {
         setup:
             CsrfDisablesPostRequestFromRequestCacheConfig.repo = Mock(CsrfTokenRepository)