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解析机制

  1. 启动时解析

    • 检查查询语句是否包含#{#entityName}
    • 硬编码比较,无法控制表达式内容
  2. 请求时解析

    • 通过QueryParameterSetterFactory.create()方法处理
    • 最终调用InternalSpelExpressionParser.doParseExpression
    • 不会将?0等占位符作为SpEL表达式解析

Spring Data MongoDB的SpEL解析机制

关键解析流程

  1. org.springframework.data.mongodb.util.json.ParameterBindingJsonReader处理表达式
  2. PARAMETER_BINDING_PATTERN.matcher(expression)检查\?(\d+)格式占位符
  3. 直接替换占位符为请求参数值
  4. 对结果表达式进行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. 测试方法

  1. 配置类测试

    • application.properties中尝试注入SpEL表达式
    • 配合actuator端点验证效果
  2. 注解测试

    • 检查@Query@Aggregation等注解的可控参数
    • 验证参数是否经过SpEL解析
  3. 上下文分析

    • 区分StandardEvaluationContextSimpleEvaluationContext
    • 前者支持完整SpEL功能,后者限制危险操作

3. 版本比对

  • 对比不同版本间的代码差异
  • 特别关注异常处理逻辑的变化
  • 分析防御机制被绕过的可能性

防御建议

  1. 使用SimpleEvaluationContext替代StandardEvaluationContext
  2. 对用户输入进行严格过滤和转义
  3. 限制actuator端点的访问权限
  4. 及时更新存在漏洞的组件版本

总结

SpEL注入漏洞主要存在于Spring生态系统的配置和注解场景中,通过系统化的分析和测试方法,安全研究人员可以有效地发现这类漏洞。理解不同组件对SpEL解析的差异是实现高效挖掘的关键。

Spring表达式语言(SpEL)注入漏洞研究与挖掘指南 前言 本文基于对SpEL表达式的深入研究,总结了多种Spring组件中存在的SpEL注入场景,并详细分析了CVE-2022-22980漏洞的发现过程和技术细节。旨在为安全研究人员提供SpEL漏洞挖掘的系统性方法。 SpEL注入常见场景 1. spring-cloud-starter-netflix-turbine 漏洞点 : application.properties 中的 turbine.cluster-name-expression 属性 利用方式 : 限制条件 : 需要配合actuator端点( /actuator/env 、 /actuator/restart ) 使用 /actuator/restart 时可能导致服务崩溃 2. spring-cloud-stream 漏洞点 : @StreamListener 注解的 condition 属性 利用方式 : 特点 : 注解参数通常为硬编码,实际利用难度较大 3. spring-cloud-kubernetes 漏洞点 : application.properties 中的 spring.cloud.kubernetes.discovery.filter 属性 利用方式 : 限制条件 : 需要配合 /actuator/env 使用 SimpleEvaluationContext 不支持 T(Runtime) 等危险操作 4. spring-data-jpa 漏洞点 : @Query 注解的 value 属性 利用方式 : 特点 : 实际危害性较低,通常为开发人员可控内容 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块外,异常会中断流程 漏洞利用示例 当传入参数为恶意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解析的差异是实现高效挖掘的关键。