@@ -125,13 +125,6 @@ abstract class TaintKind extends string {
125125 */
126126 predicate additionalFlowStepVar ( EssaVariable fromvar , EssaVariable tovar ) { none ( ) }
127127
128- /** Holds if this kind of taint can start from `expr`.
129- * In other words, is `expr` a source of this kind of taint.
130- */
131- final predicate startsFrom ( ControlFlowNode expr ) {
132- expr .( TaintSource ) .isSourceOf ( this , _)
133- }
134-
135128 /** Holds if this kind of taint "taints" `expr`.
136129 */
137130 final predicate taints ( ControlFlowNode expr ) {
@@ -318,6 +311,18 @@ abstract class Sanitizer extends string {
318311
319312}
320313
314+ /** Hold if `sanitizer` is valid. A sanitizer is valid if there is
315+ * a `TaintTracking::Configuration` that declares `sanitizer` or
316+ * there are no `TaintTracking::Configuration`s.
317+ */
318+ private predicate valid_sanitizer ( Sanitizer sanitizer ) {
319+ not exists ( TaintTracking:: Configuration c )
320+ or
321+ exists ( DataFlow:: Configuration c | c .isSanitizer ( sanitizer ) )
322+ or
323+ exists ( TaintTracking:: Configuration c | c .isSanitizer ( sanitizer ) )
324+ }
325+
321326/** DEPRECATED -- Use DataFlowExtension instead.
322327 * An extension to taint-flow. For adding library or framework specific flows.
323328 * Examples include flow from a request to untrusted part of that request or
@@ -584,12 +589,19 @@ private newtype TTaintedNode =
584589 n .( TaintSource ) .isSourceOf ( kind , context )
585590 )
586591 or
592+ exists ( DataFlow:: Configuration config , TaintKind kind |
593+ taint = TaintFlowImplementation:: TTrackedTaint ( kind ) and
594+ config .isSource ( n ) and context .getDepth ( ) = 0 and
595+ kind instanceof GenericFlowType
596+ )
597+ or
587598 TaintFlowImplementation:: step ( _, taint , context , n ) and
588599 exists ( TaintKind kind |
589600 kind = taint .( TaintFlowImplementation:: TrackedTaint ) .getKind ( )
590601 or
591602 kind = taint .( TaintFlowImplementation:: TrackedAttribute ) .getKind ( _) |
592603 not exists ( Sanitizer sanitizer |
604+ valid_sanitizer ( sanitizer ) and
593605 sanitizer .sanitizingNode ( kind , n )
594606 )
595607 )
@@ -839,26 +851,37 @@ library module TaintFlowImplementation {
839851 or
840852 call_taint_step ( fromnode , totaint , tocontext , tonode )
841853 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
854+ exists ( DataFlowNode fromnodenode |
855+ fromnodenode = fromnode .getNode ( ) and
856+ (
857+ not exists ( TaintTracking:: Configuration c )
858+ or
859+ exists ( DataFlow:: Configuration c | c .isExtension ( fromnodenode ) )
860+ or
861+ exists ( TaintTracking:: Configuration c | c .isExtension ( fromnodenode ) )
862+ )
863+ |
864+ fromnodenode .getASuccessorNode ( ) = tonode and
865+ fromnode .getContext ( ) = tocontext and
855866 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 ( )
867+ or
868+ exists ( CallNode call |
869+ fromnodenode .getAReturnSuccessorNode ( call ) = tonode and
870+ fromnode .getContext ( ) = tocontext .getCallee ( call ) and
871+ totaint = fromnode .getTrackedValue ( )
872+ )
873+ or
874+ exists ( CallNode call |
875+ fromnodenode .getACalleeSuccessorNode ( call ) = tonode and
876+ fromnode .getContext ( ) .getCallee ( call ) = tocontext and
877+ totaint = fromnode .getTrackedValue ( )
878+ )
879+ or
880+ exists ( TaintKind tokind |
881+ fromnodenode .getASuccessorNode ( fromnode .getTaintKind ( ) , tokind ) = tonode and
882+ totaint = fromnode .getTrackedValue ( ) .toKind ( tokind ) and
883+ tocontext = fromnode .getContext ( )
884+ )
862885 )
863886 or
864887 exists ( TaintKind tokind |
@@ -1038,8 +1061,18 @@ library module TaintFlowImplementation {
10381061 prev .( DataFlowVariable ) .getASuccessorVariable ( ) = var
10391062 )
10401063 or
1041- origin .getNode ( ) .( DataFlowNode ) .getASuccessorVariable ( ) = var and
1042- context = origin .getContext ( )
1064+ exists ( DataFlowNode originnode |
1065+ originnode = origin .getNode ( ) and
1066+ (
1067+ not exists ( TaintTracking:: Configuration c )
1068+ or
1069+ exists ( DataFlow:: Configuration c | c .isExtension ( originnode ) )
1070+ or
1071+ exists ( TaintTracking:: Configuration c | c .isExtension ( originnode ) )
1072+ ) and
1073+ originnode .getASuccessorVariable ( ) = var and
1074+ context = origin .getContext ( )
1075+ )
10431076 or
10441077 exists ( TrackedTaint taint , EssaVariable prev |
10451078 tainted_var ( prev , context , origin ) and
@@ -1062,6 +1095,7 @@ library module TaintFlowImplementation {
10621095 exists ( TaintKind kind |
10631096 kind = origin .getTaintKind ( ) and
10641097 not exists ( Sanitizer san |
1098+ valid_sanitizer ( san ) |
10651099 san .sanitizingDefinition ( kind , def )
10661100 or
10671101 san .sanitizingNode ( kind , def .( EssaNodeDefinition ) .getDefiningNode ( ) )
@@ -1184,6 +1218,7 @@ library module TaintFlowImplementation {
11841218 exists ( TaintKind kind |
11851219 kind = origin .getTaintKind ( ) |
11861220 not exists ( FunctionObject callee , Sanitizer sanitizer |
1221+ valid_sanitizer ( sanitizer ) and
11871222 callee .getACall ( ) = call .getCall ( ) and
11881223 sanitizer .sanitizingCall ( kind , callee )
11891224 )
@@ -1197,6 +1232,7 @@ library module TaintFlowImplementation {
11971232 var = test .getInput ( ) and
11981233 tainted_var ( var , context , origin ) and
11991234 not exists ( Sanitizer sanitizer |
1235+ valid_sanitizer ( sanitizer ) and
12001236 sanitizer .sanitizingEdge ( kind , test )
12011237 )
12021238 |
@@ -1246,6 +1282,7 @@ library module TaintFlowImplementation {
12461282 var = uniphi .getInput ( ) and
12471283 tainted_var ( var , context , origin ) and
12481284 not exists ( Sanitizer sanitizer |
1285+ valid_sanitizer ( sanitizer ) and
12491286 sanitizer .sanitizingSingleEdge ( kind , uniphi )
12501287 )
12511288 )
@@ -1438,6 +1475,109 @@ class CallContext extends TCallContext {
14381475
14391476}
14401477
1478+
1479+ /** Data flow module providing an interface compatible with
1480+ * the other language implementations.
1481+ */
1482+ module DataFlow {
1483+
1484+ class FlowType = TaintKind ;
1485+
1486+ /** Generic taint kind, source and sink classes for convenience and
1487+ * compatibility with other language libraries
1488+ */
1489+
1490+ class Node = ControlFlowNode ;
1491+
1492+ class PathNode = TaintedNode ;
1493+
1494+ class Extension = DataFlowExtension:: DataFlowNode ;
1495+
1496+ abstract class Configuration extends string {
1497+
1498+ bindingset [ this ]
1499+ Configuration ( ) { this = this }
1500+
1501+ abstract predicate isSource ( Node source ) ;
1502+
1503+ abstract predicate isSink ( Node sink ) ;
1504+
1505+ predicate isSanitizer ( Sanitizer sanitizer ) { none ( ) }
1506+
1507+ predicate isExtension ( Extension extension ) { none ( ) }
1508+
1509+ predicate hasFlowPath ( PathNode source , PathNode sink ) {
1510+ this .isSource ( source .getNode ( ) ) and
1511+ this .isSink ( sink .getNode ( ) ) and
1512+ source .getTaintKind ( ) instanceof GenericFlowType and
1513+ sink .getTaintKind ( ) instanceof GenericFlowType
1514+ }
1515+
1516+ predicate hasFlow ( Node source , Node sink ) {
1517+ exists ( PathNode psource , PathNode psink |
1518+ psource .getNode ( ) = source and
1519+ psink .getNode ( ) = sink and
1520+ this .isSource ( source ) and
1521+ this .isSink ( sink ) and
1522+ this .hasFlowPath ( psource , psink )
1523+ )
1524+ }
1525+
1526+ }
1527+
1528+ }
1529+
1530+ private class GenericFlowType extends DataFlow:: FlowType {
1531+
1532+ GenericFlowType ( ) {
1533+ this = "Generic taint kind" and
1534+ exists ( DataFlow:: Configuration c )
1535+ }
1536+
1537+ }
1538+
1539+ module TaintTracking {
1540+
1541+ class Source = TaintSource ;
1542+
1543+ class Sink = TaintSink ;
1544+
1545+ class PathSource = TaintedPathSource ;
1546+
1547+ class PathSink = TaintedPathSink ;
1548+
1549+ class Extension = DataFlowExtension:: DataFlowNode ;
1550+
1551+ abstract class Configuration extends string {
1552+
1553+ bindingset [ this ]
1554+ Configuration ( ) { this = this }
1555+
1556+ abstract predicate isSource ( Source source ) ;
1557+
1558+ abstract predicate isSink ( Sink sink ) ;
1559+
1560+ predicate isSanitizer ( Sanitizer sanitizer ) { none ( ) }
1561+
1562+ predicate isExtension ( Extension extension ) { none ( ) }
1563+
1564+ predicate hasFlowPath ( PathSource source , PathSink sink ) {
1565+ this .isSource ( source .getNode ( ) ) and
1566+ this .isSink ( sink .getNode ( ) ) and
1567+ source .flowsTo ( sink )
1568+ }
1569+
1570+ predicate hasFlow ( Source source , Sink sink ) {
1571+ this .isSource ( source ) and
1572+ this .isSink ( sink ) and
1573+ source .flowsToSink ( sink )
1574+ }
1575+
1576+ }
1577+
1578+ }
1579+
1580+
14411581pragma [ noinline]
14421582private predicate dict_construct ( ControlFlowNode itemnode , ControlFlowNode dictnode ) {
14431583 dictnode .( DictNode ) .getAValue ( ) = itemnode
0 commit comments