@@ -15,31 +15,82 @@ private class RatpackPromiseValueMethod extends Method, TaintPreservingCallable
15
15
override predicate returnsTaintFrom ( int arg ) { arg = 0 }
16
16
}
17
17
18
- abstract private class SimpleFluentLambdaMethod extends Method {
19
- SimpleFluentLambdaMethod ( ) { getNumberOfParameters ( ) = 1 }
20
-
18
+ abstract private class FluentLambdaMethod extends Method {
21
19
/**
22
- * Holds if this lambda consumes taint from the quaifier when `arg` is tainted.
20
+ * Holds if this lambda consumes taint from the quaifier when `lambdaArg`
21
+ * for `methodArg` is tainted.
23
22
* Eg. `tainted.map(stillTainted -> ..)`
24
23
*/
25
- abstract predicate consumesTaint ( int arg ) ;
24
+ abstract predicate consumesTaint ( int methodArg , int lambdaArg ) ;
26
25
27
26
/**
28
- * Holds if the lambda passed produces taint that taints the result of this method.
27
+ * Holds if the lambda passed at the given `arg` position produces taint
28
+ * that taints the result of this method.
29
29
* Eg. `var tainted = CompletableFuture.supplyAsync(() -> taint());`
30
30
*/
31
- predicate doesReturnTaint ( ) { none ( ) }
31
+ predicate doesReturnTaint ( int arg ) { none ( ) }
32
+ }
33
+
34
+ private class RatpackPromiseProviderethod extends Method , FluentLambdaMethod {
35
+ RatpackPromiseProviderethod ( ) { isStatic ( ) and hasName ( [ "flatten" , "sync" ] ) }
36
+
37
+ override predicate consumesTaint ( int methodArg , int lambdaArg ) { none ( ) }
38
+
39
+ override predicate doesReturnTaint ( int arg ) { arg = 0 }
40
+ }
41
+
42
+ abstract private class SimpleFluentLambdaMethod extends FluentLambdaMethod {
43
+ override predicate consumesTaint ( int methodArg , int lambdaArg ) {
44
+ methodArg = 0 and consumesTaint ( lambdaArg )
45
+ }
46
+
47
+ /**
48
+ * Holds if this lambda consumes taint from the quaifier when `arg` is tainted.
49
+ * Eg. `tainted.map(stillTainted -> ..)`
50
+ */
51
+ abstract predicate consumesTaint ( int lambdaArg ) ;
32
52
}
33
53
34
54
private class RatpackPromiseMapMethod extends SimpleFluentLambdaMethod {
35
55
RatpackPromiseMapMethod ( ) {
36
56
getDeclaringType ( ) instanceof RatpackPromise and
37
- hasName ( [ "map" , "flatMap" ] )
57
+ hasName ( [ "map" , "flatMap" , "blockingMap" ] )
38
58
}
39
59
40
- override predicate consumesTaint ( int arg ) { arg = 0 }
60
+ override predicate consumesTaint ( int lambdaArg ) { lambdaArg = 0 }
41
61
42
- override predicate doesReturnTaint ( ) { any ( ) }
62
+ override predicate doesReturnTaint ( int arg ) { arg = 0 }
63
+ }
64
+
65
+ /**
66
+ * Represents the `mapIf` and `flatMapIf` method.
67
+ *
68
+ * `<O> Promise<O> mapIf(Predicate<T> predicate, Function<T, O> onTrue, Function<T, O> onFalse)`
69
+ * `<O> Promise<O> flatMapIf(Predicate<T> predicate, Function<T, Promise<O>> onTrue, Function<T, Promise<O>> onFalse)`
70
+ */
71
+ private class RatpackPromiseMapIfMethod extends FluentLambdaMethod {
72
+ RatpackPromiseMapIfMethod ( ) {
73
+ getDeclaringType ( ) instanceof RatpackPromise and
74
+ hasName ( [ "mapIf" , "flatMapIf" ] ) and
75
+ getNumberOfParameters ( ) = 3
76
+ }
77
+
78
+ override predicate consumesTaint ( int methodArg , int lambdaArg ) {
79
+ methodArg = [ 1 , 2 , 3 ] and lambdaArg = 0
80
+ }
81
+
82
+ override predicate doesReturnTaint ( int arg ) { arg = [ 1 , 2 ] }
83
+ }
84
+
85
+ private class RatpackPromiseMapErrorMethod extends FluentLambdaMethod {
86
+ RatpackPromiseMapErrorMethod ( ) {
87
+ getDeclaringType ( ) instanceof RatpackPromise and
88
+ hasName ( [ "mapError" , "flatMapError" ] )
89
+ }
90
+
91
+ override predicate consumesTaint ( int methodArg , int lambdaArg ) { none ( ) }
92
+
93
+ override predicate doesReturnTaint ( int arg ) { arg = getNumberOfParameters ( ) - 1 }
43
94
}
44
95
45
96
private class RatpackPromiseThenMethod extends SimpleFluentLambdaMethod {
@@ -48,16 +99,29 @@ private class RatpackPromiseThenMethod extends SimpleFluentLambdaMethod {
48
99
hasName ( "then" )
49
100
}
50
101
51
- override predicate consumesTaint ( int arg ) { arg = 0 }
102
+ override predicate consumesTaint ( int lambdaArg ) { lambdaArg = 0 }
52
103
}
53
104
54
- private class RatpackPromiseNextMethod extends FluentMethod , SimpleFluentLambdaMethod {
55
- RatpackPromiseNextMethod ( ) {
105
+ private class RatpackPromiseFluentMethod extends FluentMethod , FluentLambdaMethod {
106
+ RatpackPromiseFluentMethod ( ) {
56
107
getDeclaringType ( ) instanceof RatpackPromise and
57
- hasName ( "next" )
108
+ not isStatic ( ) and
109
+ exists ( ParameterizedType t |
110
+ t instanceof RatpackPromise and
111
+ t = getDeclaringType ( ) and
112
+ t = getReturnType ( )
113
+ )
58
114
}
59
115
60
- override predicate consumesTaint ( int arg ) { arg = 0 }
116
+ override predicate consumesTaint ( int methodArg , int lambdaArg ) {
117
+ hasName ( [ "next" ] ) and methodArg = 0 and lambdaArg = 0
118
+ or
119
+ hasName ( [ "cacheIf" ] ) and methodArg = 0 and lambdaArg = 0
120
+ or
121
+ hasName ( [ "route" ] ) and methodArg = [ 0 , 1 ] and lambdaArg = 0
122
+ }
123
+
124
+ override predicate doesReturnTaint ( int arg ) { hasName ( [ "flatMapIf" ] ) and arg = 1 }
61
125
}
62
126
63
127
private class RatpackPromiseTaintPreservingStep extends AdditionalTaintStep {
@@ -70,10 +134,13 @@ private class RatpackPromiseTaintPreservingStep extends AdditionalTaintStep {
70
134
* Holds if the method access qualifier `node1` has dataflow to the functional expression parameter `node2`.
71
135
*/
72
136
predicate stepIntoLambda ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
73
- exists ( MethodAccess ma , SimpleFluentLambdaMethod sflm , int arg | sflm .consumesTaint ( arg ) |
74
- ma .getMethod ( ) = sflm and
137
+ exists ( MethodAccess ma , FluentLambdaMethod flm , int methodArg , int lambdaArg |
138
+ flm .consumesTaint ( methodArg , lambdaArg )
139
+ |
140
+ ma .getMethod ( ) = flm and
75
141
node1 .asExpr ( ) = ma .getQualifier ( ) and
76
- ma .getArgument ( 0 ) .( FunctionalExpr ) .asMethod ( ) .getParameter ( arg ) = node2 .asParameter ( )
142
+ ma .getArgument ( methodArg ) .( FunctionalExpr ) .asMethod ( ) .getParameter ( lambdaArg ) =
143
+ node2 .asParameter ( )
77
144
)
78
145
}
79
146
@@ -82,13 +149,13 @@ private class RatpackPromiseTaintPreservingStep extends AdditionalTaintStep {
82
149
* method access result `node2`.
83
150
*/
84
151
predicate stepOutOfLambda ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
85
- exists ( SimpleFluentLambdaMethod sflm , MethodAccess ma , FunctionalExpr fe |
86
- sflm .doesReturnTaint ( )
152
+ exists ( FluentLambdaMethod flm , MethodAccess ma , FunctionalExpr fe , int arg |
153
+ flm .doesReturnTaint ( arg )
87
154
|
88
155
fe .asMethod ( ) .getBody ( ) .getAStmt ( ) .( ReturnStmt ) .getResult ( ) = node1 .asExpr ( ) and
89
- ma .getMethod ( ) = sflm and
156
+ ma .getMethod ( ) = flm and
90
157
node2 .asExpr ( ) = ma and
91
- ma .getArgument ( 0 ) = fe
158
+ ma .getArgument ( arg ) = fe
92
159
)
93
160
}
94
161
}
0 commit comments