@@ -14,10 +14,7 @@ import ModelGeneratorUtils
14
14
15
15
string captureFlow ( TargetAPI api ) {
16
16
result = captureQualifierFlow ( api ) or
17
- result = captureParameterFlowToReturnValue ( api ) or
18
- result = captureFieldFlowIn ( api ) or
19
- result = captureParameterToParameterFlow ( api ) or
20
- result = captureFieldFlow ( api )
17
+ result = captureThroughFlow ( api )
21
18
}
22
19
23
20
/**
@@ -40,31 +37,63 @@ string captureQualifierFlow(TargetAPI api) {
40
37
result = asValueModel ( api , "Argument[-1]" , "ReturnValue" )
41
38
}
42
39
43
- class FieldToReturnConfig extends TaintTracking:: Configuration {
44
- FieldToReturnConfig ( ) { this = "FieldToReturnConfig" }
40
+ class TaintRead extends DataFlow:: FlowState {
41
+ TaintRead ( ) { this = "TaintRead" }
42
+ }
43
+
44
+ class TaintStore extends DataFlow:: FlowState {
45
+ TaintStore ( ) { this = "TaintStore" }
46
+ }
45
47
46
- override predicate isSource ( DataFlow:: Node source ) {
47
- source instanceof DataFlow:: InstanceParameterNode
48
+ class ThroughFlowConfig extends TaintTracking:: Configuration {
49
+ ThroughFlowConfig ( ) { this = "ThroughFlowConfig" }
50
+
51
+ override predicate isSource ( DataFlow:: Node source , DataFlow:: FlowState state ) {
52
+ source instanceof DataFlow:: ParameterNode and
53
+ source .getEnclosingCallable ( ) instanceof TargetAPI and
54
+ state instanceof TaintRead
48
55
}
49
56
50
- override predicate isSink ( DataFlow:: Node sink ) {
57
+ override predicate isSink ( DataFlow:: Node sink , DataFlow :: FlowState state ) {
51
58
sink instanceof ReturnNodeExt and
52
59
not sink .( ReturnNode ) .asExpr ( ) .( ThisAccess ) .isOwnInstanceAccess ( ) and
53
- not exists ( captureQualifierFlow ( sink .asExpr ( ) .getEnclosingCallable ( ) ) )
60
+ not exists ( captureQualifierFlow ( sink .asExpr ( ) .getEnclosingCallable ( ) ) ) and
61
+ ( state instanceof TaintRead or state instanceof TaintStore )
54
62
}
55
63
56
- override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
57
- isRelevantTaintStep ( node1 , node2 )
64
+ override predicate isAdditionalFlowStep (
65
+ DataFlow:: Node node1 , DataFlow:: FlowState state1 , DataFlow:: Node node2 ,
66
+ DataFlow:: FlowState state2
67
+ ) {
68
+ exists ( TypedContent tc |
69
+ store ( node1 , tc , node2 , _) and
70
+ isRelevantContent ( tc .getContent ( ) ) and
71
+ ( state1 instanceof TaintRead or state1 instanceof TaintStore ) and
72
+ state2 instanceof TaintStore
73
+ )
74
+ or
75
+ exists ( DataFlow:: Content c |
76
+ readStep ( node1 , c , node2 ) and
77
+ isRelevantContent ( c ) and
78
+ state1 instanceof TaintRead and
79
+ state2 instanceof TaintRead
80
+ )
58
81
}
59
82
83
+ override predicate isSanitizer ( DataFlow:: Node n ) { not isRelevantType ( n .getType ( ) ) }
84
+
60
85
override DataFlow:: FlowFeature getAFeature ( ) {
61
86
result instanceof DataFlow:: FeatureEqualSourceSinkCallContext
62
87
}
63
88
}
64
89
65
90
/**
66
- * Capture APIs that return tainted instance data.
67
- * Example of an API that returns tainted instance data:
91
+ * Capture APIs that transfer taint from an input parameter to an output return
92
+ * value or parameter.
93
+ * Allows a sequence of read steps followed by a sequence of store steps.
94
+ *
95
+ * Examples:
96
+ *
68
97
* ```
69
98
* public class Foo {
70
99
* private String tainted;
@@ -83,48 +112,7 @@ class FieldToReturnConfig extends TaintTracking::Configuration {
83
112
* p;Foo;true;returnsTainted;;Argument[-1];ReturnValue;taint
84
113
* p;Foo;true;putsTaintIntoParameter;(List);Argument[-1];Argument[0];taint
85
114
* ```
86
- */
87
- string captureFieldFlow ( TargetAPI api ) {
88
- exists ( FieldToReturnConfig config , ReturnNodeExt returnNodeExt |
89
- config .hasFlow ( _, returnNodeExt ) and
90
- returnNodeExt .getEnclosingCallable ( ) = api and
91
- not api .getDeclaringType ( ) instanceof EnumType and
92
- isRelevantType ( returnNodeExt .getType ( ) )
93
- |
94
- result = asTaintModel ( api , "Argument[-1]" , returnNodeAsOutput ( api , returnNodeExt ) )
95
- )
96
- }
97
-
98
- class ParameterToFieldConfig extends TaintTracking:: Configuration {
99
- ParameterToFieldConfig ( ) { this = "ParameterToFieldConfig" }
100
-
101
- override predicate isSource ( DataFlow:: Node source ) {
102
- source instanceof DataFlow:: ParameterNode and
103
- isRelevantType ( source .getType ( ) )
104
- }
105
-
106
- override predicate isSink ( DataFlow:: Node sink ) {
107
- thisAccess ( sink .( DataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) )
108
- }
109
-
110
- override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
111
- store ( node1 , _, node2 , _)
112
- }
113
-
114
- override DataFlow:: FlowFeature getAFeature ( ) {
115
- result instanceof DataFlow:: FeatureEqualSourceSinkCallContext
116
- }
117
- }
118
-
119
- private predicate thisAccess ( DataFlow:: Node n ) {
120
- n .asExpr ( ) .( InstanceAccess ) .isOwnInstanceAccess ( )
121
- or
122
- n .( DataFlow:: ImplicitInstanceAccess ) .getInstanceAccess ( ) instanceof OwnInstanceAccess
123
- }
124
-
125
- /**
126
- * Captures APIs that accept input and store them in a field.
127
- * Example:
115
+ *
128
116
* ```
129
117
* public class Foo {
130
118
* private String tainted;
@@ -134,96 +122,38 @@ private predicate thisAccess(DataFlow::Node n) {
134
122
* ```
135
123
* Captured Model:
136
124
* `p;Foo;true;doSomething;(String);Argument[0];Argument[-1];taint`
137
- */
138
- string captureFieldFlowIn ( TargetAPI api ) {
139
- exists ( DataFlow:: Node source , ParameterToFieldConfig config |
140
- config .hasFlow ( source , _) and
141
- source .asParameter ( ) .getCallable ( ) = api
142
- |
143
- result =
144
- asTaintModel ( api , "Argument[" + source .asParameter ( ) .getPosition ( ) + "]" , "Argument[-1]" )
145
- )
146
- }
147
-
148
- class ParameterToReturnValueTaintConfig extends TaintTracking:: Configuration {
149
- ParameterToReturnValueTaintConfig ( ) { this = "ParameterToReturnValueTaintConfig" }
150
-
151
- override predicate isSource ( DataFlow:: Node source ) {
152
- exists ( TargetAPI api |
153
- api = source .asParameter ( ) .getCallable ( ) and
154
- isRelevantType ( api .getReturnType ( ) ) and
155
- isRelevantType ( source .asParameter ( ) .getType ( ) )
156
- )
157
- }
158
-
159
- override predicate isSink ( DataFlow:: Node sink ) { sink instanceof ReturnNode }
160
-
161
- // consider store steps to track taint across objects to model factory methods returning tainted objects
162
- override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
163
- store ( node1 , _, node2 , _)
164
- }
165
-
166
- override DataFlow:: FlowFeature getAFeature ( ) {
167
- result instanceof DataFlow:: FeatureEqualSourceSinkCallContext
168
- }
169
- }
170
-
171
- predicate paramFlowToReturnValueExists ( Parameter p ) {
172
- exists ( ParameterToReturnValueTaintConfig config , ReturnStmt rtn |
173
- config .hasFlow ( DataFlow:: parameterNode ( p ) , DataFlow:: exprNode ( rtn .getResult ( ) ) )
174
- )
175
- }
176
-
177
- /**
178
- * Capture APIs that return (parts of) data passed in as a parameter.
179
- * Example:
125
+ *
180
126
* ```
181
127
* public class Foo {
182
- *
183
128
* public String returnData(String tainted) {
184
129
* return tainted.substring(0,10)
185
130
* }
186
131
* }
187
132
* ```
188
133
* Captured Model:
189
- * ```
190
- * p;Foo;true;returnData;;Argument[0];ReturnValue;taint
191
- * ```
192
- */
193
- string captureParameterFlowToReturnValue ( TargetAPI api ) {
194
- exists ( Parameter p |
195
- p = api .getAParameter ( ) and
196
- paramFlowToReturnValueExists ( p )
197
- |
198
- result = asTaintModel ( api , parameterAccess ( p ) , "ReturnValue" )
199
- )
200
- }
201
-
202
- /**
203
- * Capture APIs that pass tainted data from a parameter to a parameter.
204
- * Example:
134
+ * `p;Foo;true;returnData;;Argument[0];ReturnValue;taint`
135
+ *
205
136
* ```
206
137
* public class Foo {
207
- *
208
138
* public void addToList(String tainted, List<String> foo) {
209
139
* foo.add(tainted);
210
140
* }
211
141
* }
212
142
* ```
213
143
* Captured Model:
214
- * ```
215
- * p;Foo;true;addToList;;Argument[0];Argument[1];taint
216
- * ```
144
+ * `p;Foo;true;addToList;;Argument[0];Argument[1];taint`
217
145
*/
218
- string captureParameterToParameterFlow ( TargetAPI api ) {
219
- exists ( DataFlow:: ParameterNode source , DataFlow:: PostUpdateNode sink |
220
- source .getEnclosingCallable ( ) = api and
221
- sink .getPreUpdateNode ( ) .asExpr ( ) = api .getAParameter ( ) .getAnAccess ( ) and
222
- TaintTracking:: localTaint ( source , sink )
146
+ string captureThroughFlow ( TargetAPI api ) {
147
+ exists (
148
+ ThroughFlowConfig config , DataFlow:: ParameterNode p , ReturnNodeExt returnNodeExt , string input ,
149
+ string output
223
150
|
224
- result =
225
- asTaintModel ( api , parameterAccess ( source .asParameter ( ) ) ,
226
- parameterAccess ( sink .getPreUpdateNode ( ) .asExpr ( ) .( VarAccess ) .getVariable ( ) ) )
151
+ config .hasFlow ( p , returnNodeExt ) and
152
+ returnNodeExt .getEnclosingCallable ( ) = api and
153
+ input = parameterNodeAsInput ( p ) and
154
+ output = returnNodeAsOutput ( api , returnNodeExt ) and
155
+ input != output and
156
+ result = asTaintModel ( api , input , output )
227
157
)
228
158
}
229
159
0 commit comments