@@ -189,25 +189,13 @@ class SequenceKind extends CollectionKind {
189189 }
190190
191191 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
202192 exists ( BinaryExprNode mod |
203193 mod = tonode and
204194 mod .getOp ( ) instanceof Mod and
205195 mod .getAnOperand ( ) = fromnode and
206196 result = this .getItem ( ) and
207197 result .getClass ( ) = theStrType ( )
208198 )
209- or
210- result = this and sequence_call ( fromnode , tonode )
211199 }
212200
213201 override TaintKind getTaintOfMethodResult ( string name ) {
@@ -220,26 +208,42 @@ class SequenceKind extends CollectionKind {
220208
221209}
222210
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 */
224232pragma [ 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 ) {
226234 sub .isLoad ( ) and
227235 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
232237}
233238
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
241244}
242245
246+
243247/** A taint kind representing a mapping of objects to kinds.
244248 * Typically a dict, but can include other mappings.
245249 */
@@ -255,20 +259,6 @@ class DictKind extends CollectionKind {
255259 result = valueKind
256260 }
257261
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-
272262 override TaintKind getTaintOfMethodResult ( string name ) {
273263 name = "get" and result = valueKind
274264 or
@@ -284,6 +274,24 @@ class DictKind extends CollectionKind {
284274}
285275
286276
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+
287295/** A type of sanitizer of untrusted data.
288296 * Examples include sanitizers for http responses, for DB access or for shell commands.
289297 * Usually a sanitizer can only sanitize data for one particular use.
@@ -890,6 +898,22 @@ library module TaintFlowImplementation {
890898 tocontext = fromnode .getContext ( )
891899 )
892900 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
893917 exists ( TaintFlow flow , TaintKind tokind |
894918 flow .additionalFlowStep ( fromnode .getNode ( ) , fromnode .getTaintKind ( ) , tonode , tokind ) and
895919 totaint = fromnode .getTrackedValue ( ) .toKind ( tokind ) and
0 commit comments