Spring Security EnableMethodSecurity注解授权绕过(CVE-2025-22223)
字数 1629 2025-08-29 22:41:10

Spring Security EnableMethodSecurity 注解授权绕过漏洞分析 (CVE-2025-22223)

漏洞概述

漏洞编号: CVE-2025-22223
影响版本: Spring Security 6.4.0 - 6.4.3
修复版本: Spring Security 6.4.4
漏洞类型: 授权绕过
漏洞描述: 当使用 @EnableMethodSecurity 注解并在泛型父类、接口或重写方法上使用方法安全注解时,Spring Security 可能无法正确识别子类与父类的方法关系,导致安全注解失效。

受影响的安全注解

以下方法安全注解可能受到影响:

  • @PreAuthorize("hasRole('ADMIN')")
  • @Secured("ROLE_ADMIN")
  • @PreFilter("filterObject.owner == authentication.name")
  • @PostFilter("filterObject.owner == authentication.name")

漏洞复现环境

  1. Spring Boot 3.4.3 (默认使用 Spring Security 6.4.3)
  2. 使用 @EnableMethodSecurity 注解
  3. 包含泛型参数的父类方法上使用安全注解
  4. 子类继承并实现该方法

漏洞复现步骤

1. 创建Spring Boot入口类

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

2. 创建Spring Web配置类

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((requests) -> requests
                .anyRequest().authenticated()
            )
            .formLogin((form) -> form
                .loginPage("/login")
                .permitAll()
            )
            .logout((logout) -> logout.permitAll());
        return http.build();
    }
}

3. 创建方法安全配置类

@Configuration
@EnableMethodSecurity
public class MethodSecurityConfig {
}

4. 创建方法授权控制服务基类

public abstract class SecureServiceParent<T> {
    @Secured({"ROLE_USER", "ROLE_ADMIN"})
    public abstract T securedMethod();
}

5. 创建子类实现父类方法

@Service
public class SecureService extends SecureServiceParent<String> {
    @Override
    public String securedMethod() {
        return "Hello from secured method!";
    }
}

6. 创建测试控制器

@RestController
public class TestController {
    @Autowired
    private SecureService secureService;
    
    @GetMapping("/test")
    public String test() {
        return secureService.securedMethod();
    }
}

7. 测试漏洞

访问 /test 接口时,即使未登录也能成功执行 securedMethod 方法,证明安全注解失效。

漏洞原理分析

问题根源

漏洞存在于 org.springframework.security.core.annotation.UniqueSecurityAnnotationScanner 类中,具体在方法注解扫描逻辑上。

关键代码分析

  1. 方法查找问题:

    Method method = targetClass.getDeclaredMethod(methodName, parameterTypes);
    

    getDeclaredMethod 只能获取当前类声明的方法,无法获取父类方法,特别是当方法包含泛型参数时。

  2. 注解扫描策略:

    findDirectAnnotations(method)
    

    使用 DIRECT 策略只搜索直接声明在目标元素上的注解,不包括继承的注解。

  3. 泛型方法参数匹配问题:

    • 父类方法签名: securedMethod()
    • 子类方法签名: securedMethod()

    虽然看起来相同,但由于泛型擦除和类型参数的实际差异,导致方法匹配失败。

递归搜索的局限性

虽然 findClosestMethodAnnotations 方法会递归搜索父类和接口的方法,但当方法包含泛型参数时,由于方法签名匹配失败,无法正确找到父类方法及其注解。

漏洞修复方案

官方修复

在 Spring Security 6.4.4 中,官方新增了 findMethod 方法来进行更可靠的方法查找:

private static Method findMethod(Class<?> targetClass, String methodName, Class<?>... parameterTypes) {
    // 更完善的方法查找逻辑
}

修复建议

  1. 升级到 Spring Security 6.4.4 或更高版本
  2. 如果无法立即升级,可以采取以下临时措施:
    • 避免在泛型父类方法上使用安全注解
    • 在子类中显式添加安全注解
    • 使用接口而非抽象类定义安全方法

