Skip to content

Commit aa360c0

Browse files
authored
Merge pull request github#5413 from smowton/smowton/feature/infer-fluent-method-taint-flow
Add taint-preserving edges where a call also has a value-preserving edge
2 parents 53c3604 + 6d108c0 commit aa360c0

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ private import semmle.code.java.frameworks.spring.SpringController
1111
private import semmle.code.java.frameworks.spring.SpringHttp
1212
private import semmle.code.java.frameworks.Networking
1313
private import semmle.code.java.dataflow.ExternalFlow
14+
private import semmle.code.java.dataflow.internal.DataFlowPrivate
1415
import semmle.code.java.dataflow.FlowSteps
1516

1617
/**
@@ -41,6 +42,12 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) {
4142
* different objects.
4243
*/
4344
predicate localAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
45+
localAdditionalBasicTaintStep(src, sink)
46+
or
47+
composedValueAndTaintModelStep(src, sink)
48+
}
49+
50+
private predicate localAdditionalBasicTaintStep(DataFlow::Node src, DataFlow::Node sink) {
4451
localAdditionalTaintExprStep(src.asExpr(), sink.asExpr())
4552
or
4653
localAdditionalTaintUpdateStep(src.asExpr(),
@@ -56,6 +63,32 @@ predicate localAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
5663
)
5764
}
5865

66+
/**
67+
* Holds if an additional step from `src` to `sink` through a call can be inferred from the
68+
* combination of a value-preserving step providing an alias between an input and the output
69+
* and a taint step from `src` to one the aliased nodes. For example, if we know that `f(a, b)` returns
70+
* the exact value of `a` and also propagates taint from `b` to its result, then we also know that
71+
* `a` is tainted after `f` completes, and vice versa.
72+
*/
73+
private predicate composedValueAndTaintModelStep(ArgumentNode src, DataFlow::Node sink) {
74+
exists(Call call, ArgumentNode valueSource, DataFlow::PostUpdateNode valueSourcePost |
75+
src.argumentOf(call, _) and
76+
valueSource.argumentOf(call, _) and
77+
src != valueSource and
78+
valueSourcePost.getPreUpdateNode() = valueSource and
79+
DataFlow::localFlowStep(valueSource, DataFlow::exprNode(call)) and
80+
(
81+
// in-x -value-> out-y and in-z -taint-> out-y ==> in-z -taint-> in-x
82+
localAdditionalBasicTaintStep(src, DataFlow::exprNode(call)) and
83+
sink = valueSourcePost
84+
or
85+
// in-x -value-> out-y and in-z -taint-> in-x ==> in-z -taint-> out-y
86+
localAdditionalBasicTaintStep(src, valueSourcePost) and
87+
sink = DataFlow::exprNode(call)
88+
)
89+
)
90+
}
91+
5992
/**
6093
* Holds if the additional step from `src` to `sink` should be included in all
6194
* global taint flow configurations.

0 commit comments

Comments
 (0)