Spring Security EnableMethodSecurity注解授权绕过(CVE-2025-22223)
1603437587432088 漏洞分析 683浏览 · 2025-04-23 12:28

漏洞描述

img.png
该漏洞影响 Spring Security 6.4.0 - 6.4.3 版本,在6.4.4 版本做了修复

漏洞演示

通过漏洞描述我们知道该漏洞的触发需要使用 EnableMethodSecurity 注解,并且在泛型父类,接口,重写方法上使用了方法安全注解,如:@PreAuthorize("hasRole('ADMIN')") @Secured("ROLE_ADMIN") @PreFilter("filterObject.owner == authentication.name") @PostFilter("filterObject.owner == authentication.name")

首先我们需要构造一个spring Security的项目 这里使用spring boot构造spring-boot-starter-parent 版本为 3.4.3 该版本使用的spring security 版本为 6.4.3 刚好符合要求创建spring boot入口类

创建 spring web 配置类

创建 方法安全配置类

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

在该基类中定义了抽象方法 securedMethod 该方法将被子类继承实现,并使用 @Secured 注解进行方法安全控制

只有具有ROLE_USERROLE_ADMIN 角色的用户可以访问该方法

创建子类,子类实现父类方法 securedMethod

创建测试控制器

测试控制器方法 test 调用了安全服务的 securedMethod 方法

一般来讲因为 @EnableMethodSecurity 注解的配置,所以 @Secured 注解的方法在未登录的情况下无法访问,即此时访问/test接口会响应一个访问被拒绝的响应

将我们的程序跑起来并访问http://127.0.0.1:8080/test
img_1.png
如上图,我们访问/test接口时并没有登录 securedMethod 方法却成功执行了。

这证明当存在泛型时spring security并不能有效的将子类与父类的securedMethod方法识别为同一个,故此时在包含了泛型参数的父类方法中使用的@Secured等注解进行的访问控制并不能生效。

为了进行对比可以修改 securedMethod方法的签名取消掉泛型信息再次对/test接口进行访问,此时页面会被重定向到登录页面。

漏洞原理

我们知道漏洞支持的最高版本为6.4.3 所以我们将6.4.3版本与6.4.4版本进行对比参考比较链接

从而发现在core/src/main/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScanner.java 类中进行了关键更改
img_2.png
在上图的代码中,首先通过反射调用targetClassgetDeclaredMethod以获取当前类的某一个方法得到一个Method对象,然后通过findDirectAnnotations方法获取到该方法的所有注解。

getDeclaredMethod 方法获取的方法名并不能获取到父类的方法,当存在重写方法时该方法获取到的Method对象只包括当前类声明的方法

findDirectAnnotations 方法搜索注解的策略是MergedAnnotations.SearchStrategy.DIRECT 即只搜索直接声明在目标元素上的注解,不包括继承的注解,所以此时也获取不到父类方法的注解。

这样就产生了漏洞

在实际测试的时候发现只是单纯的在父类方法中声明方法安全注解而不在子类中声明并不会导致漏洞,只有在父类方法包含泛型的时候才会导致漏洞,

那么证明这个漏洞逻辑还不够完整,我们看findClosestMethodAnnotations方法中下面的代码

这里递归调用了findClosestMethodAnnotations方法,第二个参数发生了变化成了targetClass的父类,

也就是说在 findClosestMethodAnnotations是会递归搜索当前目标类的所有父类或者接口的方法从而查找到所有相关的注解的。

这就是为什么普通的方法并不会存在漏洞,那为什么泛型方法会导致漏洞呢?这就要回到173行的代码了

这里获取Method对象的方法是通过方法名以及方法参数列表来查找的,当一个方法是泛型方法时我们看看他的方法参数列表是怎么样的

也就是我们上面SecureServiceParentsecuredMethod方法

其实现类SecureServicesecuredMethod方法的签名

两者的不一致导致findClosestMethodAnnotations在查找子类泛型方法的父类实现时找不到,也就不能获取到父类方法上的注解,从而导致漏洞。

漏洞修复

官方新增了 findMethod方法来进行方法查找

参考链接

代码diff

CVE-2025-22223: Spring Security authorization bypass for method security annotations on parameterized types

0 条评论
某人
表情
可输入 255