@@ -9,68 +9,74 @@ class RatpackPromise extends RefType {
99 }
1010}
1111
12- /**
13- * Taint flows from the qualifier to the first argument of the lambda passed to this method access.
14- * Eg. `tainted.map(stillTainted -> ..)`
15- */
16- abstract private class TaintFromQualifierToFunctionalArgumentMethodAccess extends MethodAccess { }
12+ abstract private class SimpleFluentLambdaMethod extends Method {
13+ SimpleFluentLambdaMethod ( ) { getNumberOfParameters ( ) = 1 }
1714
18- class RatpackPromiseMapMethod extends Method {
15+ /**
16+ * Holds if this lambda consumes taint from the quaifier when `arg` is tainted.
17+ * Eg. `tainted.map(stillTainted -> ..)`
18+ */
19+ abstract predicate consumesTaint ( int arg ) ;
20+
21+ /**
22+ * Holds if the lambda passed produces taint that taints the result of this method.
23+ * Eg. `var tainted = CompletableFuture.supplyAsync(() -> taint());`
24+ */
25+ predicate doesReturnTaint ( ) { none ( ) }
26+ }
27+
28+ class RatpackPromiseMapMethod extends SimpleFluentLambdaMethod {
1929 RatpackPromiseMapMethod ( ) {
2030 getDeclaringType ( ) instanceof RatpackPromise and
2131 hasName ( "map" )
2232 }
23- }
2433
25- class RatpackPromiseMapMethodAccess extends TaintFromQualifierToFunctionalArgumentMethodAccess {
26- RatpackPromiseMapMethodAccess ( ) { getMethod ( ) instanceof RatpackPromiseMapMethod }
34+ override predicate consumesTaint ( int arg ) { arg = 0 }
35+
36+ override predicate doesReturnTaint ( ) { any ( ) }
2737}
2838
29- class RatpackPromiseThenMethod extends Method {
39+ class RatpackPromiseThenMethod extends SimpleFluentLambdaMethod {
3040 RatpackPromiseThenMethod ( ) {
3141 getDeclaringType ( ) instanceof RatpackPromise and
3242 hasName ( "then" )
3343 }
34- }
3544
36- class RatpackPromiseThenMethodAccess extends TaintFromQualifierToFunctionalArgumentMethodAccess {
37- RatpackPromiseThenMethodAccess ( ) { getMethod ( ) instanceof RatpackPromiseThenMethod }
45+ override predicate consumesTaint ( int arg ) { arg = 0 }
3846}
3947
40- class RatpackPromiseNextMethod extends FluentMethod {
48+ class RatpackPromiseNextMethod extends FluentMethod , SimpleFluentLambdaMethod {
4149 RatpackPromiseNextMethod ( ) {
4250 getDeclaringType ( ) instanceof RatpackPromise and
4351 hasName ( "next" )
4452 }
45- }
4653
47- class RatpackPromiseNextMethodAccess extends TaintFromQualifierToFunctionalArgumentMethodAccess {
48- RatpackPromiseNextMethodAccess ( ) { getMethod ( ) instanceof RatpackPromiseNextMethod }
54+ override predicate consumesTaint ( int arg ) { arg = 0 }
4955}
5056
5157private class RatpackPromiseTaintPreservingCallable extends AdditionalTaintStep {
5258 override predicate step ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
53- stepFromFunctionalExpToPromise ( node1 , node2 ) or
54- stepFromPromiseToFunctionalArgument ( node1 , node2 )
59+ stepIntoLambda ( node1 , node2 ) or
60+ stepOutOfLambda ( node1 , node2 )
5561 }
5662
57- /**
58- * Tracks taint from return from lambda function to the outer `Promise`.
59- */
60- private predicate stepFromFunctionalExpToPromise ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
61- exists ( FunctionalExpr fe |
62- fe .asMethod ( ) .getBody ( ) .getAStmt ( ) .( ReturnStmt ) .getResult ( ) = node1 .asExpr ( ) and
63- node2 .asExpr ( ) .( RatpackPromiseMapMethodAccess ) .getArgument ( 0 ) = fe
63+ predicate stepIntoLambda ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
64+ exists ( MethodAccess ma , SimpleFluentLambdaMethod sflm , int arg |
65+ ma .getMethod ( ) = sflm and
66+ sflm .consumesTaint ( arg ) and
67+ node1 .asExpr ( ) = ma .getQualifier ( ) and
68+ ma .getArgument ( 0 ) .( FunctionalExpr ) .asMethod ( ) .getParameter ( arg ) = node2 .asParameter ( )
6469 )
6570 }
6671
67- /**
68- * Tracks taint from the previous `Promise` to the first argument of lambda passed to `map` or `then`.
69- */
70- private predicate stepFromPromiseToFunctionalArgument ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
71- exists ( TaintFromQualifierToFunctionalArgumentMethodAccess ma |
72- node1 .asExpr ( ) = ma .getQualifier ( ) and
73- ma .getArgument ( 0 ) .( FunctionalExpr ) .asMethod ( ) .getParameter ( 0 ) = node2 .asParameter ( )
72+ predicate stepOutOfLambda ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
73+ exists ( SimpleFluentLambdaMethod sflm , MethodAccess ma , FunctionalExpr fe |
74+ sflm .doesReturnTaint ( )
75+ |
76+ fe .asMethod ( ) .getBody ( ) .getAStmt ( ) .( ReturnStmt ) .getResult ( ) = node1 .asExpr ( ) and
77+ ma .getMethod ( ) = sflm and
78+ node2 .asExpr ( ) = ma and
79+ ma .getArgument ( 0 ) = fe
7480 )
7581 }
7682}
0 commit comments