@@ -166,60 +166,6 @@ private predicate inputStreamWrapper(Constructor c, int argi) {
166166/** An object construction that preserves the data flow status of any of its arguments. */
167167private predicate constructorStep ( Expr tracked , ConstructorCall sink ) {
168168 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
223169 // wrappers constructed by extension
224170 exists ( Constructor c , Parameter p , SuperConstructorInvocationStmt sup |
225171 c = sink .getConstructor ( ) and
@@ -267,32 +213,12 @@ private int argToParam(Call call, int arg) {
267213/** Access to a method that passes taint from qualifier to argument. */
268214private predicate qualifierToArgumentStep ( Expr tracked , Expr sink ) {
269215 exists ( MethodAccess ma , int arg |
270- taintPreservingQualifierToArgument ( ma .getMethod ( ) , argToParam ( ma , arg ) ) and
216+ ma .getMethod ( ) . ( TaintPreservingCallable ) . transfersTaint ( - 1 , argToParam ( ma , arg ) ) and
271217 tracked = ma .getQualifier ( ) and
272218 sink = ma .getArgument ( arg )
273219 )
274220}
275221
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-
296222/** Access to a method that passes taint from the qualifier. */
297223private predicate qualifierToMethodStep ( Expr tracked , MethodAccess sink ) {
298224 ( taintPreservingQualifierToMethod ( sink .getMethod ( ) ) or unsafeEscape ( sink ) ) and
@@ -305,50 +231,16 @@ private predicate qualifierToMethodStep(Expr tracked, MethodAccess sink) {
305231private predicate taintPreservingQualifierToMethod ( Method m ) {
306232 m instanceof CloneMethod
307233 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
315234 m .getDeclaringType ( ) .getQualifiedName ( ) .matches ( "%StringWriter" ) and
316235 (
317236 m .getName ( ) = "getBuffer"
318237 or
319238 m .getName ( ) = "toString"
320239 )
321240 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
328241 m .getDeclaringType ( ) .hasQualifiedName ( "java.io" , "ObjectInputStream" ) and
329242 m .getName ( ) .matches ( "read%" )
330243 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
352244 m instanceof GetterMethod and
353245 m .getDeclaringType ( ) .getASubtype * ( ) instanceof SpringUntrustedDataType and
354246 not m .getDeclaringType ( ) instanceof TypeObject
@@ -421,69 +313,13 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
421313 * `arg`th argument is tainted.
422314 */
423315private 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
446316 method .getDeclaringType ( ) .hasQualifiedName ( "org.apache.commons.codec.binary" , "Base64" ) and
447317 (
448318 method .getName ( ) = "decodeBase64" and arg = 0
449319 or
450320 method .getName ( ) .matches ( "encodeBase64%" ) and arg = 0
451321 )
452322 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
487323 method .( TaintPreservingCallable ) .returnsTaintFrom ( arg )
488324}
489325
@@ -493,48 +329,13 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) {
493329 */
494330private predicate argToArgStep ( Expr tracked , Expr sink ) {
495331 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
497333 ma .getMethod ( ) = method and
498334 ma .getArgument ( input ) = tracked and
499335 ma .getArgument ( output ) = sink
500336 )
501337}
502338
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-
538339/**
539340 * Holds if `tracked` is the argument of a method that transfers taint
540341 * from the argument to the qualifier and `sink` is the qualifier.
0 commit comments