CodeQL 文档

表达式语言注入 (Spring)

ID: java/spel-expression-injection
Kind: path-problem
Security severity: 9.3
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-094
Query suites:
   - java-code-scanning.qls
   - java-security-extended.qls
   - java-security-and-quality.qls

单击以在 CodeQL 存储库中查看查询

Spring 表达式语言 (SpEL) 是 Spring Framework 提供的强大表达式语言。该语言提供许多功能,包括调用 JVM 中可用的方法。如果使用攻击者控制的数据构建 SpEL 表达式,然后在强大的上下文中对其进行评估,则攻击者可能能够运行任意代码。

SpelExpressionParser 类解析 SpEL 表达式字符串并返回 Expression 实例,然后可以通过调用其一个方法来对其进行评估。默认情况下,在功能强大的 StandardEvaluationContext 中评估表达式,该上下文允许表达式访问 JVM 中可用的其他方法。

建议

一般而言,应避免在 SpEL 表达式中包含用户输入。如果必须在表达式中包含用户输入,则应在不允许任意方法调用的受限上下文中对其进行评估。

示例

以下示例使用不受信任的数据构建 SpEL 表达式,然后在默认的强大上下文中运行它。

public Object evaluate(Socket socket) throws IOException {
  try (BufferedReader reader = new BufferedReader(
      new InputStreamReader(socket.getInputStream()))) {

    String string = reader.readLine();
    ExpressionParser parser = new SpelExpressionParser();
    Expression expression = parser.parseExpression(string);
    return expression.getValue();
  }
}

下一个示例展示了如何在不允许访问任意方法的 SimpleEvaluationContext 中运行不受信任的 SpEL 表达式。但是,建议避免在 SpEL 表达式中使用不受信任的输入。

public Object evaluate(Socket socket) throws IOException {
  try (BufferedReader reader = new BufferedReader(
      new InputStreamReader(socket.getInputStream()))) {

    String string = reader.readLine();
    ExpressionParser parser = new SpelExpressionParser();
    Expression expression = parser.parseExpression(string);
    SimpleEvaluationContext context 
        = SimpleEvaluationContext.forReadWriteDataBinding().build();
    return expression.getValue(context);
  }
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私