PoC Archive PoC Archive
High CVE-2026-43515 patched

Apache Tomcat Split-Collection Security Constraint Bypass (CVE-2026-43515)

by covepseng · 2026-07-05

Severity
High
CVE
CVE-2026-43515
Category
web
Affected product
Apache Tomcat — org.apache.catalina.realm.RealmBase.findSecurityConstraints()
Affected versions
7.0.0–7.0.109 (fixed 7.0.110), 8.5.0–8.5.100 (fixed 8.5.101), 9.0.0.M1–9.0.117 (fixed 9.0.118), 10.1.0.M1–10.1.54 (fixed 10.1.55), 11.0.0.M1–11.0.21 (fixed 11.0.22)
Disclosed
2026-07-05
Patch status
patched

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-06
Author / Researchercovepseng
CVE / AdvisoryCVE-2026-43515
Categoryweb
SeverityHigh
CVSS ScoreN/A (not published by upstream source reviewed; authentication/authorization bypass on a subset of configurations)
StatusPoC
Tagsapache-tomcat, java, security-constraint, auth-bypass, realm-base, servlet, web-xml, access-control
RelatedN/A

Affected Target

FieldValue
Software / SystemApache Tomcat — org.apache.catalina.realm.RealmBase.findSecurityConstraints()
Versions Affected7.0.0–7.0.109 (fixed 7.0.110), 8.5.0–8.5.100 (fixed 8.5.101), 9.0.0.M1–9.0.117 (fixed 9.0.118), 10.1.0.M1–10.1.54 (fixed 10.1.55), 11.0.0.M1–11.0.21 (fixed 11.0.22)
Language / PlatformJava (Tomcat internals); Go (PoC exploit client)
Authentication RequiredNo — the bypass allows an unauthenticated request to reach a resource that should require authentication
Network Access RequiredYes — HTTP access to the Tomcat instance

Summary

CVE-2026-43515 is a security constraint evaluation bug in Apache Tomcat’s RealmBase.findSecurityConstraints(). When a single <security-constraint> defines multiple <web-resource-collection> blocks that share the same URL pattern (e.g. *.html) but each declare a different HTTP method, Tomcat only enforces the constraint for the method declared in the first matching collection; subsequent collections targeting the same URL pattern with a different method are silently never evaluated. This allows requests using the “second” HTTP method (e.g. POST, when GET was declared first) to bypass authentication entirely. The bug requires an uncommon but spec-valid web.xml shape to be present.


Vulnerability Details

Root Cause

In RealmBase.findSecurityConstraints(), the matched boolean and pos index used to track which <web-resource-collection> matched a request’s URL pattern were declared outside the per-collection loop. Once collection[0] matched the URL pattern, pos was frozen at 0 for the remainder of the evaluation. A subsequent call to collection[pos].findMethod(method) therefore always checked the method list of collection[0], even when a later collection (collection[1], etc.) in the same constraint declared the actual HTTP method being used. If the requested method isn’t in collection[0]’s method list, findMethod() returns false, no constraint is added to the results, and AuthenticatorBase concludes the request is “not subject to any constraint” — bypassing authentication for that method entirely.

The fix (Apache commit 276087d9c7abbcecc6c4fb4e4b08cf64780c6e36) moves the matched flag inside the per-collection loop and replaces the frozen collection[pos] lookup with collection[j], so each collection is evaluated independently against its own method list.

Attack Vector

  1. The bug requires a web.xml with a single <security-constraint> containing two (or more) <web-resource-collection> blocks that share the same <url-pattern> (e.g. *.html) but declare different <http-method> values (e.g. one collection restricts GET, another restricts POST), protected by an <auth-constraint>.
  2. A GET request to the protected resource without credentials is correctly rejected (401), because it matches the first collection.
  3. A POST request to the same resource without credentials is incorrectly allowed through (200), because Tomcat’s constraint lookup only ever checks the first matched collection’s method list, and POST isn’t in it — the bug treats the resource as unconstrained for that method.
  4. An attacker sends an unauthenticated POST (or whichever method is declared only in a non-first collection) to reach content or functionality that should require the admin (or other) role.

Impact

Unauthenticated bypass of Tomcat’s declarative access control for any deployment using the split-collection web.xml pattern described above, allowing an attacker to read or interact with resources (via the un-enforced HTTP method) that the administrator intended to protect. Impact is scoped to deployments using this specific, uncommon-but-valid configuration shape; standard single-collection or no-method constraints are unaffected.


Environment / Lab Setup

Target: Apache Tomcat 11.0.0-M1 (Dockerfile pins this affected version) with a
        web.xml containing the vulnerable split web-resource-collection pattern
        protecting /protected/secret.html.

Requirements: Podman >= 4.0 (or Docker), Go >= 1.22.

Build & run:
  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

Proof of Concept

PoC Script

See exploit/exploit.go in this folder, plus lab files dockerfile, web.xml, tomcat-users.xml, logging.properties.

1
2
3
4
5
6
cd exploit
go run exploit.go \
  -target   http://localhost:8080 \
  -path     /protected/secret.html \
  -username validuser \
  -password s3cret!

The exploit issues three probes: (1) GET without credentials, expected 401 (constraint enforced); (2) POST without credentials — on vulnerable Tomcat this returns 200, confirming the bypass; (3) GET with valid credentials as a sanity check that authenticated access still works. The verbose Tomcat log line “Not subject to any constraint” for the POST request is the direct confirmation that RealmBase never matched the second collection.


Detection & Indicators of Compromise

Tomcat FINE-level log signature (logging.properties enables this verbosity):
  AuthenticatorBase.invoke  Calling authenticate()          <- GET, correctly enforced
  AuthenticatorBase.invoke  Failed authenticate() test       <- 401
  AuthenticatorBase.invoke  Not subject to any constraint    <- POST/bypass, 200

Signs of compromise:

  • Access log entries showing 200 responses for non-GET methods (POST, PUT, DELETE) against paths matched by extension-based security constraints that should require authentication.
  • web.xml configurations containing a single <security-constraint> with multiple <web-resource-collection> blocks sharing a URL pattern but different <http-method> values — a configuration smell worth auditing even before observing exploitation.
  • Unexplained access to resources under authenticated paths without corresponding successful authentication events in access/auth logs.

Remediation

ActionDetail
Primary fixUpgrade to a patched Tomcat release: 7.0.110, 8.5.101, 9.0.118, 10.1.55, or 11.0.22 (or later), which include commit 276087d9c7abbcecc6c4fb4e4b08cf64780c6e36 fixing RealmBase.findSecurityConstraints().
Interim mitigationAudit web.xml for <security-constraint> blocks with multiple <web-resource-collection> entries sharing the same URL pattern but different HTTP methods, and rewrite them as separate <security-constraint> blocks (one per method) until patched, which is not subject to the frozen-index bug.

References


Notes

Mirrored from https://github.com/covepseng/cve-2026-43515-poc on 2026-07-05.