Skip to content

Commit fec8097

Browse files
committed
Refactor SpelInjectionQuery
1 parent 787b733 commit fec8097

File tree

3 files changed

+31
-14
lines changed

3 files changed

+31
-14
lines changed

java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ private import semmle.code.java.frameworks.spring.SpringExpression
77
private import semmle.code.java.security.SpelInjection
88

99
/**
10+
* DEPRECATED: Use `SpelInjectionFlow` instead.
11+
*
1012
* A taint-tracking configuration for unsafe user input
1113
* that is used to construct and evaluate a SpEL expression.
1214
*/
13-
class SpelInjectionConfig extends TaintTracking::Configuration {
15+
deprecated class SpelInjectionConfig extends TaintTracking::Configuration {
1416
SpelInjectionConfig() { this = "SpelInjectionConfig" }
1517

1618
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
@@ -22,37 +24,52 @@ class SpelInjectionConfig extends TaintTracking::Configuration {
2224
}
2325
}
2426

27+
/**
28+
* A taint-tracking configuration for unsafe user input
29+
* that is used to construct and evaluate a SpEL expression.
30+
*/
31+
private module SpelInjectionConfig implements DataFlow::ConfigSig {
32+
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
33+
34+
predicate isSink(DataFlow::Node sink) { sink instanceof SpelExpressionEvaluationSink }
35+
36+
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
37+
any(SpelExpressionInjectionAdditionalTaintStep c).step(node1, node2)
38+
}
39+
}
40+
41+
/** Tracks flow of unsafe user input that is used to construct and evaluate a SpEL expression. */
42+
module SpelInjectionFlow = TaintTracking::Make<SpelInjectionConfig>;
43+
2544
/** Default sink for SpEL injection vulnerabilities. */
2645
private class DefaultSpelExpressionEvaluationSink extends SpelExpressionEvaluationSink {
2746
DefaultSpelExpressionEvaluationSink() {
2847
exists(MethodAccess ma |
2948
ma.getMethod() instanceof ExpressionEvaluationMethod and
3049
ma.getQualifier() = this.asExpr() and
31-
not exists(SafeEvaluationContextFlowConfig config |
32-
config.hasFlowTo(DataFlow::exprNode(ma.getArgument(0)))
33-
)
50+
not SafeEvaluationContextFlow::hasFlowToExpr(ma.getArgument(0))
3451
)
3552
}
3653
}
3754

3855
/**
3956
* A configuration for safe evaluation context that may be used in expression evaluation.
4057
*/
41-
private class SafeEvaluationContextFlowConfig extends DataFlow2::Configuration {
42-
SafeEvaluationContextFlowConfig() { this = "SpelInjection::SafeEvaluationContextFlowConfig" }
43-
44-
override predicate isSource(DataFlow::Node source) { source instanceof SafeContextSource }
58+
private module SafeEvaluationContextFlowConfig implements DataFlow::ConfigSig {
59+
predicate isSource(DataFlow::Node source) { source instanceof SafeContextSource }
4560

46-
override predicate isSink(DataFlow::Node sink) {
61+
predicate isSink(DataFlow::Node sink) {
4762
exists(MethodAccess ma |
4863
ma.getMethod() instanceof ExpressionEvaluationMethod and
4964
ma.getArgument(0) = sink.asExpr()
5065
)
5166
}
5267

53-
override int fieldFlowBranchLimit() { result = 0 }
68+
int fieldFlowBranchLimit() { result = 0 }
5469
}
5570

71+
private module SafeEvaluationContextFlow = DataFlow::Make<SafeEvaluationContextFlowConfig>;
72+
5673
/**
5774
* A `ContextSource` that is safe from SpEL injection.
5875
*/

java/ql/src/Security/CWE/CWE-094/SpelInjection.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
import java
1515
import semmle.code.java.security.SpelInjectionQuery
1616
import semmle.code.java.dataflow.DataFlow
17-
import DataFlow::PathGraph
17+
import SpelInjectionFlow::PathGraph
1818

19-
from DataFlow::PathNode source, DataFlow::PathNode sink, SpelInjectionConfig conf
20-
where conf.hasFlowPath(source, sink)
19+
from SpelInjectionFlow::PathNode source, SpelInjectionFlow::PathNode sink
20+
where SpelInjectionFlow::hasFlowPath(source, sink)
2121
select sink.getNode(), source, sink, "SpEL expression depends on a $@.", source.getNode(),
2222
"user-provided value"

java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class HasSpelInjectionTest extends InlineExpectationsTest {
1111

1212
override predicate hasActualResult(Location location, string element, string tag, string value) {
1313
tag = "hasSpelInjection" and
14-
exists(DataFlow::Node sink, SpelInjectionConfig conf | conf.hasFlowTo(sink) |
14+
exists(DataFlow::Node sink | SpelInjectionFlow::hasFlowTo(sink) |
1515
sink.getLocation() = location and
1616
element = sink.toString() and
1717
value = ""

0 commit comments

Comments
 (0)