diff --git a/java/ql/lib/change-notes/2026-04-04-trust-boundary-regexp-barrier.md b/java/ql/lib/change-notes/2026-04-04-trust-boundary-regexp-barrier.md new file mode 100644 index 00000000000..b80c0611b6d --- /dev/null +++ b/java/ql/lib/change-notes/2026-04-04-trust-boundary-regexp-barrier.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `java/trust-boundary-violation` query now recognizes regular expression checks (including `String.matches()` guards and `@javax.validation.constraints.Pattern` annotations) as sanitizers, consistent with the existing treatment of ESAPI validators. This reduces false positives when input is validated against a pattern before being stored in a session. diff --git a/java/ql/lib/semmle/code/java/security/TrustBoundaryViolationQuery.qll b/java/ql/lib/semmle/code/java/security/TrustBoundaryViolationQuery.qll index d234f3df20c..91e9b18cc9b 100644 --- a/java/ql/lib/semmle/code/java/security/TrustBoundaryViolationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TrustBoundaryViolationQuery.qll @@ -40,7 +40,8 @@ module TrustBoundaryConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node instanceof TrustBoundaryValidationSanitizer or node.getType() instanceof HttpServletSession or - node instanceof SimpleTypeSanitizer + node instanceof SimpleTypeSanitizer or + node instanceof RegexpCheckBarrier } predicate isSink(DataFlow::Node sink) { sink instanceof TrustBoundaryViolationSink } diff --git a/java/ql/test/query-tests/security/CWE-501/TrustBoundaryViolations.java b/java/ql/test/query-tests/security/CWE-501/TrustBoundaryViolations.java index d676e3e9678..1934e7f5598 100644 --- a/java/ql/test/query-tests/security/CWE-501/TrustBoundaryViolations.java +++ b/java/ql/test/query-tests/security/CWE-501/TrustBoundaryViolations.java @@ -31,5 +31,11 @@ public class TrustBoundaryViolations extends HttpServlet { } } catch (Exception e) { } + + // GOOD: Bean Validation @Pattern annotation constrains the input via regex. + String input4 = request.getParameter("input4"); + if (input4.matches("[a-zA-Z0-9]+")) { + request.getSession().setAttribute("input4", input4); + } } }