5
5
6
6
private import CaptureModelsSpecific
7
7
8
- class ActiveConfiguration extends Unit {
9
- predicate activateThroughFlowConfig ( ) { none ( ) }
10
-
11
- predicate activateFromSourceConfig ( ) { none ( ) }
12
-
13
- predicate activateToSinkConfig ( ) { none ( ) }
14
- }
15
-
16
8
class DataFlowTargetApi extends TargetApiSpecific {
17
9
DataFlowTargetApi ( ) { isRelevantForDataFlowModels ( this ) }
18
10
}
@@ -46,6 +38,20 @@ private predicate isRelevantContent(DataFlow::Content c) {
46
38
DataFlowPrivate:: containerContent ( c )
47
39
}
48
40
41
+ /**
42
+ * Gets the MaD string representation of the parameter node `p`.
43
+ */
44
+ string parameterNodeAsInput ( DataFlow:: ParameterNode p ) {
45
+ result = parameterAccess ( p .asParameter ( ) )
46
+ or
47
+ result = qualifierString ( ) and p instanceof InstanceParameterNode
48
+ }
49
+
50
+ /**
51
+ * Gets the MaD input string representation of `source`.
52
+ */
53
+ string asInputArgument ( DataFlow:: Node source ) { result = asInputArgumentSpecific ( source ) }
54
+
49
55
/**
50
56
* Gets the summary model for `api` with `input`, `output` and `kind`.
51
57
*/
@@ -111,61 +117,70 @@ string captureQualifierFlow(TargetApiSpecific api) {
111
117
112
118
private int accessPathLimit ( ) { result = 2 }
113
119
120
+ private newtype TTaintState =
121
+ TTaintRead ( int n ) { n in [ 0 .. accessPathLimit ( ) ] } or
122
+ TTaintStore ( int n ) { n in [ 1 .. accessPathLimit ( ) ] }
123
+
124
+ abstract private class TaintState extends TTaintState {
125
+ abstract string toString ( ) ;
126
+ }
127
+
114
128
/**
115
129
* A FlowState representing a tainted read.
116
130
*/
117
- private class TaintRead extends DataFlow :: FlowState {
131
+ private class TaintRead extends TaintState , TTaintRead {
118
132
private int step ;
119
133
120
- TaintRead ( ) { this = "TaintRead(" + step + ")" and step in [ 0 .. accessPathLimit ( ) ] }
134
+ TaintRead ( ) { this = TTaintRead ( step ) }
121
135
122
136
/**
123
137
* Gets the flow state step number.
124
138
*/
125
139
int getStep ( ) { result = step }
140
+
141
+ override string toString ( ) { result = "TaintRead(" + step + ")" }
126
142
}
127
143
128
144
/**
129
145
* A FlowState representing a tainted write.
130
146
*/
131
- private class TaintStore extends DataFlow :: FlowState {
147
+ private class TaintStore extends TaintState , TTaintStore {
132
148
private int step ;
133
149
134
- TaintStore ( ) { this = "TaintStore(" + step + ")" and step in [ 1 .. accessPathLimit ( ) ] }
150
+ TaintStore ( ) { this = TTaintStore ( step ) }
135
151
136
152
/**
137
153
* Gets the flow state step number.
138
154
*/
139
155
int getStep ( ) { result = step }
156
+
157
+ override string toString ( ) { result = "TaintStore(" + step + ")" }
140
158
}
141
159
142
160
/**
143
- * A TaintTracking Configuration used for tracking flow through APIs.
161
+ * A data-flow configuration for tracking flow through APIs.
144
162
* The sources are the parameters of an API and the sinks are the return values (excluding `this`) and parameters.
145
163
*
146
164
* This can be used to generate Flow summaries for APIs from parameter to return.
147
165
*/
148
- private class ThroughFlowConfig extends TaintTracking:: Configuration {
149
- ThroughFlowConfig ( ) {
150
- this = "ThroughFlowConfig" and any ( ActiveConfiguration ac ) .activateThroughFlowConfig ( )
151
- }
166
+ module ThroughFlowConfig implements DataFlow:: StateConfigSig {
167
+ class FlowState = TaintState ;
152
168
153
- override predicate isSource ( DataFlow:: Node source , DataFlow :: FlowState state ) {
169
+ predicate isSource ( DataFlow:: Node source , FlowState state ) {
154
170
source instanceof DataFlow:: ParameterNode and
155
171
source .getEnclosingCallable ( ) instanceof DataFlowTargetApi and
156
172
state .( TaintRead ) .getStep ( ) = 0
157
173
}
158
174
159
- override predicate isSink ( DataFlow:: Node sink , DataFlow :: FlowState state ) {
175
+ predicate isSink ( DataFlow:: Node sink , FlowState state ) {
160
176
sink instanceof DataFlowImplCommon:: ReturnNodeExt and
161
177
not isOwnInstanceAccessNode ( sink ) and
162
178
not exists ( captureQualifierFlow ( sink .asExpr ( ) .getEnclosingCallable ( ) ) ) and
163
179
( state instanceof TaintRead or state instanceof TaintStore )
164
180
}
165
181
166
- override predicate isAdditionalTaintStep (
167
- DataFlow:: Node node1 , DataFlow:: FlowState state1 , DataFlow:: Node node2 ,
168
- DataFlow:: FlowState state2
182
+ predicate isAdditionalFlowStep (
183
+ DataFlow:: Node node1 , FlowState state1 , DataFlow:: Node node2 , FlowState state2
169
184
) {
170
185
exists ( DataFlowImplCommon:: TypedContent tc |
171
186
DataFlowImplCommon:: store ( node1 , tc , node2 , _) and
@@ -184,24 +199,28 @@ private class ThroughFlowConfig extends TaintTracking::Configuration {
184
199
)
185
200
}
186
201
187
- override predicate isSanitizer ( DataFlow:: Node n ) {
202
+ predicate isBarrier ( DataFlow:: Node n ) {
188
203
exists ( Type t | t = n .getType ( ) and not isRelevantType ( t ) )
189
204
}
190
205
191
- override DataFlow:: FlowFeature getAFeature ( ) {
206
+ predicate isBarrier ( DataFlow:: Node node , FlowState state ) { none ( ) }
207
+
208
+ DataFlow:: FlowFeature getAFeature ( ) {
192
209
result instanceof DataFlow:: FeatureEqualSourceSinkCallContext
193
210
}
194
211
}
195
212
213
+ private module ThroughFlow = TaintTracking:: MakeWithState< ThroughFlowConfig > ;
214
+
196
215
/**
197
216
* Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter.
198
217
*/
199
218
string captureThroughFlow ( DataFlowTargetApi api ) {
200
219
exists (
201
- ThroughFlowConfig config , DataFlow:: ParameterNode p ,
202
- DataFlowImplCommon :: ReturnNodeExt returnNodeExt , string input , string output
220
+ DataFlow:: ParameterNode p , DataFlowImplCommon :: ReturnNodeExt returnNodeExt , string input ,
221
+ string output
203
222
|
204
- config . hasFlow ( p , returnNodeExt ) and
223
+ ThroughFlow :: hasFlow ( p , returnNodeExt ) and
205
224
returnNodeExt .getEnclosingCallable ( ) = api and
206
225
input = parameterNodeAsInput ( p ) and
207
226
output = returnNodeAsOutput ( returnNodeExt ) and
@@ -211,41 +230,37 @@ string captureThroughFlow(DataFlowTargetApi api) {
211
230
}
212
231
213
232
/**
214
- * A TaintTracking Configuration used for tracking flow through APIs .
233
+ * A dataflow configuration used for finding new sources .
215
234
* The sources are the already known existing sources and the sinks are the API return nodes.
216
235
*
217
236
* This can be used to generate Source summaries for an API, if the API expose an already known source
218
237
* via its return (then the API itself becomes a source).
219
238
*/
220
- private class FromSourceConfiguration extends TaintTracking:: Configuration {
221
- FromSourceConfiguration ( ) {
222
- this = "FromSourceConfiguration" and any ( ActiveConfiguration ac ) .activateFromSourceConfig ( )
223
- }
239
+ module FromSourceConfig implements DataFlow:: ConfigSig {
240
+ predicate isSource ( DataFlow:: Node source ) { ExternalFlow:: sourceNode ( source , _) }
224
241
225
- override predicate isSource ( DataFlow:: Node source ) { ExternalFlow:: sourceNode ( source , _) }
226
-
227
- override predicate isSink ( DataFlow:: Node sink ) {
242
+ predicate isSink ( DataFlow:: Node sink ) {
228
243
exists ( DataFlowTargetApi c |
229
244
sink instanceof DataFlowImplCommon:: ReturnNodeExt and
230
245
sink .getEnclosingCallable ( ) = c
231
246
)
232
247
}
233
248
234
- override DataFlow:: FlowFeature getAFeature ( ) {
235
- result instanceof DataFlow:: FeatureHasSinkCallContext
236
- }
249
+ DataFlow:: FlowFeature getAFeature ( ) { result instanceof DataFlow:: FeatureHasSinkCallContext }
237
250
238
- override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
251
+ predicate isAdditionalFlowStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
239
252
isRelevantTaintStep ( node1 , node2 )
240
253
}
241
254
}
242
255
256
+ private module FromSource = TaintTracking:: Make< FromSourceConfig > ;
257
+
243
258
/**
244
259
* Gets the source model(s) of `api`, if there is flow from an existing known source to the return of `api`.
245
260
*/
246
261
string captureSource ( DataFlowTargetApi api ) {
247
- exists ( DataFlow:: Node source , DataFlow:: Node sink , FromSourceConfiguration config , string kind |
248
- config . hasFlow ( source , sink ) and
262
+ exists ( DataFlow:: Node source , DataFlow:: Node sink , string kind |
263
+ FromSource :: hasFlow ( source , sink ) and
249
264
ExternalFlow:: sourceNode ( source , kind ) and
250
265
api = sink .getEnclosingCallable ( ) and
251
266
isRelevantSourceKind ( kind ) and
@@ -254,35 +269,30 @@ string captureSource(DataFlowTargetApi api) {
254
269
}
255
270
256
271
/**
257
- * A TaintTracking Configuration used for tracking flow through APIs .
272
+ * A dataflow configuration used for finding new sinks .
258
273
* The sources are the parameters of the API and the fields of the enclosing type.
259
274
*
260
275
* This can be used to generate Sink summaries for APIs, if the API propagates a parameter (or enclosing type field)
261
276
* into an existing known sink (then the API itself becomes a sink).
262
277
*/
263
- private class PropagateToSinkConfiguration extends TaintTracking:: Configuration {
264
- PropagateToSinkConfiguration ( ) {
265
- this = "parameters or fields flowing into sinks" and
266
- any ( ActiveConfiguration ac ) .activateToSinkConfig ( )
267
- }
278
+ module PropagateToSinkConfig implements DataFlow:: ConfigSig {
279
+ predicate isSource ( DataFlow:: Node source ) { apiSource ( source ) }
268
280
269
- override predicate isSource ( DataFlow:: Node source ) { apiSource ( source ) }
281
+ predicate isSink ( DataFlow:: Node sink ) { ExternalFlow :: sinkNode ( sink , _ ) }
270
282
271
- override predicate isSink ( DataFlow:: Node sink ) { ExternalFlow :: sinkNode ( sink , _ ) }
283
+ predicate isBarrier ( DataFlow:: Node node ) { sinkModelSanitizer ( node ) }
272
284
273
- override predicate isSanitizer ( DataFlow:: Node node ) { sinkModelSanitizer ( node ) }
274
-
275
- override DataFlow:: FlowFeature getAFeature ( ) {
276
- result instanceof DataFlow:: FeatureHasSourceCallContext
277
- }
285
+ DataFlow:: FlowFeature getAFeature ( ) { result instanceof DataFlow:: FeatureHasSourceCallContext }
278
286
}
279
287
288
+ private module PropagateToSink = TaintTracking:: Make< PropagateToSinkConfig > ;
289
+
280
290
/**
281
291
* Gets the sink model(s) of `api`, if there is flow from a parameter to an existing known sink.
282
292
*/
283
293
string captureSink ( DataFlowTargetApi api ) {
284
- exists ( DataFlow:: Node src , DataFlow:: Node sink , PropagateToSinkConfiguration config , string kind |
285
- config . hasFlow ( src , sink ) and
294
+ exists ( DataFlow:: Node src , DataFlow:: Node sink , string kind |
295
+ PropagateToSink :: hasFlow ( src , sink ) and
286
296
ExternalFlow:: sinkNode ( sink , kind ) and
287
297
api = src .getEnclosingCallable ( ) and
288
298
isRelevantSinkKind ( kind ) and
0 commit comments