diff --git a/java/ql/lib/semmle/code/java/security/RequestForgery.qll b/java/ql/lib/semmle/code/java/security/RequestForgery.qll index 5eb35c05cd4..dc15ad943bc 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgery.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgery.qll @@ -164,3 +164,24 @@ private class HostComparisonSanitizer extends RequestForgerySanitizer { this = DataFlow::BarrierGuard::getABarrierNode() } } + +/** + * A qualifier in a call to a `.matches()` method 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) { + 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::getABarrierNode() } +} diff --git a/java/ql/test/query-tests/security/CWE-918/SanitizationTests.java b/java/ql/test/query-tests/security/CWE-918/SanitizationTests.java index 03a61cfcf97..f7e46b62946 100644 --- a/java/ql/test/query-tests/security/CWE-918/SanitizationTests.java +++ b/java/ql/test/query-tests/security/CWE-918/SanitizationTests.java @@ -119,8 +119,30 @@ public class SanitizationTests extends HttpServlet { String unsafeUri10 = String.format("%s://%s:%s%s", "http", "myserver.com", "80", request.getParameter("baduri10")); // $ Source HttpRequest unsafer10 = HttpRequest.newBuilder(new URI(unsafeUri10)).build(); // $ Alert client.send(unsafer10, null); // $ Alert + + // GOOD: sanitisation by regexp validation + String safeUri10 = "https://example.com/"; + String param10 = request.getParameter("uri10"); + if (param10.matches("[a-zA-Z0-9/_-]+")) { + safeUri10 = safeUri10 + param10; + } + HttpRequest r10 = HttpRequest.newBuilder(new URI(safeUri10)).build(); + client.send(r10, null); + + + String param11 = request.getParameter("uri11"); + validate(param11); + String safeUri11 = "https://example.com/" + param11; + HttpRequest r11 = HttpRequest.newBuilder(new URI(safeUri11)).build(); + client.send(r11, null); } catch (Exception e) { // TODO: handle exception } } + + private void validate(String s) { + if (!s.matches("[a-zA-Z0-9/_-]+")) { + throw new IllegalArgumentException("Invalid ID"); + } + } }