diff --git a/java/ql/lib/change-notes/2026-09-15-uri-host-comparisons.md b/java/ql/lib/change-notes/2026-09-15-uri-host-comparisons.md new file mode 100644 index 000000000000..9ad96608e3ef --- /dev/null +++ b/java/ql/lib/change-notes/2026-09-15-uri-host-comparisons.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The queries `java/ssrf` and `java/unvalidated-url-redirection` recognize case-insensitive comparisons of `URI.getHost()` with fixed string allowlist entries, as well as equality and case-insensitive comparisons when the host is stored in a local variable. diff --git a/java/ql/lib/semmle/code/java/security/RequestForgery.qll b/java/ql/lib/semmle/code/java/security/RequestForgery.qll index 489b45dffa2c..e1c77a721535 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgery.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgery.qll @@ -13,6 +13,7 @@ import semmle.code.java.frameworks.Properties private import semmle.code.java.controlflow.Guards private import semmle.code.java.dataflow.StringPrefixes private import semmle.code.java.dataflow.ExternalFlow +private import semmle.code.java.dataflow.SSA private import semmle.code.java.security.Sanitizers /** @@ -122,11 +123,21 @@ private class ExternalRequestForgerySanitizer extends RequestForgerySanitizer { ExternalRequestForgerySanitizer() { barrierNode(this, "request-forgery") } } -/** - * A comparison on the host of a url, that is a sanitizer for URL redirects. - * E.g. `"example.org".equals(url.getHost())"` - */ +/** Gets a host read, following local assignments with a single explicit SSA definition. */ +private MethodCall getCheckedHost(Expr checked) { + result = checked.getUnderlyingExpr() and + result.getMethod().hasQualifiedName("java.net", "URI", "getHost") + or + exists(SsaExplicitWrite def | + checked.getUnderlyingExpr().(VarRead).getVariable() instanceof LocalScopeVariable and + def.getARead() = checked.getUnderlyingExpr() and + result = getCheckedHost(def.getValue()) + ) +} + +/** Holds if a comparison validates the host of a URI. */ private predicate isHostComparisonSanitizer(Guard guard, Expr e, boolean branch) { + // Direct equality checks also accept nonconstant comparison operands. guard = any(MethodCall equalsCall | equalsCall.getMethod().getName() = "equals" and @@ -137,6 +148,21 @@ private predicate isHostComparisonSanitizer(Guard guard, Expr e, boolean branch) e = hostCall.getQualifier() ) ) + or + exists(MethodCall comparison, Expr checked, Expr allowed | + guard = comparison and + comparison.getMethod().getDeclaringType() instanceof TypeString and + comparison.getMethod().hasName(["equals", "equalsIgnoreCase"]) and + branch = true and + ( + checked = comparison.getQualifier() and allowed = comparison.getArgument(0) + or + checked = comparison.getArgument(0) and allowed = comparison.getQualifier() + ) and + // New cases require a fixed allowlist entry, not another untrusted value. + exists(allowed.(CompileTimeConstantExpr).getStringValue()) and + e = getCheckedHost(checked).getQualifier() + ) } /** diff --git a/java/ql/test/query-tests/security/CWE-601/semmle/tests/HostComparisonRedirect.java b/java/ql/test/query-tests/security/CWE-601/semmle/tests/HostComparisonRedirect.java new file mode 100644 index 000000000000..edc5638bec26 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-601/semmle/tests/HostComparisonRedirect.java @@ -0,0 +1,248 @@ +import java.net.URI; +import java.util.Arrays; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class HostComparisonRedirect { + public void unguarded(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + response.sendRedirect(uri.toString()); // $ Alert + } + + public void directEquals(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); + if ("example.com".equals(uri.getHost())) { + response.sendRedirect(uri.toString()); + } + } + + public void directEqualsIgnoreCase(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); + if ("example.com".equalsIgnoreCase(uri.getHost())) { + response.sendRedirect(uri.toString()); + } + } + + public void reversedEqualsIgnoreCase(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); + if (uri.getHost().equalsIgnoreCase("example.com")) { + response.sendRedirect(uri.toString()); + } + } + + public void localEquals(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); + String host = uri.getHost(); + if ("example.com".equals(host)) { + response.sendRedirect(uri.toString()); + } + } + + public void localEqualsIgnoreCase(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); + String host = uri.getHost(); + if ("example.com".equalsIgnoreCase(host)) { + response.sendRedirect(uri.toString()); + } + } + + public void streamEquals(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ SPURIOUS: Source + if (Arrays.stream(new String[]{"example.com"}).anyMatch(uri.getHost()::equals)) { + response.sendRedirect(uri.toString()); // $ SPURIOUS: Alert + } + } + + public void reportedStreamHelper(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ SPURIOUS: Source + if (isAllowedStream(uri.getHost(), "example.com")) { + response.sendRedirect(uri.toString()); // $ SPURIOUS: Alert + } + } + + private static boolean isAllowedStream(String host, String... allowedHosts) { + return Arrays.stream(allowedHosts).anyMatch(host::equalsIgnoreCase); + } + + public void reportedLoopHelper(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ SPURIOUS: Source + if (isAllowedLoop(uri.getHost(), "example.com")) { + response.sendRedirect(uri.toString()); // $ SPURIOUS: Alert + } + } + + private static boolean isAllowedLoop(String host, String... allowedHosts) { + for (String allowed : allowedHosts) { + if (allowed.equalsIgnoreCase(host)) { + return true; + } + } + return false; + } + + public void wrongBranch(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + if (!"example.com".equals(uri.getHost())) { + response.sendRedirect(uri.toString()); // $ Alert + } + } + + public void differentUri(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI checked = new URI(request.getParameter("checked")); + URI used = new URI(request.getParameter("url")); // $ Source + if ("example.com".equals(checked.getHost())) { + response.sendRedirect(used.toString()); // $ Alert + } + } + + public void constantUrl(HttpServletResponse response) throws Exception { + response.sendRedirect("https://example.com/"); + } + + public void caseInsensitiveWrongBranch(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + if (!"example.com".equalsIgnoreCase(uri.getHost())) { + response.sendRedirect(uri.toString()); // $ Alert + } + } + + public void caseInsensitiveDifferentUri(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI checked = new URI(request.getParameter("checked")); + URI used = new URI(request.getParameter("url")); // $ Source + if ("example.com".equalsIgnoreCase(checked.getHost())) { + response.sendRedirect(used.toString()); // $ Alert + } + } + + public void reassignedHost(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + String host = uri.getHost(); + host = "example.com"; + if ("example.com".equalsIgnoreCase(host)) { + response.sendRedirect(uri.toString()); // $ Alert + } + } + + public void conditionallyReassignedHost(HttpServletRequest request, HttpServletResponse response, boolean skip) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + String host = uri.getHost(); + if (skip) { + host = "example.com"; + } + if ("example.com".equalsIgnoreCase(host)) { + response.sendRedirect(uri.toString()); // $ Alert + } + } + + public void reassignedUri(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI("https://example.com/"); + String host = uri.getHost(); + uri = new URI(request.getParameter("url")); // $ Source + if ("example.com".equalsIgnoreCase(host)) { + response.sendRedirect(uri.toString()); // $ Alert + } + } + + public void untrustedComparison(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + if (request.getParameter("allowed").equalsIgnoreCase(uri.getHost())) { + response.sendRedirect(uri.toString()); // $ Alert + } + } + + public void unrelatedComparison(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + if (new FakeComparison().equalsIgnoreCase(uri.getHost())) { + response.sendRedirect(uri.toString()); // $ Alert + } + } + + private static class FakeComparison { + boolean equalsIgnoreCase(String host) { + return true; + } + } + + public void aliasChain(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); + String host = uri.getHost(); + String alias = host; + String secondAlias = alias; + if ("example.com".equalsIgnoreCase(secondAlias)) { + response.sendRedirect(uri.toString()); + } + } + + public void finallyOverwrite(HttpServletRequest request, HttpServletResponse response, boolean skip) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + String host = uri.getHost(); + try { + if (skip) return; + host = "example.com"; + } finally { + if ("example.com".equalsIgnoreCase(host)) { + response.sendRedirect(uri.toString()); // $ Alert + } + } + } + + public void rejectionReturns(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); + String host = uri.getHost(); + if (!"example.com".equalsIgnoreCase(host)) return; + response.sendRedirect(uri.toString()); + } + + private static final String ALLOWED_HOST = "example.com"; + + public void constantAllowlistField(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); + String host = uri.getHost(); + if (ALLOWED_HOST.equalsIgnoreCase(host)) { + response.sendRedirect(uri.toString()); + } + } + + public void orBypass(HttpServletRequest request, HttpServletResponse response, boolean skip) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + String host = uri.getHost(); + if ("example.com".equalsIgnoreCase(host) || skip) { + response.sendRedirect(uri.toString()); // $ Alert + } + } + + public void assignmentCast(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); + Object value = uri.getHost(); + String host = (String) value; + if ("example.com".equalsIgnoreCase(host)) { + response.sendRedirect(uri.toString()); + } + } + + public void comparisonCast(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); + Object host = uri.getHost(); + if ("example.com".equalsIgnoreCase((String) host)) { + response.sendRedirect(uri.toString()); + } + } + + public void castHostOverwrite(HttpServletRequest request, HttpServletResponse response) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + Object host = uri.getHost(); + host = "example.com"; + if ("example.com".equalsIgnoreCase((String) host)) { + response.sendRedirect(uri.toString()); // $ Alert + } + } + + public void castHostConditionalOverwrite(HttpServletRequest request, HttpServletResponse response, boolean skip) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + Object host = uri.getHost(); + if (skip) host = "example.com"; + if ("example.com".equalsIgnoreCase((String) host)) { + response.sendRedirect(uri.toString()); // $ Alert + } + } +} diff --git a/java/ql/test/query-tests/security/CWE-601/semmle/tests/UrlRedirect.expected b/java/ql/test/query-tests/security/CWE-601/semmle/tests/UrlRedirect.expected index 4e311cdd5609..7a16ee15c617 100644 --- a/java/ql/test/query-tests/security/CWE-601/semmle/tests/UrlRedirect.expected +++ b/java/ql/test/query-tests/security/CWE-601/semmle/tests/UrlRedirect.expected @@ -1,4 +1,21 @@ #select +| HostComparisonRedirect.java:9:31:9:44 | toString(...) | HostComparisonRedirect.java:8:27:8:53 | getParameter(...) : String | HostComparisonRedirect.java:9:31:9:44 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:8:27:8:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:52:35:52:48 | toString(...) | HostComparisonRedirect.java:50:27:50:53 | getParameter(...) : String | HostComparisonRedirect.java:52:35:52:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:50:27:50:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:59:35:59:48 | toString(...) | HostComparisonRedirect.java:57:27:57:53 | getParameter(...) : String | HostComparisonRedirect.java:59:35:59:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:57:27:57:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:70:35:70:48 | toString(...) | HostComparisonRedirect.java:68:27:68:53 | getParameter(...) : String | HostComparisonRedirect.java:70:35:70:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:68:27:68:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:86:35:86:48 | toString(...) | HostComparisonRedirect.java:84:27:84:53 | getParameter(...) : String | HostComparisonRedirect.java:86:35:86:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:84:27:84:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:94:35:94:49 | toString(...) | HostComparisonRedirect.java:92:28:92:54 | getParameter(...) : String | HostComparisonRedirect.java:94:35:94:49 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:92:28:92:54 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:105:35:105:48 | toString(...) | HostComparisonRedirect.java:103:27:103:53 | getParameter(...) : String | HostComparisonRedirect.java:105:35:105:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:103:27:103:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:113:35:113:49 | toString(...) | HostComparisonRedirect.java:111:28:111:54 | getParameter(...) : String | HostComparisonRedirect.java:113:35:113:49 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:111:28:111:54 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:122:35:122:48 | toString(...) | HostComparisonRedirect.java:118:27:118:53 | getParameter(...) : String | HostComparisonRedirect.java:122:35:122:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:118:27:118:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:133:35:133:48 | toString(...) | HostComparisonRedirect.java:127:27:127:53 | getParameter(...) : String | HostComparisonRedirect.java:133:35:133:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:127:27:127:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:142:35:142:48 | toString(...) | HostComparisonRedirect.java:140:23:140:49 | getParameter(...) : String | HostComparisonRedirect.java:142:35:142:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:140:23:140:49 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:149:35:149:48 | toString(...) | HostComparisonRedirect.java:147:27:147:53 | getParameter(...) : String | HostComparisonRedirect.java:149:35:149:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:147:27:147:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:156:35:156:48 | toString(...) | HostComparisonRedirect.java:154:27:154:53 | getParameter(...) : String | HostComparisonRedirect.java:156:35:156:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:154:27:154:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:184:39:184:52 | toString(...) | HostComparisonRedirect.java:177:27:177:53 | getParameter(...) : String | HostComparisonRedirect.java:184:39:184:52 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:177:27:177:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:210:35:210:48 | toString(...) | HostComparisonRedirect.java:207:27:207:53 | getParameter(...) : String | HostComparisonRedirect.java:210:35:210:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:207:27:207:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:236:35:236:48 | toString(...) | HostComparisonRedirect.java:232:27:232:53 | getParameter(...) : String | HostComparisonRedirect.java:236:35:236:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:232:27:232:53 | getParameter(...) | user-provided value | +| HostComparisonRedirect.java:245:35:245:48 | toString(...) | HostComparisonRedirect.java:241:27:241:53 | getParameter(...) : String | HostComparisonRedirect.java:245:35:245:48 | toString(...) | Untrusted URL redirection depends on a $@. | HostComparisonRedirect.java:241:27:241:53 | getParameter(...) | user-provided value | | MicronautUrlRedirect.java:14:38:14:55 | create(...) | MicronautUrlRedirect.java:12:39:12:63 | target : String | MicronautUrlRedirect.java:14:38:14:55 | create(...) | Untrusted URL redirection depends on a $@. | MicronautUrlRedirect.java:12:39:12:63 | target | user-provided value | | MicronautUrlRedirect.java:28:47:28:64 | create(...) | MicronautUrlRedirect.java:27:45:27:69 | target : String | MicronautUrlRedirect.java:28:47:28:64 | create(...) | Untrusted URL redirection depends on a $@. | MicronautUrlRedirect.java:27:45:27:69 | target | user-provided value | | MicronautUrlRedirect.java:33:38:33:55 | create(...) | MicronautUrlRedirect.java:32:44:32:68 | target : String | MicronautUrlRedirect.java:33:38:33:55 | create(...) | Untrusted URL redirection depends on a $@. | MicronautUrlRedirect.java:32:44:32:68 | target | user-provided value | @@ -10,14 +27,65 @@ | UrlRedirect.java:42:43:42:72 | getParameter(...) | UrlRedirect.java:42:43:42:72 | getParameter(...) | UrlRedirect.java:42:43:42:72 | getParameter(...) | Untrusted URL redirection depends on a $@. | UrlRedirect.java:42:43:42:72 | getParameter(...) | user-provided value | | mad/Test.java:14:22:14:38 | (...)... | mad/Test.java:9:16:9:41 | getParameter(...) : String | mad/Test.java:14:22:14:38 | (...)... | Untrusted URL redirection depends on a $@. | mad/Test.java:9:16:9:41 | getParameter(...) | user-provided value | edges +| HostComparisonRedirect.java:8:19:8:54 | new URI(...) : URI | HostComparisonRedirect.java:9:31:9:33 | uri : URI | provenance | | +| HostComparisonRedirect.java:8:27:8:53 | getParameter(...) : String | HostComparisonRedirect.java:8:19:8:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:9:31:9:33 | uri : URI | HostComparisonRedirect.java:9:31:9:44 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:50:19:50:54 | new URI(...) : URI | HostComparisonRedirect.java:52:35:52:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:50:27:50:53 | getParameter(...) : String | HostComparisonRedirect.java:50:19:50:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:52:35:52:37 | uri : URI | HostComparisonRedirect.java:52:35:52:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:57:19:57:54 | new URI(...) : URI | HostComparisonRedirect.java:59:35:59:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:57:27:57:53 | getParameter(...) : String | HostComparisonRedirect.java:57:19:57:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:59:35:59:37 | uri : URI | HostComparisonRedirect.java:59:35:59:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:68:19:68:54 | new URI(...) : URI | HostComparisonRedirect.java:70:35:70:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:68:27:68:53 | getParameter(...) : String | HostComparisonRedirect.java:68:19:68:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:70:35:70:37 | uri : URI | HostComparisonRedirect.java:70:35:70:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:84:19:84:54 | new URI(...) : URI | HostComparisonRedirect.java:86:35:86:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:84:27:84:53 | getParameter(...) : String | HostComparisonRedirect.java:84:19:84:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:86:35:86:37 | uri : URI | HostComparisonRedirect.java:86:35:86:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:92:20:92:55 | new URI(...) : URI | HostComparisonRedirect.java:94:35:94:38 | used : URI | provenance | | +| HostComparisonRedirect.java:92:28:92:54 | getParameter(...) : String | HostComparisonRedirect.java:92:20:92:55 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:94:35:94:38 | used : URI | HostComparisonRedirect.java:94:35:94:49 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:103:19:103:54 | new URI(...) : URI | HostComparisonRedirect.java:105:35:105:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:103:27:103:53 | getParameter(...) : String | HostComparisonRedirect.java:103:19:103:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:105:35:105:37 | uri : URI | HostComparisonRedirect.java:105:35:105:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:111:20:111:55 | new URI(...) : URI | HostComparisonRedirect.java:113:35:113:38 | used : URI | provenance | | +| HostComparisonRedirect.java:111:28:111:54 | getParameter(...) : String | HostComparisonRedirect.java:111:20:111:55 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:113:35:113:38 | used : URI | HostComparisonRedirect.java:113:35:113:49 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:118:19:118:54 | new URI(...) : URI | HostComparisonRedirect.java:122:35:122:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:118:27:118:53 | getParameter(...) : String | HostComparisonRedirect.java:118:19:118:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:122:35:122:37 | uri : URI | HostComparisonRedirect.java:122:35:122:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:127:19:127:54 | new URI(...) : URI | HostComparisonRedirect.java:133:35:133:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:127:27:127:53 | getParameter(...) : String | HostComparisonRedirect.java:127:19:127:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:133:35:133:37 | uri : URI | HostComparisonRedirect.java:133:35:133:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:140:15:140:50 | new URI(...) : URI | HostComparisonRedirect.java:142:35:142:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:140:23:140:49 | getParameter(...) : String | HostComparisonRedirect.java:140:15:140:50 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:142:35:142:37 | uri : URI | HostComparisonRedirect.java:142:35:142:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:147:19:147:54 | new URI(...) : URI | HostComparisonRedirect.java:149:35:149:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:147:27:147:53 | getParameter(...) : String | HostComparisonRedirect.java:147:19:147:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:149:35:149:37 | uri : URI | HostComparisonRedirect.java:149:35:149:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:154:19:154:54 | new URI(...) : URI | HostComparisonRedirect.java:156:35:156:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:154:27:154:53 | getParameter(...) : String | HostComparisonRedirect.java:154:19:154:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:156:35:156:37 | uri : URI | HostComparisonRedirect.java:156:35:156:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:177:19:177:54 | new URI(...) : URI | HostComparisonRedirect.java:184:39:184:41 | uri : URI | provenance | | +| HostComparisonRedirect.java:177:27:177:53 | getParameter(...) : String | HostComparisonRedirect.java:177:19:177:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:184:39:184:41 | uri : URI | HostComparisonRedirect.java:184:39:184:52 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:207:19:207:54 | new URI(...) : URI | HostComparisonRedirect.java:210:35:210:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:207:27:207:53 | getParameter(...) : String | HostComparisonRedirect.java:207:19:207:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:210:35:210:37 | uri : URI | HostComparisonRedirect.java:210:35:210:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:232:19:232:54 | new URI(...) : URI | HostComparisonRedirect.java:236:35:236:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:232:27:232:53 | getParameter(...) : String | HostComparisonRedirect.java:232:19:232:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:236:35:236:37 | uri : URI | HostComparisonRedirect.java:236:35:236:48 | toString(...) | provenance | MaD:10 | +| HostComparisonRedirect.java:241:19:241:54 | new URI(...) : URI | HostComparisonRedirect.java:245:35:245:37 | uri : URI | provenance | | +| HostComparisonRedirect.java:241:27:241:53 | getParameter(...) : String | HostComparisonRedirect.java:241:19:241:54 | new URI(...) : URI | provenance | Src:MaD:6 MaD:8 | +| HostComparisonRedirect.java:245:35:245:37 | uri : URI | HostComparisonRedirect.java:245:35:245:48 | toString(...) | provenance | MaD:10 | | MicronautUrlRedirect.java:12:39:12:63 | target : String | MicronautUrlRedirect.java:14:49:14:54 | target : String | provenance | | -| MicronautUrlRedirect.java:14:49:14:54 | target : String | MicronautUrlRedirect.java:14:38:14:55 | create(...) | provenance | MaD:8 Sink:MaD:2 | +| MicronautUrlRedirect.java:14:49:14:54 | target : String | MicronautUrlRedirect.java:14:38:14:55 | create(...) | provenance | MaD:9 Sink:MaD:2 | | MicronautUrlRedirect.java:27:45:27:69 | target : String | MicronautUrlRedirect.java:28:58:28:63 | target : String | provenance | | -| MicronautUrlRedirect.java:28:58:28:63 | target : String | MicronautUrlRedirect.java:28:47:28:64 | create(...) | provenance | MaD:8 Sink:MaD:1 | +| MicronautUrlRedirect.java:28:58:28:63 | target : String | MicronautUrlRedirect.java:28:47:28:64 | create(...) | provenance | MaD:9 Sink:MaD:1 | | MicronautUrlRedirect.java:32:44:32:68 | target : String | MicronautUrlRedirect.java:33:49:33:54 | target : String | provenance | | -| MicronautUrlRedirect.java:33:49:33:54 | target : String | MicronautUrlRedirect.java:33:38:33:55 | create(...) | provenance | MaD:8 Sink:MaD:3 | +| MicronautUrlRedirect.java:33:49:33:54 | target : String | MicronautUrlRedirect.java:33:38:33:55 | create(...) | provenance | MaD:9 Sink:MaD:3 | | MicronautUrlRedirect.java:37:45:37:69 | target : String | MicronautUrlRedirect.java:38:58:38:63 | target : String | provenance | | -| MicronautUrlRedirect.java:38:58:38:63 | target : String | MicronautUrlRedirect.java:38:47:38:64 | create(...) | provenance | MaD:8 Sink:MaD:4 | +| MicronautUrlRedirect.java:38:58:38:63 | target : String | MicronautUrlRedirect.java:38:47:38:64 | create(...) | provenance | MaD:9 Sink:MaD:4 | | UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:32:25:32:67 | weakCleanup(...) | provenance | Src:MaD:6 MaD:7 | | UrlRedirect.java:32:37:32:66 | getParameter(...) : String | UrlRedirect.java:45:28:45:39 | input : String | provenance | Src:MaD:6 | | UrlRedirect.java:45:28:45:39 | input : String | UrlRedirect.java:46:10:46:14 | input : String | provenance | | @@ -32,8 +100,78 @@ models | 5 | Sink: org.kohsuke.stapler; HttpResponses; true; redirectTo; (String); ; Argument[0]; url-redirection; ai-manual | | 6 | Source: javax.servlet; ServletRequest; false; getParameter; (String); ; ReturnValue; remote; manual | | 7 | Summary: java.lang; String; false; replaceAll; ; ; Argument[this]; ReturnValue; taint; manual | -| 8 | Summary: java.net; URI; false; create; ; ; Argument[0]; ReturnValue; taint; manual | +| 8 | Summary: java.net; URI; false; URI; (String); ; Argument[0]; Argument[this]; taint; manual | +| 9 | Summary: java.net; URI; false; create; ; ; Argument[0]; ReturnValue; taint; manual | +| 10 | Summary: java.net; URI; false; toString; ; ; Argument[this]; ReturnValue; taint; manual | nodes +| HostComparisonRedirect.java:8:19:8:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:8:27:8:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:9:31:9:33 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:9:31:9:44 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:50:19:50:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:50:27:50:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:52:35:52:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:52:35:52:48 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:57:19:57:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:57:27:57:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:59:35:59:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:59:35:59:48 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:68:19:68:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:68:27:68:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:70:35:70:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:70:35:70:48 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:84:19:84:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:84:27:84:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:86:35:86:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:86:35:86:48 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:92:20:92:55 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:92:28:92:54 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:94:35:94:38 | used : URI | semmle.label | used : URI | +| HostComparisonRedirect.java:94:35:94:49 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:103:19:103:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:103:27:103:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:105:35:105:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:105:35:105:48 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:111:20:111:55 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:111:28:111:54 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:113:35:113:38 | used : URI | semmle.label | used : URI | +| HostComparisonRedirect.java:113:35:113:49 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:118:19:118:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:118:27:118:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:122:35:122:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:122:35:122:48 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:127:19:127:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:127:27:127:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:133:35:133:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:133:35:133:48 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:140:15:140:50 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:140:23:140:49 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:142:35:142:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:142:35:142:48 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:147:19:147:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:147:27:147:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:149:35:149:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:149:35:149:48 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:154:19:154:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:154:27:154:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:156:35:156:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:156:35:156:48 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:177:19:177:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:177:27:177:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:184:39:184:41 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:184:39:184:52 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:207:19:207:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:207:27:207:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:210:35:210:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:210:35:210:48 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:232:19:232:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:232:27:232:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:236:35:236:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:236:35:236:48 | toString(...) | semmle.label | toString(...) | +| HostComparisonRedirect.java:241:19:241:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparisonRedirect.java:241:27:241:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparisonRedirect.java:245:35:245:37 | uri : URI | semmle.label | uri : URI | +| HostComparisonRedirect.java:245:35:245:48 | toString(...) | semmle.label | toString(...) | | MicronautUrlRedirect.java:12:39:12:63 | target : String | semmle.label | target : String | | MicronautUrlRedirect.java:14:38:14:55 | create(...) | semmle.label | create(...) | | MicronautUrlRedirect.java:14:49:14:54 | target : String | semmle.label | target : String | diff --git a/java/ql/test/query-tests/security/CWE-918/HostComparison.java b/java/ql/test/query-tests/security/CWE-918/HostComparison.java new file mode 100644 index 000000000000..163a74d1d8ae --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-918/HostComparison.java @@ -0,0 +1,247 @@ +import java.net.URI; +import java.util.Arrays; +import javax.servlet.http.HttpServletRequest; + +public class HostComparison { + public void unguarded(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + uri.toURL().openConnection(); // $ Alert + } + + public void directEquals(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); + if ("example.com".equals(uri.getHost())) { + uri.toURL().openConnection(); + } + } + + public void directEqualsIgnoreCase(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); + if ("example.com".equalsIgnoreCase(uri.getHost())) { + uri.toURL().openConnection(); + } + } + + public void reversedEqualsIgnoreCase(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); + if (uri.getHost().equalsIgnoreCase("example.com")) { + uri.toURL().openConnection(); + } + } + + public void localEquals(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); + String host = uri.getHost(); + if ("example.com".equals(host)) { + uri.toURL().openConnection(); + } + } + + public void localEqualsIgnoreCase(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); + String host = uri.getHost(); + if ("example.com".equalsIgnoreCase(host)) { + uri.toURL().openConnection(); + } + } + + public void streamEquals(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ SPURIOUS: Source + if (Arrays.stream(new String[]{"example.com"}).anyMatch(uri.getHost()::equals)) { + uri.toURL().openConnection(); // $ SPURIOUS: Alert + } + } + + public void reportedStreamHelper(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ SPURIOUS: Source + if (isAllowedStream(uri.getHost(), "example.com")) { + uri.toURL().openConnection(); // $ SPURIOUS: Alert + } + } + + private static boolean isAllowedStream(String host, String... allowedHosts) { + return Arrays.stream(allowedHosts).anyMatch(host::equalsIgnoreCase); + } + + public void reportedLoopHelper(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ SPURIOUS: Source + if (isAllowedLoop(uri.getHost(), "example.com")) { + uri.toURL().openConnection(); // $ SPURIOUS: Alert + } + } + + private static boolean isAllowedLoop(String host, String... allowedHosts) { + for (String allowed : allowedHosts) { + if (allowed.equalsIgnoreCase(host)) { + return true; + } + } + return false; + } + + public void wrongBranch(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + if (!"example.com".equals(uri.getHost())) { + uri.toURL().openConnection(); // $ Alert + } + } + + public void differentUri(HttpServletRequest request) throws Exception { + URI checked = new URI(request.getParameter("checked")); + URI used = new URI(request.getParameter("url")); // $ Source + if ("example.com".equals(checked.getHost())) { + used.toURL().openConnection(); // $ Alert + } + } + + public void constantUrl() throws Exception { + new URI("https://example.com/").toURL().openConnection(); + } + + public void caseInsensitiveWrongBranch(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + if (!"example.com".equalsIgnoreCase(uri.getHost())) { + uri.toURL().openConnection(); // $ Alert + } + } + + public void caseInsensitiveDifferentUri(HttpServletRequest request) throws Exception { + URI checked = new URI(request.getParameter("checked")); + URI used = new URI(request.getParameter("url")); // $ Source + if ("example.com".equalsIgnoreCase(checked.getHost())) { + used.toURL().openConnection(); // $ Alert + } + } + + public void reassignedHost(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + String host = uri.getHost(); + host = "example.com"; + if ("example.com".equalsIgnoreCase(host)) { + uri.toURL().openConnection(); // $ Alert + } + } + + public void conditionallyReassignedHost(HttpServletRequest request, boolean skip) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + String host = uri.getHost(); + if (skip) { + host = "example.com"; + } + if ("example.com".equalsIgnoreCase(host)) { + uri.toURL().openConnection(); // $ Alert + } + } + + public void reassignedUri(HttpServletRequest request) throws Exception { + URI uri = new URI("https://example.com/"); + String host = uri.getHost(); + uri = new URI(request.getParameter("url")); // $ Source + if ("example.com".equalsIgnoreCase(host)) { + uri.toURL().openConnection(); // $ Alert + } + } + + public void untrustedComparison(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + if (request.getParameter("allowed").equalsIgnoreCase(uri.getHost())) { + uri.toURL().openConnection(); // $ Alert + } + } + + public void unrelatedComparison(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + if (new FakeComparison().equalsIgnoreCase(uri.getHost())) { + uri.toURL().openConnection(); // $ Alert + } + } + + private static class FakeComparison { + boolean equalsIgnoreCase(String host) { + return true; + } + } + + public void aliasChain(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); + String host = uri.getHost(); + String alias = host; + String secondAlias = alias; + if ("example.com".equalsIgnoreCase(secondAlias)) { + uri.toURL().openConnection(); + } + } + + public void finallyOverwrite(HttpServletRequest request, boolean skip) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + String host = uri.getHost(); + try { + if (skip) return; + host = "example.com"; + } finally { + if ("example.com".equalsIgnoreCase(host)) { + uri.toURL().openConnection(); // $ Alert + } + } + } + + public void rejectionReturns(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); + String host = uri.getHost(); + if (!"example.com".equalsIgnoreCase(host)) return; + uri.toURL().openConnection(); + } + + private static final String ALLOWED_HOST = "example.com"; + + public void constantAllowlistField(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); + String host = uri.getHost(); + if (ALLOWED_HOST.equalsIgnoreCase(host)) { + uri.toURL().openConnection(); + } + } + + public void orBypass(HttpServletRequest request, boolean skip) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + String host = uri.getHost(); + if ("example.com".equalsIgnoreCase(host) || skip) { + uri.toURL().openConnection(); // $ Alert + } + } + + public void assignmentCast(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); + Object value = uri.getHost(); + String host = (String) value; + if ("example.com".equalsIgnoreCase(host)) { + uri.toURL().openConnection(); + } + } + + public void comparisonCast(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); + Object host = uri.getHost(); + if ("example.com".equalsIgnoreCase((String) host)) { + uri.toURL().openConnection(); + } + } + + public void castHostOverwrite(HttpServletRequest request) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + Object host = uri.getHost(); + host = "example.com"; + if ("example.com".equalsIgnoreCase((String) host)) { + uri.toURL().openConnection(); // $ Alert + } + } + + public void castHostConditionalOverwrite(HttpServletRequest request, boolean skip) throws Exception { + URI uri = new URI(request.getParameter("url")); // $ Source + Object host = uri.getHost(); + if (skip) host = "example.com"; + if ("example.com".equalsIgnoreCase((String) host)) { + uri.toURL().openConnection(); // $ Alert + } + } +} diff --git a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected index 6cb07a2dee4a..3aaa32970e6d 100644 --- a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected +++ b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected @@ -210,6 +210,23 @@ | ApacheHttpSSRFVersion5.java:388:44:388:46 | uri | ApacheHttpSSRFVersion5.java:372:30:372:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:388:44:388:46 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRFVersion5.java:372:30:372:56 | getParameter(...) | user-provided value | | ApacheHttpSSRFVersion5.java:390:24:390:26 | uri | ApacheHttpSSRFVersion5.java:372:30:372:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:390:24:390:26 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRFVersion5.java:372:30:372:56 | getParameter(...) | user-provided value | | ApacheHttpSSRFVersion5.java:394:24:394:26 | uri | ApacheHttpSSRFVersion5.java:372:30:372:56 | getParameter(...) : String | ApacheHttpSSRFVersion5.java:394:24:394:26 | uri | Potential server-side request forgery due to a $@. | ApacheHttpSSRFVersion5.java:372:30:372:56 | getParameter(...) | user-provided value | +| HostComparison.java:8:9:8:19 | toURL(...) | HostComparison.java:7:27:7:53 | getParameter(...) : String | HostComparison.java:8:9:8:19 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:7:27:7:53 | getParameter(...) | user-provided value | +| HostComparison.java:51:13:51:23 | toURL(...) | HostComparison.java:49:27:49:53 | getParameter(...) : String | HostComparison.java:51:13:51:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:49:27:49:53 | getParameter(...) | user-provided value | +| HostComparison.java:58:13:58:23 | toURL(...) | HostComparison.java:56:27:56:53 | getParameter(...) : String | HostComparison.java:58:13:58:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:56:27:56:53 | getParameter(...) | user-provided value | +| HostComparison.java:69:13:69:23 | toURL(...) | HostComparison.java:67:27:67:53 | getParameter(...) : String | HostComparison.java:69:13:69:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:67:27:67:53 | getParameter(...) | user-provided value | +| HostComparison.java:85:13:85:23 | toURL(...) | HostComparison.java:83:27:83:53 | getParameter(...) : String | HostComparison.java:85:13:85:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:83:27:83:53 | getParameter(...) | user-provided value | +| HostComparison.java:93:13:93:24 | toURL(...) | HostComparison.java:91:28:91:54 | getParameter(...) : String | HostComparison.java:93:13:93:24 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:91:28:91:54 | getParameter(...) | user-provided value | +| HostComparison.java:104:13:104:23 | toURL(...) | HostComparison.java:102:27:102:53 | getParameter(...) : String | HostComparison.java:104:13:104:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:102:27:102:53 | getParameter(...) | user-provided value | +| HostComparison.java:112:13:112:24 | toURL(...) | HostComparison.java:110:28:110:54 | getParameter(...) : String | HostComparison.java:112:13:112:24 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:110:28:110:54 | getParameter(...) | user-provided value | +| HostComparison.java:121:13:121:23 | toURL(...) | HostComparison.java:117:27:117:53 | getParameter(...) : String | HostComparison.java:121:13:121:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:117:27:117:53 | getParameter(...) | user-provided value | +| HostComparison.java:132:13:132:23 | toURL(...) | HostComparison.java:126:27:126:53 | getParameter(...) : String | HostComparison.java:132:13:132:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:126:27:126:53 | getParameter(...) | user-provided value | +| HostComparison.java:141:13:141:23 | toURL(...) | HostComparison.java:139:23:139:49 | getParameter(...) : String | HostComparison.java:141:13:141:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:139:23:139:49 | getParameter(...) | user-provided value | +| HostComparison.java:148:13:148:23 | toURL(...) | HostComparison.java:146:27:146:53 | getParameter(...) : String | HostComparison.java:148:13:148:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:146:27:146:53 | getParameter(...) | user-provided value | +| HostComparison.java:155:13:155:23 | toURL(...) | HostComparison.java:153:27:153:53 | getParameter(...) : String | HostComparison.java:155:13:155:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:153:27:153:53 | getParameter(...) | user-provided value | +| HostComparison.java:183:17:183:27 | toURL(...) | HostComparison.java:176:27:176:53 | getParameter(...) : String | HostComparison.java:183:17:183:27 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:176:27:176:53 | getParameter(...) | user-provided value | +| HostComparison.java:209:13:209:23 | toURL(...) | HostComparison.java:206:27:206:53 | getParameter(...) : String | HostComparison.java:209:13:209:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:206:27:206:53 | getParameter(...) | user-provided value | +| HostComparison.java:235:13:235:23 | toURL(...) | HostComparison.java:231:27:231:53 | getParameter(...) : String | HostComparison.java:235:13:235:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:231:27:231:53 | getParameter(...) | user-provided value | +| HostComparison.java:244:13:244:23 | toURL(...) | HostComparison.java:240:27:240:53 | getParameter(...) : String | HostComparison.java:244:13:244:23 | toURL(...) | Potential server-side request forgery due to a $@. | HostComparison.java:240:27:240:53 | getParameter(...) | user-provided value | | JakartaWsSSRF.java:15:23:15:25 | url | JakartaWsSSRF.java:14:22:14:48 | getParameter(...) : String | JakartaWsSSRF.java:15:23:15:25 | url | Potential server-side request forgery due to a $@. | JakartaWsSSRF.java:14:22:14:48 | getParameter(...) | user-provided value | | JavaNetHttpSSRF.java:30:32:30:35 | url1 | JavaNetHttpSSRF.java:25:27:25:53 | getParameter(...) : String | JavaNetHttpSSRF.java:30:32:30:35 | url1 | Potential server-side request forgery due to a $@. | JavaNetHttpSSRF.java:25:27:25:53 | getParameter(...) | user-provided value | | JavaNetHttpSSRF.java:33:32:33:35 | url1 | JavaNetHttpSSRF.java:25:27:25:53 | getParameter(...) : String | JavaNetHttpSSRF.java:33:32:33:35 | url1 | Potential server-side request forgery due to a $@. | JavaNetHttpSSRF.java:25:27:25:53 | getParameter(...) | user-provided value | @@ -716,6 +733,74 @@ edges | ApacheHttpSSRFVersion5.java:376:29:376:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:385:50:385:53 | host | provenance | Sink:MaD:206 | | ApacheHttpSSRFVersion5.java:376:29:376:50 | new HttpHost(...) : HttpHost | ApacheHttpSSRFVersion5.java:387:44:387:47 | host | provenance | Sink:MaD:208 | | ApacheHttpSSRFVersion5.java:376:42:376:49 | hostSink : String | ApacheHttpSSRFVersion5.java:376:29:376:50 | new HttpHost(...) : HttpHost | provenance | MaD:315 | +| HostComparison.java:7:19:7:54 | new URI(...) : URI | HostComparison.java:8:9:8:11 | uri : URI | provenance | | +| HostComparison.java:7:27:7:53 | getParameter(...) : String | HostComparison.java:7:19:7:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:7:27:7:53 | getParameter(...) : String | HostComparison.java:7:19:7:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:8:9:8:11 | uri : URI | HostComparison.java:8:9:8:19 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:49:19:49:54 | new URI(...) : URI | HostComparison.java:51:13:51:15 | uri : URI | provenance | | +| HostComparison.java:49:27:49:53 | getParameter(...) : String | HostComparison.java:49:19:49:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:49:27:49:53 | getParameter(...) : String | HostComparison.java:49:19:49:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:51:13:51:15 | uri : URI | HostComparison.java:51:13:51:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:56:19:56:54 | new URI(...) : URI | HostComparison.java:58:13:58:15 | uri : URI | provenance | | +| HostComparison.java:56:27:56:53 | getParameter(...) : String | HostComparison.java:56:19:56:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:56:27:56:53 | getParameter(...) : String | HostComparison.java:56:19:56:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:58:13:58:15 | uri : URI | HostComparison.java:58:13:58:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:67:19:67:54 | new URI(...) : URI | HostComparison.java:69:13:69:15 | uri : URI | provenance | | +| HostComparison.java:67:27:67:53 | getParameter(...) : String | HostComparison.java:67:19:67:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:67:27:67:53 | getParameter(...) : String | HostComparison.java:67:19:67:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:69:13:69:15 | uri : URI | HostComparison.java:69:13:69:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:83:19:83:54 | new URI(...) : URI | HostComparison.java:85:13:85:15 | uri : URI | provenance | | +| HostComparison.java:83:27:83:53 | getParameter(...) : String | HostComparison.java:83:19:83:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:83:27:83:53 | getParameter(...) : String | HostComparison.java:83:19:83:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:85:13:85:15 | uri : URI | HostComparison.java:85:13:85:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:91:20:91:55 | new URI(...) : URI | HostComparison.java:93:13:93:16 | used : URI | provenance | | +| HostComparison.java:91:28:91:54 | getParameter(...) : String | HostComparison.java:91:20:91:55 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:91:28:91:54 | getParameter(...) : String | HostComparison.java:91:20:91:55 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:93:13:93:16 | used : URI | HostComparison.java:93:13:93:24 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:102:19:102:54 | new URI(...) : URI | HostComparison.java:104:13:104:15 | uri : URI | provenance | | +| HostComparison.java:102:27:102:53 | getParameter(...) : String | HostComparison.java:102:19:102:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:102:27:102:53 | getParameter(...) : String | HostComparison.java:102:19:102:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:104:13:104:15 | uri : URI | HostComparison.java:104:13:104:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:110:20:110:55 | new URI(...) : URI | HostComparison.java:112:13:112:16 | used : URI | provenance | | +| HostComparison.java:110:28:110:54 | getParameter(...) : String | HostComparison.java:110:20:110:55 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:110:28:110:54 | getParameter(...) : String | HostComparison.java:110:20:110:55 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:112:13:112:16 | used : URI | HostComparison.java:112:13:112:24 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:117:19:117:54 | new URI(...) : URI | HostComparison.java:121:13:121:15 | uri : URI | provenance | | +| HostComparison.java:117:27:117:53 | getParameter(...) : String | HostComparison.java:117:19:117:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:117:27:117:53 | getParameter(...) : String | HostComparison.java:117:19:117:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:121:13:121:15 | uri : URI | HostComparison.java:121:13:121:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:126:19:126:54 | new URI(...) : URI | HostComparison.java:132:13:132:15 | uri : URI | provenance | | +| HostComparison.java:126:27:126:53 | getParameter(...) : String | HostComparison.java:126:19:126:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:126:27:126:53 | getParameter(...) : String | HostComparison.java:126:19:126:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:132:13:132:15 | uri : URI | HostComparison.java:132:13:132:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:139:15:139:50 | new URI(...) : URI | HostComparison.java:141:13:141:15 | uri : URI | provenance | | +| HostComparison.java:139:23:139:49 | getParameter(...) : String | HostComparison.java:139:15:139:50 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:139:23:139:49 | getParameter(...) : String | HostComparison.java:139:15:139:50 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:141:13:141:15 | uri : URI | HostComparison.java:141:13:141:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:146:19:146:54 | new URI(...) : URI | HostComparison.java:148:13:148:15 | uri : URI | provenance | | +| HostComparison.java:146:27:146:53 | getParameter(...) : String | HostComparison.java:146:19:146:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:146:27:146:53 | getParameter(...) : String | HostComparison.java:146:19:146:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:148:13:148:15 | uri : URI | HostComparison.java:148:13:148:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:153:19:153:54 | new URI(...) : URI | HostComparison.java:155:13:155:15 | uri : URI | provenance | | +| HostComparison.java:153:27:153:53 | getParameter(...) : String | HostComparison.java:153:19:153:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:153:27:153:53 | getParameter(...) : String | HostComparison.java:153:19:153:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:155:13:155:15 | uri : URI | HostComparison.java:155:13:155:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:176:19:176:54 | new URI(...) : URI | HostComparison.java:183:17:183:19 | uri : URI | provenance | | +| HostComparison.java:176:27:176:53 | getParameter(...) : String | HostComparison.java:176:19:176:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:176:27:176:53 | getParameter(...) : String | HostComparison.java:176:19:176:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:183:17:183:19 | uri : URI | HostComparison.java:183:17:183:27 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:206:19:206:54 | new URI(...) : URI | HostComparison.java:209:13:209:15 | uri : URI | provenance | | +| HostComparison.java:206:27:206:53 | getParameter(...) : String | HostComparison.java:206:19:206:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:206:27:206:53 | getParameter(...) : String | HostComparison.java:206:19:206:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:209:13:209:15 | uri : URI | HostComparison.java:209:13:209:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:231:19:231:54 | new URI(...) : URI | HostComparison.java:235:13:235:15 | uri : URI | provenance | | +| HostComparison.java:231:27:231:53 | getParameter(...) : String | HostComparison.java:231:19:231:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:231:27:231:53 | getParameter(...) : String | HostComparison.java:231:19:231:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:235:13:235:15 | uri : URI | HostComparison.java:235:13:235:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | +| HostComparison.java:240:19:240:54 | new URI(...) : URI | HostComparison.java:244:13:244:15 | uri : URI | provenance | | +| HostComparison.java:240:27:240:53 | getParameter(...) : String | HostComparison.java:240:19:240:54 | new URI(...) : URI | provenance | Src:MaD:292 Config | +| HostComparison.java:240:27:240:53 | getParameter(...) : String | HostComparison.java:240:19:240:54 | new URI(...) : URI | provenance | Src:MaD:292 MaD:304 | +| HostComparison.java:244:13:244:15 | uri : URI | HostComparison.java:244:13:244:23 | toURL(...) | provenance | MaD:308 Sink:MaD:15 | | JakartaWsSSRF.java:14:22:14:48 | getParameter(...) : String | JakartaWsSSRF.java:15:23:15:25 | url | provenance | Src:MaD:292 Sink:MaD:9 | | JavaNetHttpSSRF.java:25:27:25:53 | getParameter(...) : String | JavaNetHttpSSRF.java:26:31:26:34 | sink : String | provenance | Src:MaD:292 | | JavaNetHttpSSRF.java:26:23:26:35 | new URI(...) : URI | JavaNetHttpSSRF.java:39:59:39:61 | uri | provenance | Sink:MaD:12 | @@ -1774,6 +1859,74 @@ nodes | ApacheHttpSSRFVersion5.java:388:44:388:46 | uri | semmle.label | uri | | ApacheHttpSSRFVersion5.java:390:24:390:26 | uri | semmle.label | uri | | ApacheHttpSSRFVersion5.java:394:24:394:26 | uri | semmle.label | uri | +| HostComparison.java:7:19:7:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:7:27:7:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:8:9:8:11 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:8:9:8:19 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:49:19:49:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:49:27:49:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:51:13:51:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:51:13:51:23 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:56:19:56:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:56:27:56:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:58:13:58:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:58:13:58:23 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:67:19:67:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:67:27:67:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:69:13:69:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:69:13:69:23 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:83:19:83:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:83:27:83:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:85:13:85:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:85:13:85:23 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:91:20:91:55 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:91:28:91:54 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:93:13:93:16 | used : URI | semmle.label | used : URI | +| HostComparison.java:93:13:93:24 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:102:19:102:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:102:27:102:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:104:13:104:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:104:13:104:23 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:110:20:110:55 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:110:28:110:54 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:112:13:112:16 | used : URI | semmle.label | used : URI | +| HostComparison.java:112:13:112:24 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:117:19:117:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:117:27:117:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:121:13:121:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:121:13:121:23 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:126:19:126:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:126:27:126:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:132:13:132:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:132:13:132:23 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:139:15:139:50 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:139:23:139:49 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:141:13:141:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:141:13:141:23 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:146:19:146:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:146:27:146:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:148:13:148:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:148:13:148:23 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:153:19:153:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:153:27:153:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:155:13:155:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:155:13:155:23 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:176:19:176:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:176:27:176:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:183:17:183:19 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:183:17:183:27 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:206:19:206:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:206:27:206:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:209:13:209:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:209:13:209:23 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:231:19:231:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:231:27:231:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:235:13:235:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:235:13:235:23 | toURL(...) | semmle.label | toURL(...) | +| HostComparison.java:240:19:240:54 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| HostComparison.java:240:27:240:53 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| HostComparison.java:244:13:244:15 | uri : URI | semmle.label | uri : URI | +| HostComparison.java:244:13:244:23 | toURL(...) | semmle.label | toURL(...) | | JakartaWsSSRF.java:14:22:14:48 | getParameter(...) : String | semmle.label | getParameter(...) : String | | JakartaWsSSRF.java:15:23:15:25 | url | semmle.label | url | | JavaNetHttpSSRF.java:25:27:25:53 | getParameter(...) : String | semmle.label | getParameter(...) : String |