@@ -189,25 +189,13 @@ class SequenceKind extends CollectionKind {
189
189
}
190
190
191
191
override TaintKind getTaintForFlowStep ( ControlFlowNode fromnode , ControlFlowNode tonode ) {
192
- sequence_subscript_taint ( tonode , fromnode , this , result )
193
- or
194
- result = this and
195
- (
196
- slice ( fromnode , tonode ) or
197
- tonode .( BinaryExprNode ) .getAnOperand ( ) = fromnode
198
- )
199
- or
200
- result = this and TaintFlowImplementation:: copyCall ( fromnode , tonode )
201
- or
202
192
exists ( BinaryExprNode mod |
203
193
mod = tonode and
204
194
mod .getOp ( ) instanceof Mod and
205
195
mod .getAnOperand ( ) = fromnode and
206
196
result = this .getItem ( ) and
207
197
result .getClass ( ) = theStrType ( )
208
198
)
209
- or
210
- result = this and sequence_call ( fromnode , tonode )
211
199
}
212
200
213
201
override TaintKind getTaintOfMethodResult ( string name ) {
@@ -220,26 +208,42 @@ class SequenceKind extends CollectionKind {
220
208
221
209
}
222
210
223
- /* Helper for getTaintForStep() */
211
+
212
+ module SequenceKind {
213
+
214
+ predicate flowStep ( ControlFlowNode fromnode , ControlFlowNode tonode ) {
215
+ tonode .( BinaryExprNode ) .getAnOperand ( ) = fromnode
216
+ or
217
+ TaintFlowImplementation:: copyCall ( fromnode , tonode )
218
+ or
219
+ sequence_call ( fromnode , tonode )
220
+ or
221
+ sequence_subscript_slice ( fromnode , tonode )
222
+ }
223
+
224
+ predicate itemFlowStep ( ControlFlowNode fromnode , ControlFlowNode tonode ) {
225
+ sequence_subscript_index ( fromnode , tonode )
226
+ }
227
+
228
+ }
229
+
230
+
231
+ /* Helper for sequence flow steps */
224
232
pragma [ noinline]
225
- private predicate sequence_subscript_taint ( SubscriptNode sub , ControlFlowNode obj , SequenceKind seq , TaintKind key ) {
233
+ private predicate sequence_subscript_index ( ControlFlowNode obj , SubscriptNode sub ) {
226
234
sub .isLoad ( ) and
227
235
sub .getValue ( ) = obj and
228
- if sub .getNode ( ) .getIndex ( ) instanceof Slice then
229
- seq = key
230
- else
231
- key = seq .getItem ( )
236
+ not sub .getNode ( ) .getIndex ( ) instanceof Slice
232
237
}
233
238
234
- /* tonode = fromnode[:] */
235
- private predicate slice ( ControlFlowNode fromnode , SubscriptNode tonode ) {
236
- exists ( Slice all |
237
- all = tonode .getIndex ( ) .getNode ( ) and
238
- not exists ( all .getStart ( ) ) and not exists ( all .getStop ( ) ) and
239
- tonode .getValue ( ) = fromnode
240
- )
239
+ pragma [ noinline]
240
+ private predicate sequence_subscript_slice ( ControlFlowNode obj , SubscriptNode sub ) {
241
+ sub .isLoad ( ) and
242
+ sub .getValue ( ) = obj and
243
+ sub .getNode ( ) .getIndex ( ) instanceof Slice
241
244
}
242
245
246
+
243
247
/** A taint kind representing a mapping of objects to kinds.
244
248
* Typically a dict, but can include other mappings.
245
249
*/
@@ -255,20 +259,6 @@ class DictKind extends CollectionKind {
255
259
result = valueKind
256
260
}
257
261
258
- override TaintKind getTaintForFlowStep ( ControlFlowNode fromnode , ControlFlowNode tonode ) {
259
- result = valueKind and
260
- tonode .( SubscriptNode ) .getValue ( ) = fromnode and tonode .isLoad ( )
261
- or
262
- result = valueKind and
263
- tonode .( CallNode ) .getFunction ( ) .( AttrNode ) .getObject ( "get" ) = fromnode
264
- or
265
- result = this and TaintFlowImplementation:: copyCall ( fromnode , tonode )
266
- or
267
- result = this and
268
- tonode .( CallNode ) .getFunction ( ) .refersTo ( theDictType ( ) ) and
269
- tonode .( CallNode ) .getArg ( 0 ) = fromnode
270
- }
271
-
272
262
override TaintKind getTaintOfMethodResult ( string name ) {
273
263
name = "get" and result = valueKind
274
264
or
@@ -284,6 +274,24 @@ class DictKind extends CollectionKind {
284
274
}
285
275
286
276
277
+ module DictKind {
278
+
279
+ predicate flowStep ( ControlFlowNode fromnode , ControlFlowNode tonode ) {
280
+ TaintFlowImplementation:: copyCall ( fromnode , tonode )
281
+ or
282
+ tonode .( CallNode ) .getFunction ( ) .refersTo ( theDictType ( ) ) and
283
+ tonode .( CallNode ) .getArg ( 0 ) = fromnode
284
+ }
285
+
286
+ predicate valueFlowStep ( ControlFlowNode fromnode , ControlFlowNode tonode ) {
287
+ tonode .( SubscriptNode ) .getValue ( ) = fromnode and tonode .isLoad ( )
288
+ or
289
+ tonode .( CallNode ) .getFunction ( ) .( AttrNode ) .getObject ( "get" ) = fromnode
290
+ }
291
+
292
+ }
293
+
294
+
287
295
/** A type of sanitizer of untrusted data.
288
296
* Examples include sanitizers for http responses, for DB access or for shell commands.
289
297
* Usually a sanitizer can only sanitize data for one particular use.
@@ -890,6 +898,22 @@ library module TaintFlowImplementation {
890
898
tocontext = fromnode .getContext ( )
891
899
)
892
900
or
901
+ exists ( SequenceKind fromkind |
902
+ fromkind = fromnode .getTaintKind ( ) and
903
+ tocontext = fromnode .getContext ( ) |
904
+ totaint = fromnode .getTrackedValue ( ) and SequenceKind:: flowStep ( fromnode .getNode ( ) , tonode )
905
+ or
906
+ totaint = fromnode .getTrackedValue ( ) .toKind ( fromkind .getItem ( ) ) and SequenceKind:: itemFlowStep ( fromnode .getNode ( ) , tonode )
907
+ )
908
+ or
909
+ exists ( DictKind fromkind |
910
+ fromkind = fromnode .getTaintKind ( ) and
911
+ tocontext = fromnode .getContext ( ) |
912
+ totaint = fromnode .getTrackedValue ( ) and DictKind:: flowStep ( fromnode .getNode ( ) , tonode )
913
+ or
914
+ totaint = fromnode .getTrackedValue ( ) .toKind ( fromkind .getValue ( ) ) and DictKind:: valueFlowStep ( fromnode .getNode ( ) , tonode )
915
+ )
916
+ or
893
917
exists ( TaintFlow flow , TaintKind tokind |
894
918
flow .additionalFlowStep ( fromnode .getNode ( ) , fromnode .getTaintKind ( ) , tonode , tokind ) and
895
919
totaint = fromnode .getTrackedValue ( ) .toKind ( tokind ) and
0 commit comments