@@ -318,6 +318,14 @@ abstract class Sanitizer extends string {
318318
319319}
320320
321+ /** Hold if `sanitizer` is valid. A sanitizer is valid if there is
322+ * a `TaintTracking::Configuration` that declares `sanitizer` or
323+ * there are no `TaintTracking::Configuration`s.
324+ */
325+ private predicate valid_sanitizer ( Sanitizer sanitizer ) {
326+ forall ( TaintTracking:: Configuration c | c .isSanitizer ( sanitizer ) )
327+ }
328+
321329/** DEPRECATED -- Use DataFlowExtension instead.
322330 * An extension to taint-flow. For adding library or framework specific flows.
323331 * Examples include flow from a request to untrusted part of that request or
@@ -590,6 +598,7 @@ private newtype TTaintedNode =
590598 or
591599 kind = taint .( TaintFlowImplementation:: TrackedAttribute ) .getKind ( _) |
592600 not exists ( Sanitizer sanitizer |
601+ valid_sanitizer ( sanitizer ) and
593602 sanitizer .sanitizingNode ( kind , n )
594603 )
595604 )
@@ -839,26 +848,31 @@ library module TaintFlowImplementation {
839848 or
840849 call_taint_step ( fromnode , totaint , tocontext , tonode )
841850 or
842- fromnode .getNode ( ) .( DataFlowNode ) .getASuccessorNode ( ) = tonode and
843- fromnode .getContext ( ) = tocontext and
844- totaint = fromnode .getTrackedValue ( )
845- or
846- exists ( CallNode call |
847- fromnode .getNode ( ) .( DataFlowNode ) .getAReturnSuccessorNode ( call ) = tonode and
848- fromnode .getContext ( ) = tocontext .getCallee ( call ) and
849- totaint = fromnode .getTrackedValue ( )
850- )
851- or
852- exists ( CallNode call |
853- fromnode .getNode ( ) .( DataFlowNode ) .getACalleeSuccessorNode ( call ) = tonode and
854- fromnode .getContext ( ) .getCallee ( call ) = tocontext and
851+ exists ( DataFlowNode fromnodenode |
852+ fromnodenode = fromnode .getNode ( ) and
853+ forall ( TaintTracking:: Configuration c | c .isExtension ( fromnodenode ) )
854+ |
855+ fromnodenode .getASuccessorNode ( ) = tonode and
856+ fromnode .getContext ( ) = tocontext and
855857 totaint = fromnode .getTrackedValue ( )
856- )
857- or
858- exists ( TaintKind tokind |
859- fromnode .getNode ( ) .( DataFlowNode ) .getASuccessorNode ( fromnode .getTaintKind ( ) , tokind ) = tonode and
860- totaint = fromnode .getTrackedValue ( ) .toKind ( tokind ) and
861- tocontext = fromnode .getContext ( )
858+ or
859+ exists ( CallNode call |
860+ fromnodenode .getAReturnSuccessorNode ( call ) = tonode and
861+ fromnode .getContext ( ) = tocontext .getCallee ( call ) and
862+ totaint = fromnode .getTrackedValue ( )
863+ )
864+ or
865+ exists ( CallNode call |
866+ fromnodenode .getACalleeSuccessorNode ( call ) = tonode and
867+ fromnode .getContext ( ) .getCallee ( call ) = tocontext and
868+ totaint = fromnode .getTrackedValue ( )
869+ )
870+ or
871+ exists ( TaintKind tokind |
872+ fromnodenode .getASuccessorNode ( fromnode .getTaintKind ( ) , tokind ) = tonode and
873+ totaint = fromnode .getTrackedValue ( ) .toKind ( tokind ) and
874+ tocontext = fromnode .getContext ( )
875+ )
862876 )
863877 or
864878 exists ( TaintKind tokind |
@@ -1038,8 +1052,12 @@ library module TaintFlowImplementation {
10381052 prev .( DataFlowVariable ) .getASuccessorVariable ( ) = var
10391053 )
10401054 or
1041- origin .getNode ( ) .( DataFlowNode ) .getASuccessorVariable ( ) = var and
1042- context = origin .getContext ( )
1055+ exists ( DataFlowNode originnode |
1056+ originnode = origin .getNode ( ) and
1057+ forall ( TaintTracking:: Configuration c | c .isExtension ( originnode ) ) and
1058+ originnode .getASuccessorVariable ( ) = var and
1059+ context = origin .getContext ( )
1060+ )
10431061 or
10441062 exists ( TrackedTaint taint , EssaVariable prev |
10451063 tainted_var ( prev , context , origin ) and
@@ -1062,6 +1080,7 @@ library module TaintFlowImplementation {
10621080 exists ( TaintKind kind |
10631081 kind = origin .getTaintKind ( ) and
10641082 not exists ( Sanitizer san |
1083+ valid_sanitizer ( san ) |
10651084 san .sanitizingDefinition ( kind , def )
10661085 or
10671086 san .sanitizingNode ( kind , def .( EssaNodeDefinition ) .getDefiningNode ( ) )
@@ -1184,6 +1203,7 @@ library module TaintFlowImplementation {
11841203 exists ( TaintKind kind |
11851204 kind = origin .getTaintKind ( ) |
11861205 not exists ( FunctionObject callee , Sanitizer sanitizer |
1206+ valid_sanitizer ( sanitizer ) and
11871207 callee .getACall ( ) = call .getCall ( ) and
11881208 sanitizer .sanitizingCall ( kind , callee )
11891209 )
@@ -1197,6 +1217,7 @@ library module TaintFlowImplementation {
11971217 var = test .getInput ( ) and
11981218 tainted_var ( var , context , origin ) and
11991219 not exists ( Sanitizer sanitizer |
1220+ valid_sanitizer ( sanitizer ) and
12001221 sanitizer .sanitizingEdge ( kind , test )
12011222 )
12021223 |
@@ -1246,6 +1267,7 @@ library module TaintFlowImplementation {
12461267 var = uniphi .getInput ( ) and
12471268 tainted_var ( var , context , origin ) and
12481269 not exists ( Sanitizer sanitizer |
1270+ valid_sanitizer ( sanitizer ) and
12491271 sanitizer .sanitizingSingleEdge ( kind , uniphi )
12501272 )
12511273 )
@@ -1438,6 +1460,49 @@ class CallContext extends TCallContext {
14381460
14391461}
14401462
1463+
1464+ module TaintTracking {
1465+
1466+ class Source = TaintSource ;
1467+
1468+ class Sink = TaintSink ;
1469+
1470+ class PathSource = TaintedPathSource ;
1471+
1472+ class PathSink = TaintedPathSink ;
1473+
1474+ class Extension = DataFlowExtension:: DataFlowNode ;
1475+
1476+ abstract class Configuration extends string {
1477+
1478+ bindingset [ this ]
1479+ Configuration ( ) { this = this }
1480+
1481+ abstract predicate isSource ( Source source ) ;
1482+
1483+ abstract predicate isSink ( Sink sink ) ;
1484+
1485+ predicate isSanitizer ( Sanitizer sanitizer ) { none ( ) }
1486+
1487+ predicate isExtension ( Extension extension ) { none ( ) }
1488+
1489+ predicate hasFlowPath ( PathSource source , PathSink sink ) {
1490+ this .isSource ( source .getNode ( ) ) and
1491+ this .isSink ( sink .getNode ( ) ) and
1492+ source .flowsTo ( sink )
1493+ }
1494+
1495+ predicate hasFlow ( Source source , Sink sink ) {
1496+ this .isSource ( source ) and
1497+ this .isSink ( sink ) and
1498+ source .flowsToSink ( sink )
1499+ }
1500+
1501+ }
1502+
1503+ }
1504+
1505+
14411506pragma [ noinline]
14421507private predicate dict_construct ( ControlFlowNode itemnode , ControlFlowNode dictnode ) {
14431508 dictnode .( DictNode ) .getAValue ( ) = itemnode
0 commit comments