Apache Spring Data MongoDB SpEL表达式注入漏洞简述
Spring Data MongoDB 是一个用于操作 MongoDB 数据库的 Spring 框架模块。它提供了便捷的数据访问抽象和集成。和许多其他 Spring Data 模块一样,Spring Data MongoDB 支持使用 Spring Expression Language(SpEL)来构建查询。
SpEL 表达式注入漏洞是指攻击者能够通过修改输入参数,注入恶意的 SpEL 表达式,从而影响应用程序的行为或访问未授权的数据。这种类型的漏洞可能允许攻击者执行任意代码、篡改数据或泄露敏感信息。
影响版本:
Spring Data MongoDB 3.4.0
3.3.0 <= Spring Data MongoDB <= 3.3.4 旧的、不受支持的版本也会受到影响
Apache Spring Data MongoDB SpEL表达式注入漏洞利用原理
Apache Spring Data MongoDB SpEL表达式注入漏洞(CVE-2022-22980)的利用原理如下:
1. SpEL表达式注入:Spring Data MongoDB应用程序在对包含查询参数占位符的SpEL表达式使用@Query或@Aggregation注解的查询方法进行值绑定时,如果输入未被过滤,则容易受到SpEL注入攻击;
2. 攻击者构造恶意数据:攻击者可以利用这个漏洞,通过构造恶意数据执行远程代码,最终获取服务器权限;
3. 参数绑定漏洞:漏洞的核心逻辑位于ParameterBindingJsonReader类,负责读取JSON并计算占位符和SpEL表达式;
4. 正则匹配问题:在处理SpEL表达式时,存在两个正则匹配的代码,第一个正则代码只能匹配 ?#{} 或者 :#{} 形式的字符串。匹配成功后则认为是SpEL表达式格式,然后此时expression是 {} 中的值,然后接着会判断是否满足 ?\d ,也就是 ?数字。只有符合这种格式才会使用getBindableValueForIndex提取传入的参数,这也是为什么临时修复措施中推荐使用[0]代替?0的原因;
5. 漏洞触发条件:当满足以下任一条件时,则不受此漏洞影响:
- 带 @Query 或 @Aggregation 注解的查询方法不包含表达式;
- 带@Query或@Aggregation注解的查询方法不使用表达式中的参数占位符语法;
- 存储库配置为使用限制SpEL使用的QueryMethodObservationContextProvider。
Apache Spring Data MongoDB SpEL表达式注入漏洞POC
针对Apache Spring Data MongoDB SpEL表达式注入漏洞(CVE-2022-22980)的POC,以下是一个示例:
- 使用threedr3am师傅提供的demo,导入IDEA直接启动,无需配置数据库,因为该漏洞是在数据库请求之前触发的。
- 环境搭建参考链接:[threedr3am/learnjavabug](https://github.com/threedr3am/learnjavabug/tree/master/spring/spring-data-mongodb-spel-CVE-2022-22980);
- 根据官方漏洞通报,当使用 @Query 或@Aggregation 注解进行查询时,若通过SpEL占位符获取输入参数并过滤不当就会造成RCE。
- 分析数据流发现该漏洞的核心逻辑位于`ParameterBindingJsonReader`类,负责读取JSON并计算占位符和SpEL表达式。
- 漏洞触发条件包括使用 @Query 或 @Aggregation 注解的查询方法,使用SpEL表达式中的输入参数引用(如 ?0 , ?1, ...);
- 以下是一个简单的Spring Boot应用程序示例,演示了SpEL表达式注入漏洞的利用:
@RestController
publicclassUserController {
@Autowired
privateUserRepository userRepository;
@GetMapping("/users")
publicList<User> getUsers(@RequestParamString username) {
String query = "new String(new byte[]{" + username + "})";
List<User> users = userRepository.findAll(Example.of(User.builder().name(query).build()));
return users;
}
}
这个POC通过构造SpEL表达式注入的查询,尝试执行任意代码。
本POC仅用于教育和科普目的,以帮助理解漏洞的工作原理和潜在影响。在实际环境中,使用或创建POC来攻击系统是非法的,并且可能导致严重的法律后果。如果你是系统管理员或安全研究人员,应该在获得明确授权的情况下,使用这些信息来测试和加固自己的系统,而不是用于攻击他人系统。)
Apache Spring Data MongoDB SpEL表达式注入漏洞防御方式
针对Apache Spring Data MongoDB SpEL表达式注入漏洞(CVE-2022-22980)的防御方式,以下是一些推荐的措施:
1. 升级到安全版本:官方已经发布了修复该漏洞的版本,建议受影响的用户尽快升级到以下安全版本:
- Spring Data MongoDB 3.4.1及以上版本;
- Spring Data MongoDB 3.3.5及以上版本;
2. 重写查询或聚合声明:在表达式中使用参数引用时,应使用数组形式语法“[0]”而不是“?0”;
3. 清理参数:在调用查询方法之前,应对参数进行清理,以防止SpEL表达式注入;
4. 使用受限的QueryMethodEvaluationContextProvider:通过BeanPostProcessor重新配置存储库工厂Bean,使用受限的QueryMethodEvaluationContextProvider;
5. 过滤用户输入:在调用查询方法时,应对用户输入进行过滤,以防止SpEL表达式注入;
6. 官方补丁和文档:更多修复建议和详细信息,请参考官方发布的安全建议文档:[Spring Data MongoDB SpEL Expression Injection Vulnerability CVE-2022-22980](https://spring.io/blog/2022/06/20/spring-data-mongodb-spel-expression-injection-vulnerability-cve-2022-22980)。
通过实施上述措施,可以有效地防御Apache Spring Data MongoDB SpEL表达式注入漏洞(CVE-2022-22980),保护系统免受未授权远程代码执行攻击的威胁。
原文始发于微信公众号(w小小杂谈w):漏洞科普——Apache Spring Data MongoDB SpEL表达式注入漏洞(CVE-2022-22980)
评论