Add support for Apache Commons Lang StringUtils

This commit is contained in:
Chris Smowton
2021-02-09 14:21:39 +00:00
parent bf03c0f419
commit a2eeffa9c0
7 changed files with 1329 additions and 0 deletions

View File

@@ -63,3 +63,58 @@ private class ApacheLangArrayUtilsTaintPreservingMethod extends TaintPreservingC
src = [0, 2]
}
}
private Type getAnExcludedParameterType() {
result instanceof PrimitiveType or
result.(RefType).hasQualifiedName("java.nio.charset", "Charset") or
result.(RefType).hasQualifiedName("java.util", "Locale")
}
private class ApacheStringUtilsTaintPreservingMethod extends TaintPreservingCallable {
ApacheStringUtilsTaintPreservingMethod() {
this.getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "StringUtils") and
this.hasName([
"abbreviate", "abbreviateMiddle", "appendIfMissing", "appendIfMissingIgnoreCase",
"capitalize", "center", "chomp", "chop", "defaultIfBlank", "defaultIfEmpty",
"defaultString", "deleteWhitespace", "difference", "firstNonBlank", "firstNonEmpty",
"getBytes", "getCommonPrefix", "getDigits", "getIfBlank", "getIfEmpty", "join", "joinWith",
"left", "leftPad", "lowerCase", "mid", "normalizeSpace", "overlay", "prependIfMissing",
"prependIfMissingIgnoreCase", "remove", "removeAll", "removeEnd", "removeEndIgnoreCase",
"removeFirst", "removeIgnoreCase", "removePattern", "removeStart", "removeStartIgnoreCase",
"repeat", "replace", "replaceAll", "replaceChars", "replaceEach", "replaceEachRepeatedly",
"replaceFirst", "replaceIgnoreCase", "replaceOnce", "replaceOnceIgnoreCase",
"replacePattern", "reverse", "reverseDelimited", "right", "rightPad", "rotate", "split",
"splitByCharacterType", "splitByCharacterTypeCamelCase", "splitByWholeSeparator",
"splitByWholeSeparatorPreserveAllTokens", "splitPreserveAllTokens", "strip", "stripAccents",
"stripAll", "stripEnd", "stripStart", "stripToEmpty", "stripToNull", "substring",
"substringAfter", "substringAfterLast", "substringBefore", "substringBeforeLast",
"substringBetween", "substringsBetween", "swapCase", "toCodePoints", "toEncodedString",
"toRootLowerCase", "toRootUpperCase", "toString", "trim", "trimToEmpty", "trimToNull",
"truncate", "uncapitalize", "unwrap", "upperCase", "valueOf", "wrap", "wrapIfMissing"
])
}
private predicate isExcludedParameter(int arg) {
this.getName().matches(["appendIfMissing%", "prependIfMissing%"]) and arg = [2, 3]
or
this.getName().matches(["remove%", "split%", "substring%", "strip%"]) and
arg = [1 .. getNumberOfParameters() - 1]
or
this.getName().matches(["chomp", "getBytes", "replace%", "toString", "unwrap"]) and arg = 1
or
this.getName() = "join" and
// Exclude joins of types that render numerically (char[] and non-primitive arrays
// are still considered taint sources)
exists(PrimitiveType pt |
this.getParameterType(arg).(Array).getComponentType() = pt and
not pt instanceof CharacterType
) and
arg = 0
}
override predicate returnsTaintFrom(int arg) {
arg = [0 .. getNumberOfParameters() - 1] and
not this.getParameterType(arg) = getAnExcludedParameterType() and
not isExcludedParameter(arg)
}
}