@@ -11,6 +11,7 @@ private import semmle.code.java.frameworks.spring.SpringController
11
11
private import semmle.code.java.frameworks.spring.SpringHttp
12
12
private import semmle.code.java.frameworks.Networking
13
13
private import semmle.code.java.dataflow.ExternalFlow
14
+ private import semmle.code.java.dataflow.internal.DataFlowPrivate
14
15
import semmle.code.java.dataflow.FlowSteps
15
16
16
17
/**
@@ -41,6 +42,12 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) {
41
42
* different objects.
42
43
*/
43
44
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 ) {
44
51
localAdditionalTaintExprStep ( src .asExpr ( ) , sink .asExpr ( ) )
45
52
or
46
53
localAdditionalTaintUpdateStep ( src .asExpr ( ) ,
@@ -56,6 +63,31 @@ predicate localAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
56
63
)
57
64
}
58
65
66
+ /**
67
+ * Holds if an additional step from `src` to `sink` can be inferred from a value-preserving step
68
+ * across a method callsite (from input to input, or input to result) and a taint-preserving step
69
+ * across the same callsite from a different input. 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 valueSourcePun |
75
+ src .argumentOf ( call , _) and
76
+ valueSource .argumentOf ( call , _) and
77
+ valueSourcePun .getPreUpdateNode ( ) = valueSource and
78
+ DataFlow:: localFlowStep ( valueSource , DataFlow:: exprNode ( call ) ) and
79
+ (
80
+ // in-x -value-> out-y and in-z -taint-> out-y ==> in-z -taint-> in-x
81
+ localAdditionalBasicTaintStep ( src , DataFlow:: exprNode ( call ) ) and
82
+ sink = valueSourcePun
83
+ or
84
+ // in-x -value-> out-y and in-z -taint-> in-x ==> in-z -taint-> out-y
85
+ localAdditionalBasicTaintStep ( src , valueSourcePun ) and
86
+ sink = DataFlow:: exprNode ( call )
87
+ )
88
+ )
89
+ }
90
+
59
91
/**
60
92
* Holds if the additional step from `src` to `sink` should be included in all
61
93
* global taint flow configurations.
0 commit comments