@@ -100,6 +100,24 @@ abstract class TaintTransferringMethod extends Method {
100100 predicate transfersTaint ( int src , int sink ) { none ( ) }
101101}
102102
103+ private class StringTaintPreservingMethod extends TaintPreservingMethod {
104+ StringTaintPreservingMethod ( ) {
105+ getDeclaringType ( ) instanceof TypeString and
106+ hasName ( [ "concat" , "copyValueOf" , "endsWith" , "format" , "formatted" , "getBytes" , "indent" ,
107+ "intern" , "join" , "repeat" , "split" , "strip" , "stripIndent" , "stripLeading" ,
108+ "stripTrailing" , "substring" , "toCharArray" , "toLowerCase" , "toString" , "toUpperCase" ,
109+ "trim" ] )
110+ }
111+
112+ override predicate returnsTaint ( int arg ) {
113+ arg = - 1
114+ or
115+ this .hasName ( [ "concat" , "copyValueOf" ] ) and arg = 0
116+ or
117+ this .hasName ( [ "format" , "formatted" , "join" ] ) and arg = [ 0 .. getNumberOfParameters ( ) ]
118+ }
119+ }
120+
103121/**
104122 * Holds if `node` should be a sanitizer in all global taint flow configurations
105123 * but not in local taint.
@@ -338,21 +356,6 @@ private predicate qualifierToMethodStep(Expr tracked, MethodAccess sink) {
338356private predicate taintPreservingQualifierToMethod ( Method m ) {
339357 m instanceof CloneMethod
340358 or
341- m .getDeclaringType ( ) instanceof TypeString and
342- (
343- m .getName ( ) = "concat" or
344- m .getName ( ) = "endsWith" or
345- m .getName ( ) = "formatted" or
346- m .getName ( ) = "getBytes" or
347- m .getName ( ) = "split" or
348- m .getName ( ) = "substring" or
349- m .getName ( ) = "toCharArray" or
350- m .getName ( ) = "toLowerCase" or
351- m .getName ( ) = "toString" or
352- m .getName ( ) = "toUpperCase" or
353- m .getName ( ) = "trim"
354- )
355- or
356359 exists ( Class c | c .getQualifiedName ( ) = "java.lang.Number" | hasSubtype * ( c , m .getDeclaringType ( ) ) ) and
357360 (
358361 m .getName ( ) .matches ( "to%String" ) or
@@ -426,9 +429,6 @@ private predicate taintPreservingQualifierToMethod(Method m) {
426429 )
427430 )
428431 or
429- m .getDeclaringType ( ) instanceof TypeFormatter and
430- m .hasName ( [ "format" , "out" ] )
431- or
432432 m .getDeclaringType ( ) .getASourceSupertype * ( ) instanceof TypeSQLiteQueryBuilder and
433433 // buildQuery(String[] projectionIn, String selection, String groupBy, String having, String sortOrder, String limit)
434434 // buildQuery(String[] projectionIn, String selection, String[] selectionArgs, String groupBy, String having, String sortOrder, String limit)
@@ -440,7 +440,7 @@ private predicate taintPreservingQualifierToMethod(Method m) {
440440 m .( TaintPreservingMethod ) .returnsTaint ( - 1 )
441441}
442442
443- private class StringReplaceMethod extends Method {
443+ private class StringReplaceMethod extends TaintPreservingMethod {
444444 StringReplaceMethod ( ) {
445445 getDeclaringType ( ) instanceof TypeString and
446446 (
@@ -449,6 +449,8 @@ private class StringReplaceMethod extends Method {
449449 hasName ( "replaceFirst" )
450450 )
451451 }
452+
453+ override predicate returnsTaint ( int arg ) { arg = 1 }
452454}
453455
454456private predicate unsafeEscape ( MethodAccess ma ) {
@@ -496,12 +498,6 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
496498 * of its arguments are tainted.
497499 */
498500private predicate taintPreservingArgumentToMethod ( Method method ) {
499- method .getDeclaringType ( ) instanceof TypeString and
500- ( method .hasName ( "format" ) or method .hasName ( "formatted" ) or method .hasName ( "join" ) )
501- or
502- method .getDeclaringType ( ) instanceof TypeFormatter and
503- method .hasName ( "format" )
504- or
505501 method .getDeclaringType ( ) instanceof TypeDatabaseUtils and
506502 // String[] appendSelectionArgs(String[] originalValues, String[] newValues)
507503 // String concatenateWhere(String a, String b)
@@ -519,8 +515,6 @@ private predicate taintPreservingArgumentToMethod(Method method) {
519515 * `arg`th argument is tainted.
520516 */
521517private predicate taintPreservingArgumentToMethod ( Method method , int arg ) {
522- method instanceof StringReplaceMethod and arg = 1
523- or
524518 exists ( Class c | c .getQualifiedName ( ) = "java.lang.Number" |
525519 hasSubtype * ( c , method .getDeclaringType ( ) )
526520 ) and
@@ -532,10 +526,6 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) {
532526 method .getName ( ) .matches ( "to%String" ) and arg = 0
533527 )
534528 or
535- method .getDeclaringType ( ) instanceof TypeString and
536- method .getName ( ) = "concat" and
537- arg = 0
538- or
539529 (
540530 method .getDeclaringType ( ) .hasQualifiedName ( "java.lang" , "StringBuilder" ) or
541531 method .getDeclaringType ( ) .hasQualifiedName ( "java.lang" , "StringBuffer" )
@@ -617,11 +607,6 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) {
617607 exists ( ProtobufMessageLite m | method = m .getAParseFromMethod ( ) ) and
618608 arg = 0
619609 or
620- // Jackson serialization methods that return the serialized data
621- method instanceof JacksonWriteValueMethod and
622- method .getNumberOfParameters ( ) = 1 and
623- arg = 0
624- or
625610 method .getDeclaringType ( ) .hasQualifiedName ( "java.io" , "StringWriter" ) and
626611 method .hasName ( "append" ) and
627612 arg = 0
@@ -695,12 +680,6 @@ private predicate taintPreservingArgToArg(Method method, int input, int output)
695680 input = 0 and
696681 output = 2
697682 or
698- // Jackson serialization methods that write data to the first argument
699- method instanceof JacksonWriteValueMethod and
700- method .getNumberOfParameters ( ) > 1 and
701- input = method .getNumberOfParameters ( ) - 1 and
702- output = 0
703- or
704683 method .getDeclaringType ( ) instanceof TypeSQLiteQueryBuilder and
705684 // static appendColumns(StringBuilder s, String[] columns)
706685 method .hasName ( "appendColumns" ) and
@@ -721,20 +700,6 @@ private predicate argToQualifierStep(Expr tracked, Expr sink) {
721700 tracked = ma .getArgument ( i ) and
722701 sink = ma .getQualifier ( )
723702 )
724- or
725- exists ( MethodAccess ma |
726- taintPreservingArgumentToQualifier ( ma .getMethod ( ) ) and
727- tracked = ma .getAnArgument ( ) and
728- sink = ma .getQualifier ( )
729- )
730- }
731-
732- /**
733- * Holds if `method` is a method that transfers taint from any of its arguments to its qualifier.
734- */
735- private predicate taintPreservingArgumentToQualifier ( Method method ) {
736- method .getDeclaringType ( ) instanceof TypeFormatter and
737- method .hasName ( "format" )
738703}
739704
740705/**
@@ -892,6 +857,20 @@ private class TypeFormatter extends Class {
892857 TypeFormatter ( ) { this .hasQualifiedName ( "java.util" , "Formatter" ) }
893858}
894859
860+ private class FormatterMethod extends TaintPreservingMethod , TaintTransferringMethod {
861+ FormatterMethod ( ) {
862+ getDeclaringType ( ) instanceof TypeFormatter and
863+ hasName ( [ "format" , "out" , "toString" ] )
864+ }
865+
866+ override predicate returnsTaint ( int arg ) { arg = [ - 1 .. getNumberOfParameters ( ) ] }
867+
868+ override predicate transfersTaint ( int src , int sink ) {
869+ sink = - 1 and
870+ src = [ 0 .. getNumberOfParameters ( ) ]
871+ }
872+ }
873+
895874private import StringBuilderVarModule
896875
897876module StringBuilderVarModule {
0 commit comments