github / github/codeql

java/ssrf: allowlist guard not recognized when expressed via Stream/lambda (anyMatch), only via plain equals()/for-loop

Offen
#22,259 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
CodeQL
Sterne
10.1k
Forks
2.1k
Ø Merge
2 T. 15 Std.
Gemergte PRs (30 T.)
141

Beschreibung

### 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)
```java
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)
```java
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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Start with the java/ssrf query and the shared sanitizer-guard library it uses; inspect how the existing equals() and loop forms are modeled. Add regression coverage for the Arrays.stream(...).anyMatch(...), method-reference, and contains(...) examples, and verify that recognized allowlist checks clear the SSRF alert without weakening other cases.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
java
Bereich
devtools, security
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Ruhig
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.