mirror of
https://github.com/github/codeql.git
synced 2025-12-17 17:23:36 +01:00
Refactor SpelInjectionQuery
This commit is contained in:
@@ -7,10 +7,12 @@ private import semmle.code.java.frameworks.spring.SpringExpression
|
|||||||
private import semmle.code.java.security.SpelInjection
|
private import semmle.code.java.security.SpelInjection
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `SpelInjectionFlow` instead.
|
||||||
|
*
|
||||||
* A taint-tracking configuration for unsafe user input
|
* A taint-tracking configuration for unsafe user input
|
||||||
* that is used to construct and evaluate a SpEL expression.
|
* that is used to construct and evaluate a SpEL expression.
|
||||||
*/
|
*/
|
||||||
class SpelInjectionConfig extends TaintTracking::Configuration {
|
deprecated class SpelInjectionConfig extends TaintTracking::Configuration {
|
||||||
SpelInjectionConfig() { this = "SpelInjectionConfig" }
|
SpelInjectionConfig() { this = "SpelInjectionConfig" }
|
||||||
|
|
||||||
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||||
@@ -22,15 +24,30 @@ class SpelInjectionConfig extends TaintTracking::Configuration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A taint-tracking configuration for unsafe user input
|
||||||
|
* that is used to construct and evaluate a SpEL expression.
|
||||||
|
*/
|
||||||
|
private module SpelInjectionConfig implements DataFlow::ConfigSig {
|
||||||
|
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||||
|
|
||||||
|
predicate isSink(DataFlow::Node sink) { sink instanceof SpelExpressionEvaluationSink }
|
||||||
|
|
||||||
|
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||||
|
any(SpelExpressionInjectionAdditionalTaintStep c).step(node1, node2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tracks flow of unsafe user input that is used to construct and evaluate a SpEL expression. */
|
||||||
|
module SpelInjectionFlow = TaintTracking::Make<SpelInjectionConfig>;
|
||||||
|
|
||||||
/** Default sink for SpEL injection vulnerabilities. */
|
/** Default sink for SpEL injection vulnerabilities. */
|
||||||
private class DefaultSpelExpressionEvaluationSink extends SpelExpressionEvaluationSink {
|
private class DefaultSpelExpressionEvaluationSink extends SpelExpressionEvaluationSink {
|
||||||
DefaultSpelExpressionEvaluationSink() {
|
DefaultSpelExpressionEvaluationSink() {
|
||||||
exists(MethodAccess ma |
|
exists(MethodAccess ma |
|
||||||
ma.getMethod() instanceof ExpressionEvaluationMethod and
|
ma.getMethod() instanceof ExpressionEvaluationMethod and
|
||||||
ma.getQualifier() = this.asExpr() and
|
ma.getQualifier() = this.asExpr() and
|
||||||
not exists(SafeEvaluationContextFlowConfig config |
|
not SafeEvaluationContextFlow::hasFlowToExpr(ma.getArgument(0))
|
||||||
config.hasFlowTo(DataFlow::exprNode(ma.getArgument(0)))
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,21 +55,21 @@ private class DefaultSpelExpressionEvaluationSink extends SpelExpressionEvaluati
|
|||||||
/**
|
/**
|
||||||
* A configuration for safe evaluation context that may be used in expression evaluation.
|
* A configuration for safe evaluation context that may be used in expression evaluation.
|
||||||
*/
|
*/
|
||||||
private class SafeEvaluationContextFlowConfig extends DataFlow2::Configuration {
|
private module SafeEvaluationContextFlowConfig implements DataFlow::ConfigSig {
|
||||||
SafeEvaluationContextFlowConfig() { this = "SpelInjection::SafeEvaluationContextFlowConfig" }
|
predicate isSource(DataFlow::Node source) { source instanceof SafeContextSource }
|
||||||
|
|
||||||
override predicate isSource(DataFlow::Node source) { source instanceof SafeContextSource }
|
predicate isSink(DataFlow::Node sink) {
|
||||||
|
|
||||||
override predicate isSink(DataFlow::Node sink) {
|
|
||||||
exists(MethodAccess ma |
|
exists(MethodAccess ma |
|
||||||
ma.getMethod() instanceof ExpressionEvaluationMethod and
|
ma.getMethod() instanceof ExpressionEvaluationMethod and
|
||||||
ma.getArgument(0) = sink.asExpr()
|
ma.getArgument(0) = sink.asExpr()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override int fieldFlowBranchLimit() { result = 0 }
|
int fieldFlowBranchLimit() { result = 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private module SafeEvaluationContextFlow = DataFlow::Make<SafeEvaluationContextFlowConfig>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `ContextSource` that is safe from SpEL injection.
|
* A `ContextSource` that is safe from SpEL injection.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,9 +14,9 @@
|
|||||||
import java
|
import java
|
||||||
import semmle.code.java.security.SpelInjectionQuery
|
import semmle.code.java.security.SpelInjectionQuery
|
||||||
import semmle.code.java.dataflow.DataFlow
|
import semmle.code.java.dataflow.DataFlow
|
||||||
import DataFlow::PathGraph
|
import SpelInjectionFlow::PathGraph
|
||||||
|
|
||||||
from DataFlow::PathNode source, DataFlow::PathNode sink, SpelInjectionConfig conf
|
from SpelInjectionFlow::PathNode source, SpelInjectionFlow::PathNode sink
|
||||||
where conf.hasFlowPath(source, sink)
|
where SpelInjectionFlow::hasFlowPath(source, sink)
|
||||||
select sink.getNode(), source, sink, "SpEL expression depends on a $@.", source.getNode(),
|
select sink.getNode(), source, sink, "SpEL expression depends on a $@.", source.getNode(),
|
||||||
"user-provided value"
|
"user-provided value"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class HasSpelInjectionTest extends InlineExpectationsTest {
|
|||||||
|
|
||||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||||
tag = "hasSpelInjection" and
|
tag = "hasSpelInjection" and
|
||||||
exists(DataFlow::Node sink, SpelInjectionConfig conf | conf.hasFlowTo(sink) |
|
exists(DataFlow::Node sink | SpelInjectionFlow::hasFlowTo(sink) |
|
||||||
sink.getLocation() = location and
|
sink.getLocation() = location and
|
||||||
element = sink.toString() and
|
element = sink.toString() and
|
||||||
value = ""
|
value = ""
|
||||||
|
|||||||
Reference in New Issue
Block a user