Jb1/zipslip performance fix upstream
Original: https://github.com/github/codeql/pull/13281 (with performance improvements)
Summary
- Patched False negative case with original GH query (see bottom of post)
- Patched False positive case with sanitizer wrappers (see below code example)
Changes
- Declares String concatenation as an unsanitized path combination vector
- Declares String interpolation as an unsanitized path combination vector
- Creates a class
AbstractWrapperSanitizerMethodwhich identifies the set of methods which act as a more restrictive subset ofSystem.String.StartsWithwhich then acts as a SanitizerGuard. - Various helper subclasses / alias classes
- Patched False negative case with original GH query
Info
An AbstractWrapperSanitizerMethod is a Method where
- The Method has a MethodCall to a given class of Sanitizers
- The Method can /only/ return true if it first passes through the RootSanitizerGuard
- Or if it returns the resultant of the RootSanitizerGuard verbatim.
- Or it simply wraps another AbstractWrapperSanitizerMethod
For example:
bool wrapperFn(a,b){
if(guard(a,b))
return true
....
return false
}
bool wrapperFn(a,b){
...
return guard(a,b)
}
However there is a defect with the existing Taint flow configuration's isSanitizer predicate: the stringCheckGuard predicate looks for String.StartsWith method calls with a qualifier /that did not directly/ come from a call to Path.Combine. Additionally, there is no check for path canonicalization with Path.GetFullPath. Therefore, code of the following stanza will be declared as a guard and assumed to be sanitized by the GH query.
Above: The stringCheckGuard predicate erroneously declares the String.StartsWith MethodCall as a valid sanitizer.
To address this, I declared a class RootSanitizerMethodCall, which will locate instances of String.StartsWith whose qualifiers directly flow from Path.GetFullPath or have a safe sequence of Path.Combine and then Path.GetFullPath permitting further mutations following.