Spel的研究总结
字数 1940 2025-08-27 12:33:43
Spring表达式语言(SpEL)注入漏洞研究与挖掘指南
前言
本文基于对SpEL表达式的深入研究,总结了多种Spring组件中存在的SpEL注入场景,并详细分析了CVE-2022-22980漏洞的发现过程和技术细节。旨在为安全研究人员提供SpEL漏洞挖掘的系统性方法。
SpEL注入常见场景
1. spring-cloud-starter-netflix-turbine
漏洞点:
application.properties中的turbine.cluster-name-expression属性
利用方式:
turbine.cluster-name-expression="T(Runtime).getRuntime().exec('calc')"
限制条件:
- 需要配合actuator端点(
/actuator/env、/actuator/restart) - 使用
/actuator/restart时可能导致服务崩溃
2. spring-cloud-stream
漏洞点:
@StreamListener注解的condition属性
利用方式:
@StreamListener(value = Sink.INPUT, condition = "T(Runtime).getRuntime().exec('calc')")
特点:
- 注解参数通常为硬编码,实际利用难度较大
3. spring-cloud-kubernetes
漏洞点:
application.properties中的spring.cloud.kubernetes.discovery.filter属性
利用方式:
spring.cloud.kubernetes.discovery.filter=T(Runtime).getRuntime().exec('calc')
限制条件:
- 需要配合
/actuator/env - 使用
SimpleEvaluationContext不支持T(Runtime)等危险操作
4. spring-data-jpa
漏洞点:
@Query注解的value属性
利用方式:
@Query(value="select * from user where id = ?#{T(Runtime).getRuntime().exec('calc')}", nativeQuery=true)
特点:
- 实际危害性较低,通常为开发人员可控内容
CVE-2022-22980深度分析
漏洞背景
在Spring-data-mongodb组件中发现的SpEL注入漏洞,主要影响@Query和@Aggregation注解的使用场景。
技术细节对比
Spring Data JPA的SpEL解析机制
-
启动时解析:
- 检查查询语句是否包含
#{#entityName} - 硬编码比较,无法控制表达式内容
- 检查查询语句是否包含
-
请求时解析:
- 通过
QueryParameterSetterFactory.create()方法处理 - 最终调用
InternalSpelExpressionParser.doParseExpression - 不会将
?0等占位符作为SpEL表达式解析
- 通过
Spring Data MongoDB的SpEL解析机制
关键解析流程:
org.springframework.data.mongodb.util.json.ParameterBindingJsonReader处理表达式PARAMETER_BINDING_PATTERN.matcher(expression)检查\?(\d+)格式占位符- 直接替换占位符为请求参数值
- 对结果表达式进行SpEL解析
版本差异:
- 3.4.0版本:
reader.readStartDocument()在try块内,异常被捕获后继续执行 - 3.3.x及以下版本:
reader.readStartDocument()在try块外,异常会中断流程
漏洞利用示例
@Query(":#{?0}")
User getDataInfo(String info);
当传入参数为恶意SpEL表达式时,如T(Runtime).getRuntime().exec('calc'),将导致命令执行。
SpEL注入挖掘方法论
1. 目标定位
重点关注以下场景:
- 配置文件中可动态解析的属性
- 注解中的表达式参数
- 与外部输入交互的SpEL解析点
2. 测试方法
-
配置类测试:
- 在
application.properties中尝试注入SpEL表达式 - 配合actuator端点验证效果
- 在
-
注解测试:
- 检查
@Query、@Aggregation等注解的可控参数 - 验证参数是否经过SpEL解析
- 检查
-
上下文分析:
- 区分
StandardEvaluationContext和SimpleEvaluationContext - 前者支持完整SpEL功能,后者限制危险操作
- 区分
3. 版本比对
- 对比不同版本间的代码差异
- 特别关注异常处理逻辑的变化
- 分析防御机制被绕过的可能性
防御建议
- 使用
SimpleEvaluationContext替代StandardEvaluationContext - 对用户输入进行严格过滤和转义
- 限制actuator端点的访问权限
- 及时更新存在漏洞的组件版本
总结
SpEL注入漏洞主要存在于Spring生态系统的配置和注解场景中,通过系统化的分析和测试方法,安全研究人员可以有效地发现这类漏洞。理解不同组件对SpEL解析的差异是实现高效挖掘的关键。