Query
java/ssrf (Server-side request forgery), Java/Kotlin Security/CWE-918
Summary
The SSRF sanitizer-guard recognition for this query does not appear to model an allowlist check expressed via Arrays.stream(...).anyMatch(...) (or other Stream/lambda/method-reference based equality checks) as taint-clearing, even though a functionally identical check written as a plain for loop with .equals()/.equalsIgnoreCase() calls is recognized and clears the alert.
Example (not recognized — alert fires)
private static boolean isAllowedHost(String host, String... allowedHosts) {
return Arrays.stream(allowedHosts).anyMatch(host::equalsIgnoreCase);
}
void fetch(String userUrl) {
URI uri = new URI(userUrl);
if (isAllowedHost(uri.getHost(), "example.com")) {
uri.toURL().openConnection(); // still flagged as SSRF sink
}
}
Example (recognized — alert clears)
private static boolean isAllowedHost(String host, String... allowedHosts) {
for (String allowed : allowedHosts) {
if (allowed.equalsIgnoreCase(host)) {
return true;
}
}
return false;
}
(Identical behavior/contract; only the loop construct differs.)
Why this matters
Lambda-based and Stream-based collection idioms (anyMatch, Set.of(...).contains(...), etc.) have been idiomatic, widely-used Java since Java 8 (2014). A sanitizer-guard recognizer that only matches a narrow inline if (LITERAL.equals(x))/plain-loop shape — and not equivalent Stream/lambda forms — produces false positives that push teams toward less readable, less idiomatic code purely to satisfy the analyzer, with no corresponding security benefit. This also seems inconsistent with sanitizer/guard modeling in other CodeQL queries that do recognize Collection.contains(...)-style checks.
Ask
Could the java/ssrf (and ideally the shared sanitizer-guard library used across similar taint-tracking queries) be extended to recognize equality-based allowlist checks expressed via common Stream/lambda idioms (Arrays.stream(...).anyMatch(x::equals), Collection.contains(x), Set.of(...).contains(x)) as taint-clearing guards, equivalent to their imperative-loop counterparts?
Happy to provide a minimal reproducible test case/repo if useful.
Query
java/ssrf(Server-side request forgery), Java/KotlinSecurity/CWE-918Summary
The SSRF sanitizer-guard recognition for this query does not appear to model an allowlist check expressed via
Arrays.stream(...).anyMatch(...)(or otherStream/lambda/method-reference based equality checks) as taint-clearing, even though a functionally identical check written as a plainforloop with.equals()/.equalsIgnoreCase()calls is recognized and clears the alert.Example (not recognized — alert fires)
Example (recognized — alert clears)
(Identical behavior/contract; only the loop construct differs.)
Why this matters
Lambda-based and
Stream-based collection idioms (anyMatch,Set.of(...).contains(...), etc.) have been idiomatic, widely-used Java since Java 8 (2014). A sanitizer-guard recognizer that only matches a narrow inlineif (LITERAL.equals(x))/plain-loop shape — and not equivalentStream/lambda forms — produces false positives that push teams toward less readable, less idiomatic code purely to satisfy the analyzer, with no corresponding security benefit. This also seems inconsistent with sanitizer/guard modeling in other CodeQL queries that do recognizeCollection.contains(...)-style checks.Ask
Could the
java/ssrf(and ideally the shared sanitizer-guard library used across similar taint-tracking queries) be extended to recognize equality-based allowlist checks expressed via commonStream/lambda idioms (Arrays.stream(...).anyMatch(x::equals),Collection.contains(x),Set.of(...).contains(x)) as taint-clearing guards, equivalent to their imperative-loop counterparts?Happy to provide a minimal reproducible test case/repo if useful.