漏洞影响评估

受影响场景

  1. 使用 @EnableMethodSecurity 注解
  2. 存在泛型父类或接口
  3. 父类或接口方法上使用安全注解
  4. 子类继承并实现这些方法

不受影响场景

  1. 不使用泛型的普通方法继承
  2. 直接在子类方法上使用安全注解
  3. 不使用 @EnableMethodSecurity 注解

参考链接

  1. 官方修复代码diff
  2. CVE-2025-22223漏洞公告

总结

该漏洞揭示了Spring Security在处理方法安全注解时,特别是涉及泛型继承场景下的缺陷。开发人员应当及时升级到修复版本,并在设计安全控制时注意泛型方法的特殊处理。

Spring Security EnableMethodSecurity 注解授权绕过漏洞分析 (CVE-2025-22223) 漏洞概述 漏洞编号 : CVE-2025-22223 影响版本 : Spring Security 6.4.0 - 6.4.3 修复版本 : Spring Security 6.4.4 漏洞类型 : 授权绕过 漏洞描述 : 当使用 @EnableMethodSecurity 注解并在泛型父类、接口或重写方法上使用方法安全注解时,Spring Security 可能无法正确识别子类与父类的方法关系,导致安全注解失效。 受影响的安全注解 以下方法安全注解可能受到影响: @PreAuthorize("hasRole('ADMIN')") @Secured("ROLE_ADMIN") @PreFilter("filterObject.owner == authentication.name") @PostFilter("filterObject.owner == authentication.name") 漏洞复现环境 Spring Boot 3.4.3 (默认使用 Spring Security 6.4.3) 使用 @EnableMethodSecurity 注解 包含泛型参数的父类方法上使用安全注解 子类继承并实现该方法 漏洞复现步骤 1. 创建Spring Boot入口类 2. 创建Spring Web配置类 3. 创建方法安全配置类 4. 创建方法授权控制服务基类 5. 创建子类实现父类方法 6. 创建测试控制器 7. 测试漏洞 访问 /test 接口时,即使未登录也能成功执行 securedMethod 方法,证明安全注解失效。 漏洞原理分析 问题根源 漏洞存在于 org.springframework.security.core.annotation.UniqueSecurityAnnotationScanner 类中,具体在方法注解扫描逻辑上。 关键代码分析 方法查找问题 : getDeclaredMethod 只能获取当前类声明的方法,无法获取父类方法,特别是当方法包含泛型参数时。 注解扫描策略 : 使用 DIRECT 策略只搜索直接声明在目标元素上的注解,不包括继承的注解。 泛型方法参数匹配问题 : 父类方法签名: securedMethod() 子类方法签名: securedMethod() 虽然看起来相同,但由于泛型擦除和类型参数的实际差异,导致方法匹配失败。 递归搜索的局限性 虽然 findClosestMethodAnnotations 方法会递归搜索父类和接口的方法,但当方法包含泛型参数时,由于方法签名匹配失败,无法正确找到父类方法及其注解。 漏洞修复方案 官方修复 在 Spring Security 6.4.4 中,官方新增了 findMethod 方法来进行更可靠的方法查找: 修复建议 升级到 Spring Security 6.4.4 或更高版本 如果无法立即升级,可以采取以下临时措施: 避免在泛型父类方法上使用安全注解 在子类中显式添加安全注解 使用接口而非抽象类定义安全方法 漏洞影响评估 受影响场景 使用 @EnableMethodSecurity 注解 存在泛型父类或接口 父类或接口方法上使用安全注解 子类继承并实现这些方法 不受影响场景 不使用泛型的普通方法继承 直接在子类方法上使用安全注解 不使用 @EnableMethodSecurity 注解 参考链接 官方修复代码diff CVE-2025-22223漏洞公告 总结 该漏洞揭示了Spring Security在处理方法安全注解时,特别是涉及泛型继承场景下的缺陷。开发人员应当及时升级到修复版本,并在设计安全控制时注意泛型方法的特殊处理。