@@ -12,12 +12,12 @@ newtype TTaintTrackingContext =
1212
1313class TaintTrackingContext extends TTaintTrackingContext {
1414
15- string toString ( ) {
15+ string toString ( ) {
1616 this = TNoParam ( ) and result = ""
1717 or
1818 exists ( TaintKind param , AttributePath path , int n |
1919 this = TParamContext ( param , path , n ) and
20- result = "Parameter " + n .toString ( ) + "(" + path .toString ( ) + ") is " + param
20+ result = "p " + n .toString ( ) + path .extension ( ) + " = " + param
2121 )
2222 }
2323
@@ -74,7 +74,7 @@ private newtype TAttributePath =
7474 TNoAttribute ( )
7575 or
7676 TAttribute ( string name ) {
77- none ( )
77+ exists ( Attribute a | a . getName ( ) = name )
7878 }
7979 or
8080 TAttributeAttribute ( string name1 , string name2 ) {
@@ -114,15 +114,18 @@ class NoAttribute extends TNoAttribute, AttributePath {
114114
115115class NamedAttributePath extends TAttribute , AttributePath {
116116
117- override string toString ( ) {
117+ override string toString ( ) {
118118 exists ( string attr |
119119 this = TAttribute ( attr ) and
120120 result = "attribute " + attr
121121 )
122122 }
123123
124- override string extension ( ) {
125- this = TAttribute ( result )
124+ override string extension ( ) {
125+ exists ( string attr |
126+ this = TAttribute ( attr ) and
127+ result = "." + attr
128+ )
126129 }
127130
128131 override AttributePath fromAttribute ( string name ) {
@@ -140,7 +143,13 @@ newtype TTaintTrackingNode =
140143
141144class TaintTrackingNode extends TTaintTrackingNode {
142145
143- string toString ( ) { result = this .getTaintKind ( ) .repr ( ) }
146+ string toString ( ) {
147+ if this .getPath ( ) instanceof NoAttribute then (
148+ result = this .getTaintKind ( ) .repr ( )
149+ ) else (
150+ result = this .getPath ( ) .extension ( ) + " = " + this .getTaintKind ( ) .repr ( )
151+ )
152+ }
144153
145154 DataFlow:: Node getNode ( ) {
146155 this = TTaintTrackingNode_ ( result , _, _, _, _)
@@ -398,6 +407,8 @@ class TaintTrackingImplementation extends string {
398407 or
399408 this .essaFlowStep ( src , node , context , path , kind ) and edgeLabel = ""
400409 or
410+ this .instantionStep ( src , node , context , path , kind , edgeLabel )
411+ or
401412 this .legacyExtensionStep ( src , node , context , path , kind , edgeLabel )
402413 or
403414 exists ( DataFlow:: Node srcnode , TaintKind srckind |
@@ -425,11 +436,11 @@ class TaintTrackingImplementation extends string {
425436 pragma [ noinline]
426437 predicate importStep ( TaintTrackingNode src , DataFlow:: Node node , TaintTrackingContext context , AttributePath path , TaintKind kind , string edgeLabel ) {
427438 edgeLabel = "import" and
428- exists ( ModuleValue m , string name |
429- src = TTaintTrackingNode_ ( _, context , TNoAttribute ( ) , kind , this ) and
439+ exists ( ModuleValue m , string name , AttributePath srcpath |
440+ src = TTaintTrackingNode_ ( _, context , srcpath , kind , this ) and
430441 this .moduleAttributeTainted ( m , name , src ) and
431- node .asCfgNode ( ) .( ImportExprNode ) . pointsTo ( m ) and
432- path = TAttribute ( name )
442+ node .asCfgNode ( ) .pointsTo ( m ) and
443+ path = srcpath . getAttribute ( name )
433444 )
434445 }
435446
@@ -454,7 +465,8 @@ class TaintTrackingImplementation extends string {
454465 exists ( DataFlow:: Node srcnode , TaintKind srckind , string attrname |
455466 src = TTaintTrackingNode_ ( srcnode , context , path , srckind , this ) and
456467 srcnode .asCfgNode ( ) = node .asCfgNode ( ) .( AttrNode ) .getObject ( attrname ) and
457- kind = srckind .getTaintOfAttribute ( attrname ) and edgeLabel = "from taint attribute"
468+ kind = srckind .getTaintOfAttribute ( attrname ) and edgeLabel = "from taint attribute" and
469+ path instanceof NoAttribute
458470 )
459471 }
460472
@@ -498,16 +510,27 @@ class TaintTrackingImplementation extends string {
498510
499511 pragma [ noinline]
500512 predicate returnFlowStep ( TaintTrackingNode src , DataFlow:: Node node , TaintTrackingContext context , AttributePath path , TaintKind kind , string edgeLabel ) {
501- exists ( CallNode call , PythonFunctionObjectInternal pyfunc , int arg , TaintKind callerKind , DataFlow:: Node srcNode , AttributePath callerPath , TaintTrackingContext srcContext |
502- src = TTaintTrackingNode_ ( srcNode , srcContext , path , kind , this ) and
503- this .callWithTaintedArgument ( _, call , context , pyfunc , arg , callerPath , callerKind ) and
504- srcContext = TParamContext ( callerKind , callerPath , arg ) and
513+ exists ( CallNode call , PythonFunctionObjectInternal pyfunc , TaintTrackingContext callee , DataFlow:: Node retval |
514+ this .callContexts ( call , pyfunc , context , callee ) and
515+ src = TTaintTrackingNode_ ( retval , callee , path , kind , this ) and
505516 node .asCfgNode ( ) = call and
506- srcNode .asCfgNode ( ) = any ( Return ret | ret .getScope ( ) = pyfunc .getScope ( ) ) .getValue ( ) .getAFlowNode ( )
517+ retval .asCfgNode ( ) = any ( Return ret | ret .getScope ( ) = pyfunc .getScope ( ) ) .getValue ( ) .getAFlowNode ( )
507518 ) and
508519 edgeLabel = "return"
509520 }
510521
522+ pragma [ noinline]
523+ predicate callContexts ( CallNode call , PythonFunctionObjectInternal pyfunc , TaintTrackingContext caller , TaintTrackingContext callee ) {
524+ exists ( int arg , TaintKind callerKind , AttributePath callerPath |
525+ this .callWithTaintedArgument ( _, call , caller , pyfunc , arg , callerPath , callerKind ) and
526+ callee = TParamContext ( callerKind , callerPath , arg )
527+ )
528+ or
529+ pyfunc .getACall ( ) = call and
530+ callee = TNoParam ( ) and
531+ caller = TNoParam ( )
532+ }
533+
511534 predicate callWithTaintedArgument ( TaintTrackingNode src , CallNode call , TaintTrackingContext caller , CallableValue pyfunc , int arg , AttributePath path , TaintKind kind ) {
512535 exists ( DataFlow:: Node srcnode |
513536 src = TTaintTrackingNode_ ( srcnode , caller , path , kind , this ) and
@@ -638,7 +661,7 @@ class TaintTrackingImplementation extends string {
638661 defn .getValue ( ) = srcnode .asCfgNode ( ) and
639662 defn .getName ( ) = attrname and
640663 path = srcpath .getAttribute ( attrname )
641- )
664+ )
642665 }
643666
644667 pragma [ noinline]
@@ -698,7 +721,6 @@ class TaintTrackingImplementation extends string {
698721 )
699722 }
700723
701-
702724 pragma [ noinline]
703725 predicate taintedExceptionCapture ( TaintTrackingNode src , ExceptionCapture defn , TaintTrackingContext context , AttributePath path , TaintKind kind ) {
704726 exists ( DataFlow:: Node srcnode |
@@ -717,6 +739,36 @@ class TaintTrackingImplementation extends string {
717739 )
718740 }
719741
742+ predicate instantionStep ( TaintTrackingNode src , DataFlow:: Node node , TaintTrackingContext context , AttributePath path , TaintKind kind , string edgeLabel ) {
743+ exists ( DataFlow:: Node srcnode , PythonFunctionValue init , EssaVariable self , TaintTrackingContext callee |
744+ instantionCall ( node .asCfgNode ( ) , init , context , callee ) and
745+ src = TTaintTrackingNode_ ( srcnode , callee , path , kind , this ) and
746+ srcnode .asVariable ( ) = self and
747+ self .getSourceVariable ( ) .( Variable ) .isSelf ( ) and
748+ BaseFlow:: reaches_exit ( self ) and
749+ self .getScope ( ) = init .getScope ( )
750+ ) and
751+ edgeLabel = "instantiation"
752+ }
753+
754+ predicate instantionCall ( CallNode call , PythonFunctionObjectInternal init , TaintTrackingContext caller , TaintTrackingContext callee ) {
755+ exists ( ClassValue cls |
756+ call .getFunction ( ) .pointsTo ( cls ) and
757+ cls .lookup ( "__init__" ) = init
758+ |
759+ exists ( int arg , TaintKind callerKind , AttributePath callerPath |
760+ exists ( TaintTrackingNode tainted , DataFlow:: Node argument |
761+ tainted = TTaintTrackingNode_ ( argument , caller , callerPath , callerKind , this ) and
762+ call .getArg ( arg - 1 ) = argument .asCfgNode ( ) and
763+ callee = TParamContext ( callerKind , callerPath , arg )
764+ )
765+ )
766+ or
767+ callee = TNoParam ( ) and
768+ caller = TNoParam ( )
769+ )
770+ }
771+
720772}
721773
722774/* Backwards compatibility with config-less taint-tracking */
0 commit comments