Refactor regex sanitizer

Move it to Sanitizers.qll and rename it to be more general (mostly
following Go).
This commit is contained in:
Owen Mansel-Chan
2025-12-02 16:04:39 +00:00
parent e52f819df0
commit 566aa8f201
2 changed files with 32 additions and 18 deletions

View File

@@ -166,22 +166,7 @@ private class HostComparisonSanitizer extends RequestForgerySanitizer {
} }
/** /**
* A qualifier in a call to a `.matches()` method that is a sanitizer for URL redirects. * A comparison with a regular expression that is a sanitizer for URL redirects.
*
* Matches any method call where the method is named `matches`.
*/ */
private predicate isMatchesSanitizer(Guard guard, Expr e, boolean branch) { private class RegexpCheckRequestForgerySanitizer extends RequestForgerySanitizer instanceof RegexpCheckBarrier
guard = { }
any(MethodCall method |
method.getMethod().getName() = "matches" and
e = method.getQualifier() and
branch = true
)
}
/**
* A qualifier in a call to `.matches()` that is a sanitizer for URL redirects.
*/
private class MatchesSanitizer extends RequestForgerySanitizer {
MatchesSanitizer() { this = DataFlow::BarrierGuard<isMatchesSanitizer/3>::getABarrierNode() }
}

View File

@@ -3,6 +3,7 @@ overlay[local?]
module; module;
import java import java
private import semmle.code.java.controlflow.Guards
private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.DataFlow
/** /**
@@ -29,3 +30,31 @@ class SimpleTypeSanitizer extends DataFlow::Node {
this.getType() instanceof EnumType this.getType() instanceof EnumType
} }
} }
/**
* Holds if `guard` holds with branch `branch` if `e` matches a regular expression.
*
* This is overapproximate: we do not attempt to reason about the correctness of the regexp.
*
* Use this if you want to define a derived `DataFlow::BarrierGuard` without
* make the type recursive. Otherwise use `RegexpCheckBarrier`.
*/
predicate regexpMatchGuardChecks(Guard guard, Expr e, boolean branch) {
guard =
any(MethodCall method |
method.getMethod().getName() = "matches" and
e = method.getQualifier() and
branch = true
)
}
/**
* A check against a regular expression, considered as a barrier guard.
*
* This is overapproximate: we do not attempt to reason about the correctness of the regexp.
*/
class RegexpCheckBarrier extends DataFlow::Node {
RegexpCheckBarrier() {
this = DataFlow::BarrierGuard<regexpMatchGuardChecks/3>::getABarrierNode()
}
}