spring rce 漏洞分析(CVE-2022-22965)
字数 1458 2025-08-29 08:32:18
Spring Framework RCE漏洞分析(CVE-2022-22965)
漏洞概述
CVE-2022-22965是Spring Framework中的一个远程代码执行漏洞,该漏洞允许攻击者通过特制的HTTP请求修改Tomcat访问日志配置,最终实现任意代码执行。该漏洞影响Spring Framework 5.3.0至5.3.17、5.2.0至5.2.19以及更早版本。
环境要求
- JDK 9+
- Tomcat 8.0.53
- Spring Framework 5.3.17(受影响版本)
漏洞原理分析
核心机制
该漏洞利用了Spring Framework的两个特性组合:
- Java内置的
class属性:每个Java类都有一个内置的class属性,用于存储类实例 - Spring的JavaBean属性注入特性:Spring会自动将HTTP请求参数绑定到控制器方法的参数对象上
漏洞触发流程
- 攻击者发送特制的HTTP请求,参数名为
class.module.classLoader.resources.context.parent.pipeline.first.suffix - Spring以"."为分隔符解析参数,第一个对比属性为"class"
- Spring检查
propertyDescriptors变量中是否存在"class"属性 - 由于Java类确实有内置的
class属性,检查通过 - Spring获取
class实例作为属性进行注入操作 - 通过属性链式调用最终修改Tomcat访问日志配置
关键代码分析
漏洞的核心在于org.springframework.beans.CachedIntrospectionResults类的getPropertyDescriptor方法:
// 从HTTP请求参数分解出的属性值
String name = "class.module.classLoader.resources.context.parent.pipeline.first.suffix";
// 以"."为分隔符解析出第一个对比属性为"class"
String firstProperty = "class";
// 检查propertyDescriptors中是否存在"class"属性
PropertyDescriptor pd = this.propertyDescriptors.get(firstProperty);
propertyDescriptors变量存储了从JavaBean类解析出的属性描述符,包括内置的class属性:
// 在CachedIntrospectionResults构造方法中
PropertyDescriptor[] pds = this.beanInfo.getPropertyDescriptors();
// 这里会获取到Java类的所有属性,包括内置的class属性
绕过检查机制
Spring原本对classLoader属性做了检查,但通过module调用classLoader属性绕过了检查:
// 原本的检查只限制了class类的classLoader属性
// 使用module调用classLoader属性就绕过了这里的检查
class.module.classLoader...
利用条件
- JDK 9+:因为低版本JDK的
class类不存在module属性 - 使用Tomcat作为Servlet容器
- 应用程序以WAR包形式部署
- 应用程序使用了Spring的Web MVC或WebFlux框架
漏洞修复
Spring Framework 5.3.18版本中修复了该漏洞,修复方式是在org.springframework.beans.CachedIntrospectionResults类的构造方法中添加了更严格的检查:
(Class.class != beanClass || "name".equals(pd.getName()) || pd.getName().endsWith("Name"))
&& (pd.getPropertyType() == null
|| !ClassLoader.class.isAssignableFrom(pd.getPropertyType())
&& !ProtectionDomain.class.isAssignableFrom(pd.getPropertyType()))
修复措施:
- 检查属性类型是否为
ClassLoader.class和ProtectionDomain.class的子类 - 对
class属性的名称做了更严格的限制
漏洞总结
CVE-2022-22965漏洞的本质是两个Java常见特性的组合利用:
- Java内置
class属性 - Spring的JavaBean属性注入特性
漏洞成因在于对类和属性的检查不够全面,导致绕过。这个案例表明,在框架设计时需要对所有可能的属性访问路径进行严格的安全检查。
防护建议
- 升级Spring Framework到安全版本(5.3.18+或5.2.20+)
- 如果无法立即升级,可以添加
@InitBinder注解来禁止对特定字段的绑定 - 限制应用程序运行时的权限,减少攻击面
- 使用WAF等防护设备拦截恶意请求