威胁描述
计算未验证的 SpEL 表达式可能导致执行远程代码。
威胁说明
Spring 表达式语言(简写为 SpEL)是一种功能强大的表达式语言,支持在运行时查询和处理对象图。该语言的语法与统一 EL 类似,但提供了更多功能,尤其是方法调用和基本字符串模板化功能。允许计算未验证的表达式将允许攻击者执行任意代码。
示例 1:应用程序使用受用户控制的未验证数据创建和计算 SpEL 表达式
String expression = request.getParameter("message");
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw(expression);
示例 2:应用程序在执行双重 SpEL 计算的 Spring 标记中使用受用户控制的未验证数据
<spring:message text="" code="${param['message']}"></spring:message>
示例1和示例2攻击Payload:
# 弹出计算器
http://localhost:8080/test?message=${new%20java.lang.ProcessBuilder(new%20java.lang.String(new%20byte[]{99,97,108,99})).start()} # calc
参考
修复建议
1. 限制SpEL功能
SpEL 提供的两个 EvaluationContext
,区别如下:
-
SimpleEvaluationContext
- 针对不需要 SpEL 语言语法的全部范围并且应该受到有意限制的表达式类别,公开 SpEL 语言特性和配置选项的子集。 -
StandardEvaluationContext
- 公开全套 SpEL 语言功能和配置选项。您可以使用它来指定默认的根对象并配置每个可用的评估相关策略。
SimpleEvaluationContext
旨在仅支持 SpEL 语言语法的一个子集。它不包括 Java类型引用
、构造函数
和 bean引用
。所以说指定正确 EvaluationContext
,是防止SpEl表达式注入漏洞产生的首选。方法如下:
String expression = request.getParameter("message");
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(expression);
StandardEvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().withRootObject().build();
String message = exp.getValue(context, String.class);
exp.setValue(context, "Hello");
参考:Spring表达式使用
2. Spring Boot
影响版本:
-
1.1.0
-1.1.12
-
1.2.0
-1.2.7
1.3.0
修复方案:升级至 1.3.1
或以上版本
参考:
3. Spring Data Commons
影响版本:
- Spring Data Commons 1.13 - 1.13.10 (Ingalls SR10)
- Spring Data REST 2.6 - 2.6.10 (Ingalls SR10)
- Spring Data Commons 2.0 to 2.0.5 (Kay SR5)
- Spring Data REST 3.0 - 3.0.5 (Kay SR5)
- 更早的版本也会受到影响
修复方法:
升级代码框架
- Spring Data Commons
- 2.0.x的用户升级到2.0.6及以上
- 1.13.x的用户升级到1.13.11及以上
- Spring Data REST
- 2.x用户升级到2.6.11及以上
- 3.x用户升级到3.0.6及以上
- Spring Boot
- 1.5.x用户升级到1.5.11及以上
- 2.x用户升级到2.0.1及以上
网友评论