From 924bb92d914875723ea11718e1c1da8898a5dd03 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Sat, 14 Feb 2026 08:24:12 +0000 Subject: [PATCH] Expand log injection sanitizer guards to non-annotation regex matches --- .../code/java/security/LogInjection.qll | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/LogInjection.qll b/java/ql/lib/semmle/code/java/security/LogInjection.qll index deb72e5cf6a..c31e7434140 100644 --- a/java/ql/lib/semmle/code/java/security/LogInjection.qll +++ b/java/ql/lib/semmle/code/java/security/LogInjection.qll @@ -105,24 +105,35 @@ private predicate logInjectionGuard(Guard g, Expr e, boolean branch) { or exists(RegexMatch rm, CompileTimeConstantExpr target | rm = g and + not rm instanceof Annotation and target = rm.getRegex() and - e = rm.getString() + e = rm.getASanitizedExpr() | - // Allow anything except line breaks - ( - not target.getStringValue().matches("%[^%]%") and - not target.getStringValue().matches("%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%") - or - target.getStringValue().matches("%[^%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%]%") - ) and - branch = true - or - // Disallow line breaks - ( - not target.getStringValue().matches("%[^%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%]%") and - // Assuming a regex containing line breaks is correctly matching line breaks in a string - target.getStringValue().matches("%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%") - ) and - branch = false + regexPreventsLogInjection(target.getStringValue(), branch) ) } + +/** + * Holds if `regex` matches against a pattern that allows anything except + * line breaks when `branch` is `true`, or a pattern that matches line breaks + * when `branch` is `false`. + */ +bindingset[regex] +private predicate regexPreventsLogInjection(string regex, boolean branch) { + // Allow anything except line breaks + ( + not regex.matches("%[^%]%") and + not regex.matches("%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%") + or + regex.matches("%[^%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%]%") + ) and + branch = true + or + // Disallow line breaks + ( + not regex.matches("%[^%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%]%") and + // Assuming a regex containing line breaks is correctly matching line breaks in a string + regex.matches("%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%") + ) and + branch = false +}