@@ -398,74 +398,65 @@ module PromiseFlow {
398398}
399399
400400/**
401- * Holds if taint propagates from `pred` to `succ` through promises .
401+ * DEPRECATED. Use `TaintTracking::promiseStep` instead .
402402 */
403- predicate promiseTaintStep ( DataFlow:: Node pred , DataFlow:: Node succ ) {
404- // from `x` to `new Promise((res, rej) => res(x))`
405- pred = succ .( PromiseDefinition ) .getResolveParameter ( ) .getACall ( ) .getArgument ( 0 )
406- or
407- // from `x` to `Promise.resolve(x)`
408- pred = succ .( PromiseCreationCall ) .getValue ( ) and
409- not succ instanceof PromiseAllCreation
410- or
411- // from `arr` to `Promise.all(arr)`
412- pred = succ .( PromiseAllCreation ) .getArrayNode ( )
413- or
414- exists ( DataFlow:: MethodCallNode thn | thn .getMethodName ( ) = "then" |
415- // from `p` to `x` in `p.then(x => ...)`
416- pred = thn .getReceiver ( ) and
417- succ = thn .getCallback ( 0 ) .getParameter ( 0 )
403+ deprecated predicate promiseTaintStep = TaintTracking:: promiseStep / 2 ;
404+
405+ private class PromiseTaintStep extends TaintTracking:: SharedTaintStep {
406+ override predicate promiseStep ( DataFlow:: Node pred , DataFlow:: Node succ ) {
407+ // from `x` to `new Promise((res, rej) => res(x))`
408+ pred = succ .( PromiseDefinition ) .getResolveParameter ( ) .getACall ( ) .getArgument ( 0 )
418409 or
419- // from `v` to `p.then(x => return v)`
420- pred = thn .getCallback ( [ 0 .. 1 ] ) .getAReturn ( ) and
421- succ = thn
422- )
423- or
424- exists ( DataFlow:: MethodCallNode catch | catch .getMethodName ( ) = "catch" |
425- // from `p` to `p.catch(..)`
426- pred = catch .getReceiver ( ) and
427- succ = catch
410+ // from `x` to `Promise.resolve(x)`
411+ pred = succ .( PromiseCreationCall ) .getValue ( ) and
412+ not succ instanceof PromiseAllCreation
428413 or
429- // from `v` to `p.catch(x => return v)`
430- pred = catch .getCallback ( 0 ) .getAReturn ( ) and
431- succ = catch
432- )
433- or
434- // from `p` to `p.finally(..)`
435- exists ( DataFlow:: MethodCallNode finally | finally .getMethodName ( ) = "finally" |
436- pred = finally .getReceiver ( ) and
437- succ = finally
438- )
439- or
440- // from `x` to `await x`
441- exists ( AwaitExpr await |
442- pred .getEnclosingExpr ( ) = await .getOperand ( ) and
443- succ .getEnclosingExpr ( ) = await
444- )
445- or
446- exists ( DataFlow:: CallNode mapSeries |
447- mapSeries = DataFlow:: moduleMember ( "bluebird" , "mapSeries" ) .getACall ( )
448- |
449- // from `xs` to `x` in `require("bluebird").mapSeries(xs, (x) => {...})`.
450- pred = mapSeries .getArgument ( 0 ) and
451- succ = mapSeries .getABoundCallbackParameter ( 1 , 0 )
414+ // from `arr` to `Promise.all(arr)`
415+ pred = succ .( PromiseAllCreation ) .getArrayNode ( )
452416 or
453- // from `y` to `require("bluebird").mapSeries(x, x => y)`.
454- pred = mapSeries .getCallback ( 1 ) .getAReturn ( ) and
455- succ = mapSeries
456- )
457- }
458-
459- /**
460- * An additional taint step that involves promises.
461- */
462- private class PromiseTaintStep extends TaintTracking:: AdditionalTaintStep {
463- DataFlow:: Node source ;
464-
465- PromiseTaintStep ( ) { promiseTaintStep ( source , this ) }
466-
467- override predicate step ( DataFlow:: Node pred , DataFlow:: Node succ ) {
468- pred = source and succ = this
417+ exists ( DataFlow:: MethodCallNode thn | thn .getMethodName ( ) = "then" |
418+ // from `p` to `x` in `p.then(x => ...)`
419+ pred = thn .getReceiver ( ) and
420+ succ = thn .getCallback ( 0 ) .getParameter ( 0 )
421+ or
422+ // from `v` to `p.then(x => return v)`
423+ pred = thn .getCallback ( [ 0 .. 1 ] ) .getAReturn ( ) and
424+ succ = thn
425+ )
426+ or
427+ exists ( DataFlow:: MethodCallNode catch | catch .getMethodName ( ) = "catch" |
428+ // from `p` to `p.catch(..)`
429+ pred = catch .getReceiver ( ) and
430+ succ = catch
431+ or
432+ // from `v` to `p.catch(x => return v)`
433+ pred = catch .getCallback ( 0 ) .getAReturn ( ) and
434+ succ = catch
435+ )
436+ or
437+ // from `p` to `p.finally(..)`
438+ exists ( DataFlow:: MethodCallNode finally | finally .getMethodName ( ) = "finally" |
439+ pred = finally .getReceiver ( ) and
440+ succ = finally
441+ )
442+ or
443+ // from `x` to `await x`
444+ exists ( AwaitExpr await |
445+ pred .getEnclosingExpr ( ) = await .getOperand ( ) and
446+ succ .getEnclosingExpr ( ) = await
447+ )
448+ or
449+ exists ( DataFlow:: CallNode mapSeries |
450+ mapSeries = DataFlow:: moduleMember ( "bluebird" , "mapSeries" ) .getACall ( )
451+ |
452+ // from `xs` to `x` in `require("bluebird").mapSeries(xs, (x) => {...})`.
453+ pred = mapSeries .getArgument ( 0 ) and
454+ succ = mapSeries .getABoundCallbackParameter ( 1 , 0 )
455+ or
456+ // from `y` to `require("bluebird").mapSeries(x, x => y)`.
457+ pred = mapSeries .getCallback ( 1 ) .getAReturn ( ) and
458+ succ = mapSeries
459+ )
469460 }
470461}
471462
@@ -500,14 +491,13 @@ private module AsyncReturnSteps {
500491 /**
501492 * A data-flow step for ordinary return from an async function in a taint configuration.
502493 */
503- private class AsyncTaintReturn extends TaintTracking:: AdditionalTaintStep , DataFlow:: FunctionNode {
504- Function f ;
505-
506- AsyncTaintReturn ( ) { this .getFunction ( ) = f and f .isAsync ( ) }
507-
494+ private class AsyncTaintReturn extends TaintTracking:: SharedTaintStep {
508495 override predicate step ( DataFlow:: Node pred , DataFlow:: Node succ ) {
509- returnExpr ( f , pred , _) and
510- succ .( DataFlow:: FunctionReturnNode ) .getFunction ( ) = f
496+ exists ( Function f |
497+ f .isAsync ( ) and
498+ returnExpr ( f , pred , _) and
499+ succ .( DataFlow:: FunctionReturnNode ) .getFunction ( ) = f
500+ )
511501 }
512502 }
513503}
@@ -616,14 +606,12 @@ private module ClosurePromise {
616606 /**
617607 * Taint steps through closure promise methods.
618608 */
619- private class ClosurePromiseTaintStep extends TaintTracking:: AdditionalTaintStep {
620- DataFlow:: Node pred ;
621-
622- ClosurePromiseTaintStep ( ) {
609+ private class ClosurePromiseTaintStep extends TaintTracking:: SharedTaintStep {
610+ override predicate step ( DataFlow:: Node pred , DataFlow:: Node succ ) {
623611 // static methods in goog.Promise
624612 exists ( DataFlow:: CallNode call , string name |
625613 call = Closure:: moduleImport ( "goog.Promise." + name ) .getACall ( ) and
626- this = call and
614+ succ = call and
627615 pred = call .getAnArgument ( )
628616 |
629617 name = "all" or
@@ -635,12 +623,10 @@ private module ClosurePromise {
635623 // promise created through goog.promise.withResolver()
636624 exists ( DataFlow:: CallNode resolver |
637625 resolver = Closure:: moduleImport ( "goog.Promise.withResolver" ) .getACall ( ) and
638- this = resolver .getAPropertyRead ( "promise" ) and
626+ succ = resolver .getAPropertyRead ( "promise" ) and
639627 pred = resolver .getAMethodCall ( "resolve" ) .getArgument ( 0 )
640628 )
641629 }
642-
643- override predicate step ( DataFlow:: Node src , DataFlow:: Node dst ) { src = pred and dst = this }
644630 }
645631}
646632
0 commit comments