@@ -63,3 +63,58 @@ private class ApacheLangArrayUtilsTaintPreservingMethod extends TaintPreservingC
6363 src = [ 0 , 2 ]
6464 }
6565}
66+
67+ private Type getAnExcludedParameterType ( ) {
68+ result instanceof PrimitiveType or
69+ result .( RefType ) .hasQualifiedName ( "java.nio.charset" , "Charset" ) or
70+ result .( RefType ) .hasQualifiedName ( "java.util" , "Locale" )
71+ }
72+
73+ private class ApacheStringUtilsTaintPreservingMethod extends TaintPreservingCallable {
74+ ApacheStringUtilsTaintPreservingMethod ( ) {
75+ this .getDeclaringType ( ) .hasQualifiedName ( "org.apache.commons.lang3" , "StringUtils" ) and
76+ this .hasName ( [
77+ "abbreviate" , "abbreviateMiddle" , "appendIfMissing" , "appendIfMissingIgnoreCase" ,
78+ "capitalize" , "center" , "chomp" , "chop" , "defaultIfBlank" , "defaultIfEmpty" ,
79+ "defaultString" , "deleteWhitespace" , "difference" , "firstNonBlank" , "firstNonEmpty" ,
80+ "getBytes" , "getCommonPrefix" , "getDigits" , "getIfBlank" , "getIfEmpty" , "join" , "joinWith" ,
81+ "left" , "leftPad" , "lowerCase" , "mid" , "normalizeSpace" , "overlay" , "prependIfMissing" ,
82+ "prependIfMissingIgnoreCase" , "remove" , "removeAll" , "removeEnd" , "removeEndIgnoreCase" ,
83+ "removeFirst" , "removeIgnoreCase" , "removePattern" , "removeStart" , "removeStartIgnoreCase" ,
84+ "repeat" , "replace" , "replaceAll" , "replaceChars" , "replaceEach" , "replaceEachRepeatedly" ,
85+ "replaceFirst" , "replaceIgnoreCase" , "replaceOnce" , "replaceOnceIgnoreCase" ,
86+ "replacePattern" , "reverse" , "reverseDelimited" , "right" , "rightPad" , "rotate" , "split" ,
87+ "splitByCharacterType" , "splitByCharacterTypeCamelCase" , "splitByWholeSeparator" ,
88+ "splitByWholeSeparatorPreserveAllTokens" , "splitPreserveAllTokens" , "strip" , "stripAccents" ,
89+ "stripAll" , "stripEnd" , "stripStart" , "stripToEmpty" , "stripToNull" , "substring" ,
90+ "substringAfter" , "substringAfterLast" , "substringBefore" , "substringBeforeLast" ,
91+ "substringBetween" , "substringsBetween" , "swapCase" , "toCodePoints" , "toEncodedString" ,
92+ "toRootLowerCase" , "toRootUpperCase" , "toString" , "trim" , "trimToEmpty" , "trimToNull" ,
93+ "truncate" , "uncapitalize" , "unwrap" , "upperCase" , "valueOf" , "wrap" , "wrapIfMissing"
94+ ] )
95+ }
96+
97+ private predicate isExcludedParameter ( int arg ) {
98+ this .getName ( ) .matches ( [ "appendIfMissing%" , "prependIfMissing%" ] ) and arg = [ 2 , 3 ]
99+ or
100+ this .getName ( ) .matches ( [ "remove%" , "split%" , "substring%" , "strip%" ] ) and
101+ arg = [ 1 .. getNumberOfParameters ( ) - 1 ]
102+ or
103+ this .getName ( ) .matches ( [ "chomp" , "getBytes" , "replace%" , "toString" , "unwrap" ] ) and arg = 1
104+ or
105+ this .getName ( ) = "join" and
106+ // Exclude joins of types that render numerically (char[] and non-primitive arrays
107+ // are still considered taint sources)
108+ exists ( PrimitiveType pt |
109+ this .getParameterType ( arg ) .( Array ) .getComponentType ( ) = pt and
110+ not pt instanceof CharacterType
111+ ) and
112+ arg = 0
113+ }
114+
115+ override predicate returnsTaintFrom ( int arg ) {
116+ arg = [ 0 .. getNumberOfParameters ( ) - 1 ] and
117+ not this .getParameterType ( arg ) = getAnExcludedParameterType ( ) and
118+ not isExcludedParameter ( arg )
119+ }
120+ }
0 commit comments