CVE-2026-43515
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Apache Tomcat is an open-source implementation of the Jakarta Servlet, Jakarta Server Pages, Jakarta Expression Language, Jakarta WebSocket, Jakarta Annotations, and Jakarta Authentication specifications, providing a pure Java HTTP web server environment for running Java code. It is one of the most widely used Java application servers.
A moderate-severity vulnerability (CVE-2026-43515) has been identified in Apache Tomcat where, when a single security constraint defined multiple <web-resource-collection> blocks with different HTTP methods all matching the same extension pattern (for example, *.html), only the HTTP methods from the first matching collection were enforced. The remaining methods were treated as having no constraint and were served without the configured authentication or authorization.
Per OWASP: Incorrectly Configured Access Control occurs when access-control rules are present in configuration but are not consistently enforced at runtime. In this case, an administrator's deployment descriptor (web.xml) lists protection for several HTTP methods on an extension pattern, but Tomcat silently applies the protection to only the first method, leaving the others unprotected.
This issue affects versions 8.5.0 through 8.5.100, 9.0.0.M1 through 9.0.117, 10.1.0-M1 through 10.1.54, and 11.0.0-M1 through 11.0.21 of Apache Tomcat.
Details
Module Info
- Product: Apache Tomcat
- Affected packages: tomcat-catalina, tomcat-embed-core
- Affected versions: >=8.5.0 <=8.5.100, >=9.0.0.M1 <=9.0.117, >=10.1.0-M1 <=10.1.54, >=11.0.0-M1 <=11.0.21
- GitHub repository: https://github.com/apache/tomcat
- Published packages:
- Package manager: Maven
- Fixed in:
- NES for Apache Tomcat
- Apache Tomcat 11.0.22, 10.1.55, 9.0.118 (OSS)
Vulnerability Info
The bug lives in findSecurityConstraints(Request, Context) in org.apache.catalina.realm.RealmBase. The method iterates each configured SecurityConstraint and, for each constraint, walks its SecurityCollection[] looking for a URL pattern that matches the request URI. When the matching pattern is an extension pattern such as *.html, the pre-fix code declared the matched flag and the pos index **outside** the per-collection loop:
boolean matched = false;
int pos = -1;
for (int j = 0; j < collection.length; j++) {
String[] patterns = collection[j].findPatterns();
if (patterns == null) {
continue;
}
for (int k = 0; k < patterns.length && !matched; k++) {
String pattern = patterns[k];
if (pattern.startsWith("*.")) {
int slash = uri.lastIndexOf('/');
int dot = uri.lastIndexOf('.');
if (slash >= 0 && dot > slash && dot != uri.length() - 1 &&
uri.length() - dot == pattern.length() - 1) {
if (pattern.regionMatches(1, uri, dot, uri.length() - dot)) {
matched = true;
pos = j;
}
}
}
}
}
if (matched) {
found = true;
if (collection[pos].findMethod(method)) {
if (results == null) {
results = new ArrayList<>();
}
results.add(constraints[i]);
}
}
Because the inner loop's guard is k < patterns.length && !matched, and matched is never reset across collections, as soon as any collection matched the extension, pos was pinned to that first collection's index. The method check then only consulted collection[pos].findMethod(method), the first matching collection's <http-method> list. Any later collection in the same constraint that defined the same *.ext pattern with a different HTTP method was silently dropped from enforcement.
The configuration shape that triggers the bug is a single <security-constraint> with two or more <web-resource-collection> blocks targeting the same extension pattern with different methods:
<security-constraint>
<web-resource-collection>
<http-method>GET</http-method>
<url-pattern>*.html</url-pattern>
</web-resource-collection>
<web-resource-collection>
<http-method>POST</http-method>
<url-pattern>*.html</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>role1</role-name>
</auth-constraint>
</security-constraint>
The administrator intends both GET and POST on *.html to require role1. Pre-fix Tomcat enforces the constraint only on GET; POST requests to *.html are served without authentication.
The fix moves matched inside the per-collection loop and consults the current collection's methods directly via collection[j].findMethod(method) rather than via a stashed pos. Each collection is now evaluated independently and its own <http-method> list is consulted, so all per-method constraints for the same extension pattern are applied.
Mitigation
Only recent versions of Apache Tomcat are community-supported. Older versions (8.5.x and earlier) will not receive any updates to address this issue. NES for Tomcat includes an update to 8.5.x to address this issue. For more information, see here.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a patched version of Apache Tomcat.
Leverage a commercial support partner like HeroDevs for post-EOL security support.