codeql icon indicating copy to clipboard operation
codeql copied to clipboard

Jb1/zipslip performance fix upstream

Open ropwareJB opened this issue 1 year ago • 0 comments

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 AbstractWrapperSanitizerMethod which identifies the set of methods which act as a more restrictive subset of System.String.StartsWith which 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.

image 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.

ropwareJB avatar Feb 08 '24 16:02 ropwareJB