java.spring.security.audit.spel-injection.spel-injection
Community Favorite

Author
50,762
Download Count*
License
A Spring expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation.
Run Locally
Run in CI
Defintion
rules:
- id: spel-injection
message: A Spring expression is built with a dynamic value. The source of the
value(s) should be verified to avoid that unfiltered values fall into this
risky code evaluation.
metadata:
cwe:
- "CWE-94: Improper Control of Generation of Code ('Code Injection')"
owasp:
- A03:2021 - Injection
source-rule-url: https://find-sec-bugs.github.io/bugs.htm#SPEL_INJECTION
category: security
technology:
- spring
references:
- https://owasp.org/Top10/A03_2021-Injection
cwe2022-top25: true
subcategory:
- audit
likelihood: LOW
impact: HIGH
confidence: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
severity: WARNING
languages:
- java
patterns:
- pattern-either:
- pattern-inside: |
class $CLASS {
...
ExpressionParser $PARSER;
...
}
- pattern-inside: |
class $CLASS {
...
ExpressionParser $PARSER = ...;
...
}
- pattern-inside: |
$X $METHOD(...) {
...
ExpressionParser $PARSER = ...;
...
}
- pattern-inside: |
class $CLASS {
...
SpelExpressionParser $PARSER;
...
}
- pattern-inside: |
class $CLASS {
...
SpelExpressionParser $PARSER = ...;
...
}
- pattern-inside: |
$X $METHOD(...) {
...
SpelExpressionParser $PARSER = ...;
...
}
- pattern-inside: |
class $CLASS {
...
TemplateAwareExpressionParser $PARSER;
...
}
- pattern-inside: |
class $CLASS {
...
TemplateAwareExpressionParser $PARSER = ...;
...
}
- pattern-inside: |
$X $METHOD(...) {
...
TemplateAwareExpressionParser $PARSER = ...;
...
}
- pattern: |
$X $METHOD(...) {
...
$PARSER.parseExpression(...);
...
}
- pattern-not: |
$X $METHOD(...) {
...
$PARSER.parseExpression("...");
...
}
- pattern-not: |
$X $METHOD(...) {
...
String $S = "...";
...
$PARSER.parseExpression($S);
...
}
Examples
spel-injection.java
package testcode.script;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.common.TemplateAwareExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class SpelSample {
private static PersonDTO TEST_PERSON = new PersonDTO("Benoit", "Doudou");
// ruleid: spel-injection
public static void parseExpressionInterface1(String property) {
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext testContext = new StandardEvaluationContext(TEST_PERSON);
Expression exp2 = parser.parseExpression(property+" == 'Benoit'");
String dynamicValue = exp2.getValue(testContext, String.class);
System.out.println("exp2="+dynamicValue);
}
// ok: spel-injection
public static void parseExpressionInterface2(String property) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp1 = parser.parseExpression("'safe expression'");
String constantValue = exp1.getValue(String.class);
System.out.println("exp1="+constantValue);
}
// ruleid: spel-injection
public static void parseSpelExpression3(String property) {
SpelExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext testContext = new StandardEvaluationContext(TEST_PERSON);
Expression exp2 = parser.parseExpression(property+" == 'Benoit'");
String dynamicValue = exp2.getValue(testContext, String.class);
System.out.println("exp2=" + dynamicValue);
}
// ok: spel-injection
public static void parseSpelExpression4(String property) {
SpelExpressionParser parser = new SpelExpressionParser();
Expression exp1 = parser.parseExpression("'safe expression'");
String constantValue = exp1.getValue(String.class);
System.out.println("exp1="+constantValue);
}
// ok: spel-injection
public static void parseTemplateAwareExpression1(String property) {
TemplateAwareExpressionParser parser = new SpelExpressionParser();
Expression exp1 = parser.parseExpression("'safe expression'");
String constantValue = exp1.getValue(String.class);
System.out.println("exp1="+constantValue);
}
// ruleid: spel-injection
public static void parseTemplateAwareExpression2(String property) {
TemplateAwareExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext testContext = new StandardEvaluationContext(TEST_PERSON);
Expression exp2 = parser.parseExpression(property+" == 'Benoit'");
String dynamicValue = exp2.getValue(testContext, String.class);
System.out.println("exp2="+dynamicValue);
}
public static void main(String[] args) {
//Expected use case..
parseExpressionInterface("firstName");
//Malicious use case..
parseExpressionInterface("T(java.lang.Runtime).getRuntime().exec('calc.exe')");
}
static class PersonDTO {
public final String firstName;
public final String lastName;
public PersonDTO(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
}
Short Link: https://sg.run/XBp4