From a22fd39230ddd590a01d5a505fd194ce1c87033e Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 10 Feb 2026 14:54:54 +0000 Subject: [PATCH] Use RegexExecution in sanitizer definitions (expands scope) --- .../semmle/code/java/security/PathSanitizer.qll | 13 +++++-------- .../lib/semmle/code/java/security/Sanitizers.qll | 14 +++----------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll index 4685f5e48f7..ffd50655001 100644 --- a/java/ql/lib/semmle/code/java/security/PathSanitizer.qll +++ b/java/ql/lib/semmle/code/java/security/PathSanitizer.qll @@ -427,20 +427,17 @@ private class ReplaceDirectoryCharactersSanitizer extends StringReplaceOrReplace } } -/** Holds if `target` is the first argument of `matchesCall`. */ -private predicate isMatchesTarget(StringMatchesCall matchesCall, CompileTimeConstantExpr target) { - target = matchesCall.getArgument(0) -} - /** * Holds if `matchesCall` confirms that `checkedExpr` does not contain any directory characters * on the given `branch`. */ -private predicate isMatchesCall(StringMatchesCall matchesCall, Expr checkedExpr, boolean branch) { +private predicate isMatchesCall( + RegexExecutionExpr::Range regexMatch, Expr checkedExpr, boolean branch +) { exists(CompileTimeConstantExpr target, string targetValue | - isMatchesTarget(matchesCall, target) and + target = regexMatch.getRegex() and target.getStringValue() = targetValue and - checkedExpr = matchesCall.getQualifier() + checkedExpr = regexMatch.getString() | ( // Allow anything except `.`, '/', '\' diff --git a/java/ql/lib/semmle/code/java/security/Sanitizers.qll b/java/ql/lib/semmle/code/java/security/Sanitizers.qll index 3f909864d2c..ddac010391e 100644 --- a/java/ql/lib/semmle/code/java/security/Sanitizers.qll +++ b/java/ql/lib/semmle/code/java/security/Sanitizers.qll @@ -46,19 +46,11 @@ predicate regexpMatchGuardChecks(Guard guard, Expr e, boolean branch) { guard = mc and branch = true | - // `String.matches` and other `matches` methods. + e = mc.(RegexExecutionExpr::Range).getString() + or + // Other `matches` methods. method.getName() = "matches" and e = mc.getQualifier() - or - method instanceof PatternMatchesMethod and - e = mc.getArgument(1) - or - method instanceof MatcherMatchesMethod and - exists(MethodCall matcherCall | - matcherCall.getMethod() instanceof PatternMatcherMethod and - e = matcherCall.getArgument(0) and - DataFlow::localExprFlow(matcherCall, mc.getQualifier()) - ) ) }