@@ -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,32 @@ 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` 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
+
59
92
/**
60
93
* Holds if the additional step from `src` to `sink` should be included in all
61
94
* global taint flow configurations.
0 commit comments