mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Add taint-preserving edges where a call also has a value-preserving edge
For example, for a fluent method that returns `this`, we take a tainting edge from argX to either `this` or the return value to also taint the other.
This commit is contained in:
@@ -11,6 +11,7 @@ private import semmle.code.java.frameworks.spring.SpringController
|
||||
private import semmle.code.java.frameworks.spring.SpringHttp
|
||||
private import semmle.code.java.frameworks.Networking
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
private import semmle.code.java.dataflow.internal.DataFlowPrivate
|
||||
import semmle.code.java.dataflow.FlowSteps
|
||||
|
||||
/**
|
||||
@@ -41,6 +42,12 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
||||
* different objects.
|
||||
*/
|
||||
predicate localAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
||||
localAdditionalBasicTaintStep(src, sink)
|
||||
or
|
||||
composedValueAndTaintModelStep(src, sink)
|
||||
}
|
||||
|
||||
private predicate localAdditionalBasicTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
||||
localAdditionalTaintExprStep(src.asExpr(), sink.asExpr())
|
||||
or
|
||||
localAdditionalTaintUpdateStep(src.asExpr(),
|
||||
@@ -56,6 +63,31 @@ predicate localAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if an additional step from `src` to `sink` can be inferred from a value-preserving step
|
||||
* across a method callsite (from input to input, or input to result) and a taint-preserving step
|
||||
* across the same callsite from a different input. For example, if we know that `f(a, b)` returns
|
||||
* the exact value of `a` and also propagates taint from `b` to its result, then we also know that
|
||||
* `a` is tainted after `f` completes, and vice versa.
|
||||
*/
|
||||
private predicate composedValueAndTaintModelStep(ArgumentNode src, DataFlow::Node sink) {
|
||||
exists(Call call, ArgumentNode valueSource, DataFlow::PostUpdateNode valueSourcePun |
|
||||
src.argumentOf(call, _) and
|
||||
valueSource.argumentOf(call, _) and
|
||||
valueSourcePun.getPreUpdateNode() = valueSource and
|
||||
DataFlow::localFlowStep(valueSource, DataFlow::exprNode(call)) and
|
||||
(
|
||||
// in-x -value-> out-y and in-z -taint-> out-y ==> in-z -taint-> in-x
|
||||
localAdditionalBasicTaintStep(src, DataFlow::exprNode(call)) and
|
||||
sink = valueSourcePun
|
||||
or
|
||||
// in-x -value-> out-y and in-z -taint-> in-x ==> in-z -taint-> out-y
|
||||
localAdditionalBasicTaintStep(src, valueSourcePun) and
|
||||
sink = DataFlow::exprNode(call)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the additional step from `src` to `sink` should be included in all
|
||||
* global taint flow configurations.
|
||||
|
||||
Reference in New Issue
Block a user