目录

  1. 1. 前言
  2. 2. antMatchers 配置不当权限绕过
    1. 2.1. poc
    2. 2.2. 修复
  3. 3. regexMatchers 配置不当权限绕过
    1. 3.1. poc
    2. 3.2. 修复
  4. 4. useSuffixPatternMatch 低版本权限绕过
    1. 4.1. poc
    2. 4.2. 修复
  5. 5. CVE-2022-22978 (regexMatchers)
    1. 5.1. poc
    2. 5.2. 修复方式
  6. 6. CVE-2022-31692 (forward&include 转发)
    1. 6.1. CVE-2023-34034(WebFlux)

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

SpringSecurity权限绕过

2024/7/15 Web Java
  |     |   总文章阅读量:

前言

趁热打铁v2,虽然实际上是纯记录用的

参考:https://xz.aliyun.com/t/13235


antMatchers 配置不当权限绕过

漏洞代码:

@Configuration
@EnableWebSecurity
public class antMatchersConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/admin").access("hasRole('ADMIN')")
            .antMatchers("/**").permitAll();

        return http.build();
    }

    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(user);
    }

}

这里使用了antMatchers("/test").access("hasRole('ADMIN')"),只有ADMIN才可以访问test,但是没有去按照正常的写法: /test/** ,导致可以通过/test/,来绕过对/test 的校验

poc

http://127.0.0.1:8080/admin/

修复

mvcMatchers("/test").access("hasRole('ADMIN')")

antMatchers("/test/**").access("hasRole('ADMIN')")

regexMatchers 配置不当权限绕过

使用正则表达式进行匹配

漏洞代码:

public class AuthConfig {
    @Bean  
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {  
        http  
            .csrf().disable()  
            .authorizeRequests()  
            .regexMatchers("/admin").access("hasRole('ADMIN')")  
            .regexMatchers("/**").access("anonymous");
        ...

/admin正则没写完整

poc

http://127.0.0.1:8080/admin?
http://127.0.0.1:8080/admin/

修复

将正则写完整

.regexMatchers("/admin.*?").access("hasRole('ADMIN')")

useSuffixPatternMatch 低版本权限绕过

Spring-webmvc版本在<=4.3.25的情况下suffixPatternMatch默认为True

该方法为是否启用后辍匹配,如果启用,则映射到/users的方法也可以匹配到/users.*

也就是说/users/users.*是相等的

漏洞代码:

@Controller
public class AuthController {

    @RequestMapping(value = {"/admin"}, method = {RequestMethod.GET})
    @ResponseBody
    public String admin() {
        return "hello admin";
    }

    @RequestMapping(value = {"/test"}, method = {RequestMethod.GET})
    @ResponseBody
    public String test() {
        return "hello test";
    }
}

poc

低版本(1.x)的springboot上能绕过

http://127.0.0.1:8080/admin.123456789

修复

版本更新


CVE-2022-22978 (regexMatchers)

影响版本:

Spring Security 5.6.x < 5.6.4
Spring Security 5.5.x < 5.5.7
Spring Security 5.4.x < 5.4.11

漏洞代码:

.regexMatchers("/admin/.*").access("hasRole('ADMIN')")

controller配置:只能对/admin/**这种匹配所有路径的语法才能生效,如果写死了/admin/api,这样子是无法绕过的,因为就算绕过权限校验,但是程序无法匹配到路由

poc

/admin/%0a
/admin/%0d

修复方式

更新版本

或者感觉可以写死路由路径


CVE-2022-31692 (forward&include 转发)

当使用Spring Security的时候,一般会创建一个SecurityFilterChain来为特定的路由设置权限,路由A为匿名访问权限,路由B为高权限,如果在Controller中定义低权限A路由return的时候,使用了forwardinclude请求,将会导致将低权限的请求转发或包含到一个更高权限的安全端点,从而实现越权

漏洞代码:

package com.example.springsecdemo2.demos;

import ...

@Configuration
@EnableWebSecurity
public class antMatchersConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/forward").permitAll()
                .antMatchers("/admin/**").access("hasRole('ADMIN')");
//                .antMatchers("/**").permitAll();
//                .antMatchers("/test/**").permitAll();

        // @formatter:on
        return http.build();
    }


    // @formatter:off
    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(user);
    }
    // @formatter:on
}
package com.example.springsecdemo2.demos.Controller;

import ...

@Controller
public class AuthController {

    @RequestMapping(value = {"/forward"}, method = {RequestMethod.GET})
//    @GetMapping("/forward")
    public String forward() {
        return "include:/admin";
        //return "forward:/admin";
    }


    @RequestMapping(value = {"/admin/api"}, method = {RequestMethod.GET})
    @ResponseBody
    public String adminapi() {
        return "hello adminapi";
    }

    @RequestMapping(value = {"/admin/**"}, method = {RequestMethod.GET})
    @ResponseBody
    public String admin() {
        return "hello admin";
    }

    @RequestMapping(value = {"/test/api"}, method = {RequestMethod.GET})
    @ResponseBody
    public String testapi() {
        return "hello testapi";
    }

    @RequestMapping(value = {"/test/**"}, method = {RequestMethod.GET})
    @ResponseBody
    public String test() {
        return "hello test";
    }

//    @RequestMapping(value = {"/**"}, method = {RequestMethod.GET})
//    @ResponseBody
//    public String guest() {
//        return "hello guest";
//    }
}

CVE-2023-34034(WebFlux)

在Spring Security中,ServerHttpSecurityHttpSecurity分别用于配置WebFlux和Web MVC应用程序的安全性

影响版本:

  • 6.1.0 to 6.1.1
  • 6.0.0 to 6.0.4
  • 5.8.0 to 5.8.4
  • 5.7.0 to 5.7.9
  • 5.6.0 to 5.6.11

漏洞代码:

return http.authorizeExchange()
                .pathMatchers("/**").permitAll()
                .pathMatchers("admin/**").hasRole("ADMIN")	// 没有以 / 为开始
                .anyExchange().authenticated()
                .and()
            .build();

controller:

@RequestMapping(value = {"/admin/**"}, method = {RequestMethod.GET})
    @ResponseBody
    public String admin() {
        return "hello admin";
    }