@@ -166,60 +166,6 @@ private predicate inputStreamWrapper(Constructor c, int argi) {
166
166
/** An object construction that preserves the data flow status of any of its arguments. */
167
167
private predicate constructorStep ( Expr tracked , ConstructorCall sink ) {
168
168
exists ( int argi | sink .getArgument ( argi ) = tracked |
169
- exists ( string s | sink .getConstructedType ( ) .getQualifiedName ( ) = s |
170
- // some readers preserve the content of streams
171
- s = "java.io.InputStreamReader" and argi = 0
172
- or
173
- s = "java.io.BufferedReader" and argi = 0
174
- or
175
- s = "java.io.CharArrayReader" and argi = 0
176
- or
177
- s = "java.io.StringReader" and argi = 0
178
- or
179
- // data preserved through streams
180
- s = "java.io.ObjectInputStream" and argi = 0
181
- or
182
- s = "java.io.ByteArrayInputStream" and argi = 0
183
- or
184
- s = "java.io.DataInputStream" and argi = 0
185
- or
186
- s = "java.io.BufferedInputStream" and argi = 0
187
- or
188
- s = "com.esotericsoftware.kryo.io.Input" and argi = 0
189
- or
190
- s = "java.beans.XMLDecoder" and argi = 0
191
- or
192
- // a tokenizer preserves the content of a string
193
- s = "java.util.StringTokenizer" and argi = 0
194
- or
195
- // unzipping the stream preserves content
196
- s = "java.util.zip.ZipInputStream" and argi = 0
197
- or
198
- s = "java.util.zip.GZIPInputStream" and argi = 0
199
- or
200
- // a cookie with tainted ingredients is tainted
201
- s = "javax.servlet.http.Cookie" and argi = 0
202
- or
203
- s = "javax.servlet.http.Cookie" and argi = 1
204
- or
205
- // various xml stream source constructors.
206
- s = "org.xml.sax.InputSource" and argi = 0
207
- or
208
- s = "javax.xml.transform.sax.SAXSource" and argi = 0 and sink .getNumArgument ( ) = 1
209
- or
210
- s = "javax.xml.transform.sax.SAXSource" and argi = 1 and sink .getNumArgument ( ) = 2
211
- or
212
- s = "javax.xml.transform.stream.StreamSource" and argi = 0
213
- or
214
- //a URI constructed from a tainted string is tainted.
215
- s = "java.net.URI" and argi = 0 and sink .getNumArgument ( ) = 1
216
- or
217
- //a File constructed from a tainted string is tainted.
218
- s = "java.io.File" and argi = 0
219
- or
220
- s = "java.io.File" and argi = 1
221
- )
222
- or
223
169
// wrappers constructed by extension
224
170
exists ( Constructor c , Parameter p , SuperConstructorInvocationStmt sup |
225
171
c = sink .getConstructor ( ) and
@@ -267,32 +213,12 @@ private int argToParam(Call call, int arg) {
267
213
/** Access to a method that passes taint from qualifier to argument. */
268
214
private predicate qualifierToArgumentStep ( Expr tracked , Expr sink ) {
269
215
exists ( MethodAccess ma , int arg |
270
- taintPreservingQualifierToArgument ( ma .getMethod ( ) , argToParam ( ma , arg ) ) and
216
+ ma .getMethod ( ) . ( TaintPreservingCallable ) . transfersTaint ( - 1 , argToParam ( ma , arg ) ) and
271
217
tracked = ma .getQualifier ( ) and
272
218
sink = ma .getArgument ( arg )
273
219
)
274
220
}
275
221
276
- /** Methods that passes tainted data from qualifier to argument. */
277
- private predicate taintPreservingQualifierToArgument ( Method m , int arg ) {
278
- m .getDeclaringType ( ) .hasQualifiedName ( "java.io" , "ByteArrayOutputStream" ) and
279
- m .hasName ( "writeTo" ) and
280
- arg = 0
281
- or
282
- exists ( Method read |
283
- m .overrides * ( read ) and
284
- read .getDeclaringType ( ) .hasQualifiedName ( "java.io" , "InputStream" ) and
285
- read .hasName ( "read" ) and
286
- arg = 0
287
- )
288
- or
289
- m .getDeclaringType ( ) .getASupertype * ( ) .hasQualifiedName ( "java.io" , "Reader" ) and
290
- m .hasName ( "read" ) and
291
- arg = 0
292
- or
293
- m .( TaintPreservingCallable ) .transfersTaint ( - 1 , arg )
294
- }
295
-
296
222
/** Access to a method that passes taint from the qualifier. */
297
223
private predicate qualifierToMethodStep ( Expr tracked , MethodAccess sink ) {
298
224
( taintPreservingQualifierToMethod ( sink .getMethod ( ) ) or unsafeEscape ( sink ) ) and
@@ -305,50 +231,16 @@ private predicate qualifierToMethodStep(Expr tracked, MethodAccess sink) {
305
231
private predicate taintPreservingQualifierToMethod ( Method m ) {
306
232
m instanceof CloneMethod
307
233
or
308
- m .getDeclaringType ( ) .getASupertype * ( ) .hasQualifiedName ( "java.io" , "Reader" ) and
309
- (
310
- m .getName ( ) = "read" and m .getNumberOfParameters ( ) = 0
311
- or
312
- m .getName ( ) = "readLine"
313
- )
314
- or
315
234
m .getDeclaringType ( ) .getQualifiedName ( ) .matches ( "%StringWriter" ) and
316
235
(
317
236
m .getName ( ) = "getBuffer"
318
237
or
319
238
m .getName ( ) = "toString"
320
239
)
321
240
or
322
- m .getDeclaringType ( ) .hasQualifiedName ( "java.util" , "StringTokenizer" ) and
323
- m .getName ( ) .matches ( "next%" )
324
- or
325
- m .getDeclaringType ( ) .hasQualifiedName ( "java.io" , "ByteArrayOutputStream" ) and
326
- ( m .getName ( ) = "toByteArray" or m .getName ( ) = "toString" )
327
- or
328
241
m .getDeclaringType ( ) .hasQualifiedName ( "java.io" , "ObjectInputStream" ) and
329
242
m .getName ( ) .matches ( "read%" )
330
243
or
331
- m .getDeclaringType ( ) .hasQualifiedName ( "javax.xml.transform.sax" , "SAXSource" ) and
332
- m .hasName ( "getInputSource" )
333
- or
334
- m .getDeclaringType ( ) .hasQualifiedName ( "javax.xml.transform.stream" , "StreamSource" ) and
335
- m .hasName ( "getInputStream" )
336
- or
337
- m .getDeclaringType ( ) .hasQualifiedName ( "java.nio" , "ByteBuffer" ) and
338
- m .hasName ( "get" )
339
- or
340
- m .getDeclaringType ( ) instanceof TypeFile and
341
- m .hasName ( "toPath" )
342
- or
343
- m .getDeclaringType ( ) instanceof TypePath and
344
- m .hasName ( "toFile" )
345
- or
346
- m .getDeclaringType ( ) instanceof TypeFile and
347
- m .hasName ( "toURI" )
348
- or
349
- m .getDeclaringType ( ) instanceof TypeUri and
350
- m .hasName ( "toURL" )
351
- or
352
244
m instanceof GetterMethod and
353
245
m .getDeclaringType ( ) .getASubtype * ( ) instanceof SpringUntrustedDataType and
354
246
not m .getDeclaringType ( ) instanceof TypeObject
@@ -421,69 +313,13 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
421
313
* `arg`th argument is tainted.
422
314
*/
423
315
private predicate taintPreservingArgumentToMethod ( Method method , int arg ) {
424
- (
425
- method .getDeclaringType ( ) .hasQualifiedName ( "java.util" , "Base64$Encoder" ) or
426
- method .getDeclaringType ( ) .hasQualifiedName ( "java.util" , "Base64$Decoder" ) or
427
- method
428
- .getDeclaringType ( )
429
- .getASupertype * ( )
430
- .hasQualifiedName ( "org.apache.commons.codec" , "Encoder" ) or
431
- method
432
- .getDeclaringType ( )
433
- .getASupertype * ( )
434
- .hasQualifiedName ( "org.apache.commons.codec" , "Decoder" )
435
- ) and
436
- (
437
- method .getName ( ) = "encode" and arg = 0 and method .getNumberOfParameters ( ) = 1
438
- or
439
- method .getName ( ) = "decode" and arg = 0 and method .getNumberOfParameters ( ) = 1
440
- or
441
- method .getName ( ) = "encodeToString" and arg = 0
442
- or
443
- method .getName ( ) = "wrap" and arg = 0
444
- )
445
- or
446
316
method .getDeclaringType ( ) .hasQualifiedName ( "org.apache.commons.codec.binary" , "Base64" ) and
447
317
(
448
318
method .getName ( ) = "decodeBase64" and arg = 0
449
319
or
450
320
method .getName ( ) .matches ( "encodeBase64%" ) and arg = 0
451
321
)
452
322
or
453
- method .getDeclaringType ( ) .hasQualifiedName ( "org.apache.commons.io" , "IOUtils" ) and
454
- (
455
- method .getName ( ) = "buffer" and arg = 0
456
- or
457
- method .getName ( ) = "readLines" and arg = 0
458
- or
459
- method .getName ( ) = "readFully" and arg = 0 and method .getParameterType ( 1 ) .hasName ( "int" )
460
- or
461
- method .getName ( ) = "toBufferedInputStream" and arg = 0
462
- or
463
- method .getName ( ) = "toBufferedReader" and arg = 0
464
- or
465
- method .getName ( ) = "toByteArray" and arg = 0
466
- or
467
- method .getName ( ) = "toCharArray" and arg = 0
468
- or
469
- method .getName ( ) = "toInputStream" and arg = 0
470
- or
471
- method .getName ( ) = "toString" and arg = 0
472
- )
473
- or
474
- method .getDeclaringType ( ) .hasQualifiedName ( "java.net" , "URLDecoder" ) and
475
- method .hasName ( "decode" ) and
476
- arg = 0
477
- or
478
- // A URI created from a tainted string is still tainted.
479
- method .getDeclaringType ( ) instanceof TypeUri and
480
- method .hasName ( "create" ) and
481
- arg = 0
482
- or
483
- method .getDeclaringType ( ) .hasQualifiedName ( "javax.xml.transform.sax" , "SAXSource" ) and
484
- method .hasName ( "sourceToInputSource" ) and
485
- arg = 0
486
- or
487
323
method .( TaintPreservingCallable ) .returnsTaintFrom ( arg )
488
324
}
489
325
@@ -493,48 +329,13 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) {
493
329
*/
494
330
private predicate argToArgStep ( Expr tracked , Expr sink ) {
495
331
exists ( MethodAccess ma , Method method , int input , int output |
496
- taintPreservingArgToArg ( method , argToParam ( ma , input ) , argToParam ( ma , output ) ) and
332
+ method . ( TaintPreservingCallable ) . transfersTaint ( argToParam ( ma , input ) , argToParam ( ma , output ) ) and
497
333
ma .getMethod ( ) = method and
498
334
ma .getArgument ( input ) = tracked and
499
335
ma .getArgument ( output ) = sink
500
336
)
501
337
}
502
338
503
- /**
504
- * Holds if `method` is a library method that writes tainted data to the
505
- * `output`th argument if the `input`th argument is tainted.
506
- */
507
- private predicate taintPreservingArgToArg ( Method method , int input , int output ) {
508
- method .getDeclaringType ( ) .hasQualifiedName ( "org.apache.commons.io" , "IOUtils" ) and
509
- (
510
- method .hasName ( "copy" ) and input = 0 and output = 1
511
- or
512
- method .hasName ( "copyLarge" ) and input = 0 and output = 1
513
- or
514
- method .hasName ( "read" ) and input = 0 and output = 1
515
- or
516
- method .hasName ( "readFully" ) and
517
- input = 0 and
518
- output = 1 and
519
- not method .getParameterType ( 1 ) .hasName ( "int" )
520
- or
521
- method .hasName ( "write" ) and input = 0 and output = 1
522
- or
523
- method .hasName ( "writeChunked" ) and input = 0 and output = 1
524
- or
525
- method .hasName ( "writeLines" ) and input = 0 and output = 2
526
- or
527
- method .hasName ( "writeLines" ) and input = 1 and output = 2
528
- )
529
- or
530
- method .getDeclaringType ( ) .hasQualifiedName ( "java.lang" , "System" ) and
531
- method .hasName ( "arraycopy" ) and
532
- input = 0 and
533
- output = 2
534
- or
535
- method .( TaintPreservingCallable ) .transfersTaint ( input , output )
536
- }
537
-
538
339
/**
539
340
* Holds if `tracked` is the argument of a method that transfers taint
540
341
* from the argument to the qualifier and `sink` is the qualifier.
0 commit comments