@@ -9,68 +9,74 @@ class RatpackPromise extends RefType {
9
9
}
10
10
}
11
11
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 }
17
14
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 {
19
29
RatpackPromiseMapMethod ( ) {
20
30
getDeclaringType ( ) instanceof RatpackPromise and
21
31
hasName ( "map" )
22
32
}
23
- }
24
33
25
- class RatpackPromiseMapMethodAccess extends TaintFromQualifierToFunctionalArgumentMethodAccess {
26
- RatpackPromiseMapMethodAccess ( ) { getMethod ( ) instanceof RatpackPromiseMapMethod }
34
+ override predicate consumesTaint ( int arg ) { arg = 0 }
35
+
36
+ override predicate doesReturnTaint ( ) { any ( ) }
27
37
}
28
38
29
- class RatpackPromiseThenMethod extends Method {
39
+ class RatpackPromiseThenMethod extends SimpleFluentLambdaMethod {
30
40
RatpackPromiseThenMethod ( ) {
31
41
getDeclaringType ( ) instanceof RatpackPromise and
32
42
hasName ( "then" )
33
43
}
34
- }
35
44
36
- class RatpackPromiseThenMethodAccess extends TaintFromQualifierToFunctionalArgumentMethodAccess {
37
- RatpackPromiseThenMethodAccess ( ) { getMethod ( ) instanceof RatpackPromiseThenMethod }
45
+ override predicate consumesTaint ( int arg ) { arg = 0 }
38
46
}
39
47
40
- class RatpackPromiseNextMethod extends FluentMethod {
48
+ class RatpackPromiseNextMethod extends FluentMethod , SimpleFluentLambdaMethod {
41
49
RatpackPromiseNextMethod ( ) {
42
50
getDeclaringType ( ) instanceof RatpackPromise and
43
51
hasName ( "next" )
44
52
}
45
- }
46
53
47
- class RatpackPromiseNextMethodAccess extends TaintFromQualifierToFunctionalArgumentMethodAccess {
48
- RatpackPromiseNextMethodAccess ( ) { getMethod ( ) instanceof RatpackPromiseNextMethod }
54
+ override predicate consumesTaint ( int arg ) { arg = 0 }
49
55
}
50
56
51
57
private class RatpackPromiseTaintPreservingCallable extends AdditionalTaintStep {
52
58
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 )
55
61
}
56
62
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 ( )
64
69
)
65
70
}
66
71
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
74
80
)
75
81
}
76
82
}
0 commit comments