@@ -159,6 +159,44 @@ private predicate taintPreservingArgumentToQualifier(Method method, int arg) {
159
159
method .( CollectionMethod ) .hasName ( "offer" ) and arg = 0
160
160
}
161
161
162
+ /**
163
+ * Holds if `method` is a library method that returns tainted data if its
164
+ * `arg`th argument is tainted.
165
+ */
166
+ private predicate taintPreservingArgumentToMethod ( Method method , int arg ) {
167
+ method .getDeclaringType ( ) .hasQualifiedName ( "java.util" , "Collections" ) and
168
+ (
169
+ method
170
+ .hasName ( [ "checkedCollection" , "checkedList" , "checkedMap" , "checkedNavigableMap" ,
171
+ "checkedNavigableSet" , "checkedSet" , "checkedSortedMap" , "checkedSortedSet" ,
172
+ "enumeration" , "list" , "max" , "min" , "singleton" , "singletonList" ,
173
+ "synchronizedCollection" , "synchronizedList" , "synchronizedMap" ,
174
+ "synchronizedNavigableMap" , "synchronizedNavigableSet" , "synchronizedSet" ,
175
+ "synchronizedSortedMap" , "synchronizedSortedSet" , "unmodifiableCollection" ,
176
+ "unmodifiableList" , "unmodifiableMap" , "unmodifiableNavigableMap" ,
177
+ "unmodifiableNavigableSet" , "unmodifiableSet" , "unmodifiableSortedMap" ,
178
+ "unmodifiableSortedSet" ] ) and
179
+ arg = 0
180
+ or
181
+ method .hasName ( [ "nCopies" , "singletonMap" ] ) and arg = 1
182
+ )
183
+ }
184
+
185
+ /**
186
+ * Holds if `method` is a library method that writes tainted data to the
187
+ * `output`th argument if the `input`th argument is tainted.
188
+ */
189
+ private predicate taintPreservingArgToArg ( Method method , int input , int output ) {
190
+ method .getDeclaringType ( ) .hasQualifiedName ( "java.util" , "Collections" ) and
191
+ (
192
+ method .hasName ( [ "copy" , "fill" ] ) and
193
+ input = 1 and
194
+ output = 0
195
+ or
196
+ method .hasName ( "replaceAll" ) and input = 2 and output = 0
197
+ )
198
+ }
199
+
162
200
private predicate argToQualifierStep ( Expr tracked , Expr sink ) {
163
201
exists ( Method m , int i , MethodAccess ma |
164
202
taintPreservingArgumentToQualifier ( m , i ) and
@@ -168,13 +206,44 @@ private predicate argToQualifierStep(Expr tracked, Expr sink) {
168
206
)
169
207
}
170
208
209
+ /** Access to a method that passes taint from an argument. */
210
+ private predicate argToMethodStep ( Expr tracked , MethodAccess sink ) {
211
+ exists ( Method m , int i |
212
+ m = sink .getMethod ( ) and
213
+ taintPreservingArgumentToMethod ( m , i ) and
214
+ tracked = sink .getArgument ( i )
215
+ )
216
+ }
217
+
218
+ /**
219
+ * Holds if `tracked` and `sink` are arguments to a method that transfers taint
220
+ * between arguments.
221
+ */
222
+ private predicate argToArgStep ( Expr tracked , Expr sink ) {
223
+ exists ( MethodAccess ma , Method method , int input , int output |
224
+ ma .getMethod ( ) = method and
225
+ ma .getArgument ( input ) = tracked and
226
+ ma .getArgument ( output ) = sink and
227
+ (
228
+ taintPreservingArgToArg ( method , input , output )
229
+ or
230
+ method .getDeclaringType ( ) .hasQualifiedName ( "java.util" , "Collections" ) and
231
+ method .hasName ( "addAll" ) and
232
+ input >= 1 and
233
+ output = 0
234
+ )
235
+ )
236
+ }
237
+
171
238
/**
172
239
* Holds if the step from `n1` to `n2` is either extracting a value from a
173
240
* container, inserting a value into a container, or transforming one container
174
241
* to another. This is restricted to cases where `n2` is the returned value of
175
242
* a call.
176
243
*/
177
- predicate containerReturnValueStep ( Expr n1 , Expr n2 ) { qualifierToMethodStep ( n1 , n2 ) }
244
+ predicate containerReturnValueStep ( Expr n1 , Expr n2 ) {
245
+ qualifierToMethodStep ( n1 , n2 ) or argToMethodStep ( n1 , n2 )
246
+ }
178
247
179
248
/**
180
249
* Holds if the step from `n1` to `n2` is either extracting a value from a
@@ -183,7 +252,8 @@ predicate containerReturnValueStep(Expr n1, Expr n2) { qualifierToMethodStep(n1,
183
252
*/
184
253
predicate containerUpdateStep ( Expr n1 , Expr n2 ) {
185
254
qualifierToArgumentStep ( n1 , n2 ) or
186
- argToQualifierStep ( n1 , n2 )
255
+ argToQualifierStep ( n1 , n2 ) or
256
+ argToArgStep ( n1 , n2 )
187
257
}
188
258
189
259
/**
0 commit comments