Cabecera Penligente

CVE-2026-55276, Tomcat’s effective web.xml Log Can Lie

CVE-2026-55276 is easy to misread. It is not a public proof that every Apache Tomcat server is remotely exploitable. It is not the same class of issue as a default servlet RCE chain. The bug is narrower and, in some environments, more subtle: affected Tomcat versions can log an incomplete effective web.xml, leaving out special roles and empty authorization constraints that matter to access-control review. Apache describes the issue as “Logged effective web.xml is incomplete,” rates it Low, and says the flaw was reported to the Tomcat security team on June 16, 2026, then made public on June 29, 2026. Apache’s Tomcat 9, 10, and 11 security pages describe the same root condition: logic errors in effective web.xml generation meant that neither special roles nor empty authorization constraints were included in the logged effective web.xml. (Apache Tomcat)

That wording matters. The advisory is about the logged representation of the merged deployment descriptor. It is not saying that every configured authorization constraint stopped working at runtime. The safer mental model is this: the policy may still be enforced, but the evidence Tomcat prints for humans and tools may be incomplete. If your team uses the logged effective web.xml as a source of truth for security review, staging approval, compliance evidence, incident response, or automated configuration checks, CVE-2026-55276 can make your review wrong even when the application appears to start normally.

NVD lists CVE-2026-55276 as a CWE-670 Always-Incorrect Control Flow Implementation issue in Apache Tomcat and identifies the affected ranges as Tomcat 11.0.0-M1 through 11.0.22, 10.1.0-M1 through 10.1.55, 9.0.0.M1 through 9.0.118, and 8.5.0 through 8.5.100, with older unsupported versions possibly affected. NVD’s record also recommends upgrading to Tomcat 11.0.23, 10.1.56, or 9.0.119. (NVD)

CampoCurrent public information
CVECVE-2026-55276
ProductoApache Tomcat
Official issue titleLogged effective web.xml is incomplete
DebilidadCWE-670 Always-Incorrect Control Flow Implementation
Apache severityBajo
Affected Tomcat 11 range11.0.0-M1 through 11.0.22
Affected Tomcat 10.1 range10.1.0-M1 through 10.1.55
Affected Tomcat 9 range9.0.0.M1 through 9.0.118
Affected Tomcat 8.5 range8.5.0 through 8.5.100
Fixed supported versions11.0.23, 10.1.56, 9.0.119
Main condition to investigateWhether security review depends on logged effective web.xml output
Riesgo prácticoIncomplete access-control evidence, bad audit conclusions, incorrect automated checks
What it is notNot described by Apache as direct RCE

The key phrase is “logged effective web.xml.” If that sounds like a minor debugging feature, look at how Java web applications are actually operated. In many Tomcat environments, deployment descriptors are spread across application WEB-INF/web.xml, fragments in dependency JARs, annotations, container defaults, and application server context settings. Engineers turn on effective web.xml logging because they want to see the final merged view. Auditors may ask for it. Security engineers may archive it. SREs may compare it across releases. CI pipelines may scrape it. A bug in that output is not the same as broken authorization enforcement, but it can poison the evidence chain used to decide whether authorization was configured correctly.

Why effective web.xml exists

A Tomcat web application does not always run only from the literal WEB-INF/web.xml that a developer opens in an editor. The effective deployment descriptor is the result of combining several inputs. Tomcat’s own context configuration reference says the logEffectiveWebXml attribute, when set to true, logs the effective web.xml at INFO level when the application starts. The same documentation explains that this effective descriptor is produced by combining the application’s web.xml with Tomcat defaults, web-fragment.xml files, and discovered annotations. The default value is false. (Apache Tomcat)

That feature is useful because modern Java web applications often get servlet and security behavior from more than one place. A framework may contribute servlet mappings through annotations. A library may contribute a web-fragment.xml. The container may add defaults. A packaged WAR may differ from the source tree. When a production application starts, the effective descriptor answers a practical question: “What does Tomcat think this application’s deployment metadata looks like after all merging is done?”

For normal troubleshooting, that is helpful. For security, it can become dangerous if the log is treated as the final source of truth. CVE-2026-55276 shows exactly where that assumption breaks. The effective web.xml log could omit security-relevant constructs that an auditor or scanner needs to see: special roles and empty authorization constraints.

Configuration inputWhat it contributesWhy it matters for CVE-2026-55276
WEB-INF/web.xmlApplication-declared servlets, mappings, roles, constraints, login configThe original descriptor may contain special roles or deny-all constraints missing from the logged view
web-fragment.xmlMetadata from dependency JARsSecurity-relevant metadata may be merged into the final descriptor
Servlet annotationsMappings and security annotations from classesLogging may be used to understand what annotations contributed
Tomcat defaultsContainer-provided defaults and global webapp behaviorDefaults can affect the final runtime model
Context configurationPer-application or global context settingslogEffectiveWebXml itself is controlled through context configuration
Startup logsHuman-readable representation of the effective descriptorThe vulnerable output may be incomplete

The important operational mistake is simple: treating the log as the policy. The log is evidence, but it is not the only evidence. After CVE-2026-55276, teams should treat logged effective web.xml output from affected versions as potentially incomplete wherever special role names or empty authorization constraints are involved.

The Servlet security details that make this bug matter

The CVE description mentions “special roles” and “empty authorization constraints.” Those are not decorative XML details. They change the meaning of a security policy.

In a Java web application, a security-constraint usually combines a set of protected web resources with an authorization rule and, optionally, a transport guarantee. The authorization part appears under auth-constraint. Jakarta Servlet documentation states that an authorization constraint establishes an authentication requirement and names the roles permitted to perform constrained requests. It also defines two special role names: * is shorthand for all role names defined in the deployment descriptor, and ** is shorthand for any authenticated user independent of role. The same source states that an authorization constraint that names no roles means access must not be permitted under any circumstances. (Jakarta EE)

Those three cases are the heart of CVE-2026-55276:

Descriptor patternIntended meaningWhy omission from logs is dangerous
<role-name>*</role-name>All roles defined in the deployment descriptorA reviewer may think the constraint has no allowed role list or a different role list
<role-name>**</role-name>Any authenticated user, independent of roleA reviewer may miss that authentication is required even without a role mapping
Empty <auth-constraint/>Deny all access to the constrained resourcesA reviewer may miss a deliberate deny-all rule

A deny-all rule is especially easy to misinterpret if the log omits it. An empty <auth-constraint/> is not the same as no auth-constraint element. In Servlet security, the difference is critical. No authorization constraint may mean access is not restricted by that constraint. An empty authorization constraint means the constrained requests must not be permitted. Losing that distinction in a log can reverse the conclusion of a security review.

Here is a simplified deny-all example:

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Block internal metadata</web-resource-name>
    <url-pattern>/WEB-INF/*</url-pattern>
  </web-resource-collection>
  <auth-constraint/>
</security-constraint>

The intended policy is not “no roles were configured, so maybe it is open.” The intended policy is “nobody should access this through the web container.” If an affected Tomcat version logs an effective descriptor that fails to represent the empty authorization constraint correctly, a review tool or human reviewer can draw the wrong conclusion.

Now consider **:

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Authenticated downloads</web-resource-name>
    <url-pattern>/downloads/private/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
    <role-name>**</role-name>
  </auth-constraint>
</security-constraint>

This is not saying “admin only,” and it is not saying “anyone on the internet.” It is saying any authenticated user is allowed, independent of role. If the special role does not appear in the logged effective web.xml, a security review may miss that the resource is protected by authentication at all, or may incorrectly assume a concrete role mapping is missing.

Tomcat’s own SecurityConstraint API documentation also reflects the security significance of roles and collections. It describes methods for adding authorization roles, checking roles, adding protected web resource collections, and checking whether a constraint applies to a URI and method. It also notes special handling around an application-defined role named **. (Apache Tomcat)

What actually breaks in CVE-2026-55276

The vulnerable behavior is a representation bug in the logged effective descriptor. Apache’s Tomcat 11 security page states that logic errors in effective web.xml generation meant special roles and empty authorization constraints were not included in the logged effective web.xml; the same page says the issue was fixed with commits f844614c y e391c6b2 for Tomcat 11 and affected 11.0.0-M1 to 11.0.22. Tomcat 10.1 and Tomcat 9 pages describe the same issue and affected ranges for their branches. (Apache Tomcat)

That means a careful write-up should not call CVE-2026-55276 a generic Tomcat authorization bypass unless separate evidence proves that an authorization decision at runtime was wrong. The public Apache description is about the logged effective web.xml. It is possible for a security bug to be low severity and still matter to serious teams because it corrupts the evidence they use to reason about controls.

A useful way to think about it is to separate three layers:

CapaQuestionCVE-2026-55276 impact
Original descriptorWhat did the application or dependency declare?The original XML may still contain the right policy
Runtime enforcementWhat does Tomcat actually enforce for a request?Apache’s public description does not say this is directly broken
Logged effective descriptorWhat does Tomcat print as the merged policy?This is the layer Apache says is incomplete

Most bad triage comes from collapsing those layers into one. A scanner sees an affected version and labels it “critical.” An auditor sees a log and assumes it is the exact policy. A developer sees “Low” and ignores the bug. All three responses are incomplete. The right response is to upgrade, preserve the original descriptors, and verify the live access-control behavior instead of relying only on the log.

Why the severity can look inconsistent

Severity data around CVE-2026-55276 can look confusing. Apache’s own Tomcat security pages label the issue Low. NVD’s record carries the Apache description, affected versions, fixed versions, and CWE-670. Some vulnerability aggregation pages may display high or critical scores because they ingest ADP or enrichment data differently. OpenCVE’s mirrored CVE record, for example, includes the Apache CNA container with textual severity “low,” while also showing a CISA ADP Vulnrichment CVSS 3.1 vector with base score 9.1 and SSVC fields including exploitation “none.” (OpenCVE)

For defenders, the correct move is not to blindly choose the lowest or highest number. The public technical description should drive the first interpretation. Apache’s description does not describe direct unauthenticated code execution, file write, authentication bypass, or data exfiltration. It describes incomplete logging of the effective descriptor. That supports Apache’s Low rating for the generic case. At the same time, a low generic severity does not mean every organization has low operational exposure. If your governance process relies on logged effective web.xml as the main evidence for access-control correctness, the bug can undermine a control that auditors or customers expect you to trust.

SeñalWhat it saysHow to use it
Apache severityBajoTreat as the most relevant vendor severity for the described Tomcat behavior
NVD affected version dataBroad affected ranges across supported and EOL branchesUse it for inventory and patch targeting
CWE-670Control flow implementation always makes an incorrect decision in the affected logicUse it to understand why generated output can be systematically wrong
CISA ADP enrichment where presentMay show a higher generic vector in some mirrored recordsDo not let scoring override the actual public technical description
Internal riskDepends on how your team uses the logRaise priority if the log is part of audit, change approval, or compliance evidence

This is one of those cases where “Low” should mean “do not panic,” not “do nothing.”

Affected versions and upgrade paths

The supported Tomcat upgrade path is straightforward. NVD recommends Tomcat 11.0.23, 10.1.56, or 9.0.119 as fixed versions for CVE-2026-55276. (NVD) Apache’s Tomcat 9 page lists the fix under “Fixed in Apache Tomcat 9.0.119,” with CVE-2026-55276 affecting 9.0.0.M1 to 9.0.118. (Apache Tomcat) Apache’s Tomcat 10 page lists the fix under “Fixed in Apache Tomcat 10.1.56,” with the issue affecting 10.1.0-M1 to 10.1.55. (Apache Tomcat) Apache’s Tomcat 11 page lists the issue as affecting 11.0.0-M1 to 11.0.22 and fixed in the next security release line. (Apache Tomcat)

Tomcat branchGama afectadaFixed version pathLifecycle noteMedidas recomendadas
11.011.0.0-M1 through 11.0.2211.0.23 or laterSupported modern branchUpgrade and retest logging plus live authorization behavior
10.110.1.0-M1 through 10.1.5510.1.56 or laterSupported modern branchUpgrade through normal maintenance release process
9.09.0.0.M1 through 9.0.1189.0.119 or laterStill widely deployedUpgrade and plan branch lifecycle management
8.58.5.0 through 8.5.100No normal upstream 8.5 fix path listed in NVD recommendationEOLMigrate, isolate, or obtain vendor-supported maintenance
Older EOL branchesPossibly affectedNo normal upstream pathSin soporteTreat as platform risk, not just a single CVE ticket

Tomcat 8.5 deserves special attention. Apache announced that support for Tomcat 8.5.x would end on March 31, 2024, and stated that after that date releases from the 8.5.x branch would be highly unlikely, bugs affecting only that branch would not be addressed, and security vulnerability reports would not be checked against that branch. (Apache Tomcat) If your organization still runs Tomcat 8.5 because a vendor appliance, old WAR, or internal platform depends on it, CVE-2026-55276 should not be treated as an isolated patch item. It should trigger a lifecycle decision.

For supported branches, the fix is easy to describe: upgrade. For EOL branches, the decision is harder: migrate to a supported Tomcat branch, obtain a vendor-provided backport, isolate the workload, reduce reliance on logged effective descriptors, and document the residual risk.

Why scanners may produce noisy results

A scanner can detect an affected Tomcat version. It cannot automatically know whether your team uses logged effective web.xml as audit evidence. It may not know whether logEffectiveWebXml is enabled. It may not know whether your descriptors contain *, **, or empty authorization constraints. It may not know whether a vendor product embeds Tomcat and hides the real descriptor. That is why CVE-2026-55276 is a configuration-aware triage problem.

A useful scanner result should be the beginning of the workflow, not the end. The asset owner should answer these questions:

QuestionPor qué es importante
What Tomcat branch and exact version is running?Determines whether the runtime is in an affected range
Es logEffectiveWebXml enabled anywhere?Determines whether the vulnerable logging path is operationally relevant
Do original descriptors use *, **, or empty <auth-constraint/>?Determines whether the omitted constructs exist
Does any internal process scrape or archive the logged effective descriptor?Determines whether audit evidence may be corrupted
Are access-control decisions verified with live requests?Prevents bad logs from becoming bad conclusions
Is the Tomcat instance embedded in a product?Affected version may not appear in a visible banner
Is the branch EOL?Determines whether a normal upstream patch is available

A banner-only finding such as “Apache Tomcat CVE-2026-55276 detected” is incomplete. The better finding is: “Tomcat 10.1.53 is affected by CVE-2026-55276; logEffectiveWebXml is enabled; original descriptors contain an empty <auth-constraint/> para /internal/*; the startup log omits that deny-all constraint; live request testing confirms access is denied; upgraded to 10.1.56 and verified the logged descriptor now preserves the constraint.”

That is a much more useful security result.

Safe inventory checks

Start with version inventory. Tomcat’s exact version may be visible through package managers, container image metadata, the catalina.jar manifest, Maven dependency trees, or product-specific distribution paths. Do not rely only on an HTTP Server header. Many production systems hide or rewrite it.

# Linux package inventory examples
rpm -qa | grep -i tomcat || true
dpkg -l | grep -i tomcat || true

# Common Tomcat home checks
find /opt /usr/local /var/lib -maxdepth 4 -type f -name catalina.jar 2>/dev/null

# Read Tomcat implementation metadata from catalina.jar when available
for jar in $(find /opt /usr/local /var/lib -type f -name catalina.jar 2>/dev/null); do
  echo "=== $jar ==="
  unzip -p "$jar" META-INF/MANIFEST.MF | grep -E "Implementation-Version|Specification-Version" || true
done

For Maven-based applications, check whether Tomcat is embedded or bundled:

# Maven dependency tree, useful for embedded Tomcat in Java applications
mvn -q dependency:tree | grep -E "org.apache.tomcat|tomcat-embed|tomcat-catalina" || true

For Gradle:

./gradlew dependencies --configuration runtimeClasspath | grep -E "org.apache.tomcat|tomcat-embed|tomcat-catalina" || true

For containers:

# Inspect image metadata and file paths, then enter a safe read-only shell if needed
docker image inspect your-image:tag | jq '.[0].Config.Labels, .[0].Config.Env'

docker run --rm --entrypoint sh your-image:tag -c '
  find / -type f -name catalina.jar 2>/dev/null |
  while read jar; do
    echo "=== $jar ==="
    unzip -p "$jar" META-INF/MANIFEST.MF 2>/dev/null | grep -E "Implementation-Version|Specification-Version" || true
  done
'

These commands do not exploit anything. They answer the first defensive question: “Am I running a version that falls into the public affected range?”

Find whether logEffectiveWebXml is enabled

Next, check whether the vulnerable output path matters in your environment. Tomcat’s context documentation says logEffectiveWebXml defaults to false, so not every affected Tomcat version will actually emit this log. (Apache Tomcat) Still, teams often enable it temporarily during debugging, hardening, staging validation, or compliance review. It can also be inherited from global context configuration.

Search the usual context locations:

# Search Tomcat base and application descriptors for logEffectiveWebXml
grep -RIn --include="*.xml" "logEffectiveWebXml" \
  "$CATALINA_BASE/conf" \
  "$CATALINA_HOME/conf" \
  /opt /usr/local /var/lib 2>/dev/null || true

Common places to inspect include:

$CATALINA_BASE/conf/context.xml
$CATALINA_BASE/conf/[engine]/[host]/context.xml.default
$CATALINA_BASE/conf/[engine]/[host]/appname.xml
META-INF/context.xml inside a WAR
A deployment system template that generates context XML

A result like this means the startup log may include the affected output:

<Context logEffectiveWebXml="true">
</Context>

A result like this may still matter if it is inherited by multiple applications:

<!-- $CATALINA_BASE/conf/context.xml -->
<Context logEffectiveWebXml="true">
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>

The absence of logEffectiveWebXml="true" lowers the practical relevance of the logging bug, but it does not remove the need to upgrade affected supported versions. Security releases often fix multiple issues in the same maintenance window, and June 2026 Tomcat advisories included several distinct vulnerabilities across Tomcat branches. Apache’s Tomcat 9 and 10 security pages list CVE-2026-55276 alongside other fixes such as CVE-2026-55956, CVE-2026-55955, CVE-2026-53434, CVE-2026-53404, and CVE-2026-50229 in the same release area. (Apache Tomcat)

Search for the affected descriptor patterns

After version and logging checks, inspect the original descriptors. The goal is to find whether your applications use the constructs that CVE-2026-55276 can omit from the logged output.

For exploded applications:

# Find special role names and empty auth constraints in exploded webapps
find /path/to/webapps -type f \( -name "web.xml" -o -name "web-fragment.xml" -o -name "tomcat-web.xml" \) -print0 |
while IFS= read -r -d '' file; do
  echo "=== $file ==="
  grep -nE "<role-name>[[:space:]]*(\*|\*\*)[[:space:]]*</role-name>|<auth-constraint[[:space:]]*/>" "$file" || true
done

For WAR files:

# Inspect descriptors inside WARs without extracting everything permanently
for war in $(find /path/to/webapps -type f -name "*.war"); do
  echo "=== $war ==="
  jar tf "$war" | grep -E "WEB-INF/web.xml|web-fragment.xml|tomcat-web.xml" || true
  unzip -p "$war" WEB-INF/web.xml 2>/dev/null |
    grep -nE "<role-name>[[:space:]]*(\*|\*\*)[[:space:]]*</role-name>|<auth-constraint[[:space:]]*/>" || true
done

For dependency JAR fragments inside a WAR:

# Extract and inspect web-fragment.xml files from WEB-INF/lib JARs
tmpdir=$(mktemp -d)
war="/path/to/app.war"

unzip -q "$war" "WEB-INF/lib/*.jar" -d "$tmpdir"

find "$tmpdir" -type f -name "*.jar" -print0 |
while IFS= read -r -d '' jar; do
  if jar tf "$jar" | grep -q "META-INF/web-fragment.xml"; then
    echo "=== $jar ==="
    unzip -p "$jar" META-INF/web-fragment.xml |
      grep -nE "<role-name>[[:space:]]*(\*|\*\*)[[:space:]]*</role-name>|<auth-constraint[[:space:]]*/>" || true
  fi
done

rm -rf "$tmpdir"

The point is not to prove exploitation. The point is to find whether your deployment metadata contains the exact security constructs that the vulnerable log path can misrepresent.

A defensive XML scanner for local evidence

For repeatable audits, a small local parser is safer than a pile of fragile grep commands. The following Python script scans a directory or extracted WAR tree for web.xml, tomcat-web.xmly web-fragment.xml, then reports constraints containing *, **, or empty authorization constraints.

#!/usr/bin/env python3
from __future__ import annotations

import sys
from pathlib import Path
import xml.etree.ElementTree as ET


TARGET_NAMES = {"web.xml", "tomcat-web.xml", "web-fragment.xml"}


def strip_ns(tag: str) -> str:
    if "}" in tag:
        return tag.split("}", 1)[1]
    return tag


def children_named(elem: ET.Element, name: str) -> list[ET.Element]:
    return [child for child in list(elem) if strip_ns(child.tag) == name]


def text_of(elem: ET.Element | None) -> str:
    if elem is None or elem.text is None:
        return ""
    return elem.text.strip()


def analyze_descriptor(path: Path) -> list[dict[str, object]]:
    findings: list[dict[str, object]] = []

    try:
        tree = ET.parse(path)
    except ET.ParseError as exc:
        return [{
            "file": str(path),
            "type": "parse_error",
            "detail": str(exc),
        }]

    root = tree.getroot()

    for constraint in root.iter():
        if strip_ns(constraint.tag) != "security-constraint":
            continue

        auth_constraints = children_named(constraint, "auth-constraint")

        if not auth_constraints:
            continue

        for auth in auth_constraints:
            role_elems = children_named(auth, "role-name")
            roles = [text_of(role) for role in role_elems]

            if len(role_elems) == 0:
                findings.append({
                    "file": str(path),
                    "type": "empty_auth_constraint",
                    "detail": "Deny-all auth-constraint with no role-name elements",
                })

            for role in roles:
                if role in {"*", "**"}:
                    findings.append({
                        "file": str(path),
                        "type": "special_role",
                        "role": role,
                        "detail": f"Special Servlet role-name {role}",
                    })

    return findings


def main() -> int:
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} /path/to/exploded-war-or-config-tree", file=sys.stderr)
        return 2

    root = Path(sys.argv[1])
    if not root.exists():
        print(f"Path does not exist: {root}", file=sys.stderr)
        return 2

    all_findings: list[dict[str, object]] = []

    for path in root.rglob("*"):
        if path.is_file() and path.name in TARGET_NAMES:
            all_findings.extend(analyze_descriptor(path))

    if not all_findings:
        print("No special roles or empty auth-constraint elements found in scanned descriptors.")
        return 0

    for finding in all_findings:
        print(finding)

    return 1


if __name__ == "__main__":
    raise SystemExit(main())

Use it like this:

python3 scan_tomcat_constraints.py /path/to/exploded/application

For a WAR:

tmpdir=$(mktemp -d)
unzip -q /path/to/app.war -d "$tmpdir"
python3 scan_tomcat_constraints.py "$tmpdir"
rm -rf "$tmpdir"

This script deliberately avoids live HTTP probing. It helps you build a local evidence list: which descriptors contain the constructs that may be omitted from the vulnerable log output.

Live behavior still needs to be tested

CVE-2026-55276 is about logs, but defenders should still verify access-control behavior. The reason is practical, not because the public advisory says runtime enforcement is broken. If the log is incomplete, the only safe way to confirm the real security outcome is to test the application behavior directly in an authorized staging or production-safe validation window.

A minimal test plan should include:

Test dimensionEjemplosPor qué es importante
User stateUnauthenticated, authenticated low-privilege user, correct-role userConfirms whether ** or role-based rules behave as expected
HTTP methodGET, HEAD, OPTIONS, POST, PUT, DELETE, TRACE where applicablePrevents method-specific assumptions from hiding bad behavior
URL pathExact path, prefix path, extension path, default servlet pathServlet mapping and URL pattern matching change outcomes
TransportHTTP versus HTTPS where applicableuser-data-constraint may require confidential transport
Proxy routeThrough reverse proxy and direct backend where allowedProxy controls may hide backend behavior
After upgradeSame tests after Tomcat updateConfirms remediation and catches regressions

For example, if a path is supposed to be denied to everyone because of an empty <auth-constraint/>, the validation should prove that unauthenticated and authenticated users both fail:

# Expected outcome: denied
curl -i https://staging.example.com/internal/metadata.json

# Expected outcome: still denied even with a valid low-privilege session
curl -i \
  -H "Cookie: JSESSIONID=REDACTED_LOW_PRIV_SESSION" \
  https://staging.example.com/internal/metadata.json

If a path is supposed to allow any authenticated user through **, the validation should prove that unauthenticated users fail and authenticated users succeed:

# Expected outcome: 401, 403, or redirect to login
curl -i https://staging.example.com/downloads/private/report.pdf

# Expected outcome: 200 or expected application response for an authenticated user
curl -i \
  -H "Cookie: JSESSIONID=REDACTED_VALID_SESSION" \
  https://staging.example.com/downloads/private/report.pdf

Do not paste production session cookies into shared tickets. Store evidence in the form your organization normally accepts: sanitized request, sanitized response headers, status code, timestamp, target path, user role, Tomcat version, and exact descriptor snippet.

The dangerous audit failure

Where CVE-2026-55276 Breaks the Evidence Chain

The most realistic harm from CVE-2026-55276 is not a dramatic exploit chain. It is a bad audit decision. Consider an enterprise application that blocks a sensitive export directory:

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Deny direct export access</web-resource-name>
    <url-pattern>/exports/internal/*</url-pattern>
  </web-resource-collection>
  <auth-constraint/>
</security-constraint>

A security engineer starts Tomcat with logEffectiveWebXml="true" and archives the startup log as evidence. In an affected version, the logged effective descriptor may omit the empty authorization constraint. A reviewer later sees a resource collection but does not see the deny-all semantics. The reviewer may conclude that the path is not explicitly blocked, or that the application’s access-control posture changed between releases.

Now reverse the case. Suppose the original descriptor uses ** to permit any authenticated user:

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Authenticated help center</web-resource-name>
    <url-pattern>/customer/help/private/*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
    <role-name>**</role-name>
  </auth-constraint>
</security-constraint>

If the logged effective descriptor omits the special role, a reviewer may think authentication was not configured or that role mapping is incomplete. That can trigger false positives, unnecessary emergency work, or wrong remediation. In regulated environments, false evidence can be expensive even when the live application is safe.

The pattern is the same: the log lies by omission.

Bad conclusions to avoid

CVE-2026-55276 invites several wrong conclusions.

The first bad conclusion is “critical Tomcat RCE.” Apache does not describe the issue that way. The public description is incomplete logging of effective web.xml, not direct code execution.

The second bad conclusion is “nothing to fix because Apache says Low.” If you run an affected supported Tomcat version, upgrade. If your organization relies on logged effective descriptors for security evidence, review recent evidence generated from affected versions.

The third bad conclusion is “the logged effective web.xml proves the access control.” That is exactly the assumption this CVE breaks.

The fourth bad conclusion is “we can close this because logEffectiveWebXml is false today.” That may lower immediate exposure, but it does not answer whether the setting was enabled during recent audits, staging approvals, incident reviews, or previous release windows. It also does not address the normal security need to stay on patched Tomcat releases.

The fifth bad conclusion is “all Tomcat security constraints are unreliable.” That overstates the advisory. The described problem is about logged generation of the effective descriptor, not a general statement that Tomcat ignores security constraints.

Related Tomcat issues that help frame the risk

CVE-2026-55276 is not alone in showing how small Tomcat configuration semantics can affect security outcomes. It belongs in a broader family of Tomcat lessons: servlet mappings, method constraints, default servlet behavior, Realms, certificate validation, and deployment descriptors all matter.

CVE-2026-55956 is a close 2026 comparison because it concerns Tomcat default servlet security constraints. Apache’s Tomcat 9 page says that if security constraints were specified for the default servlet, any method or method omission configured as part of the constraint was ignored; Apache rated that issue Moderate and fixed it in Tomcat 9.0.119 for the 9.0 branch. (Apache Tomcat) The mechanics differ from CVE-2026-55276: CVE-2026-55956 concerns method-specific constraint behavior on the default servlet, while CVE-2026-55276 concerns incomplete logging of effective web.xml. The shared lesson is that descriptor semantics should be tested, not merely read. A related Penligent write-up on CVE-2026-55956 goes deeper into Tomcat default servlet method constraints and why version-only triage can miss the real configuration path. (Penligente)

CVE-2026-43515 is another useful comparison. Apache’s Tomcat 11 page says that when multiple security constraints defined an HTTP method constraint for the same extension pattern, only the first method constraint was applied; the issue affected Tomcat 11.0.0-M1 to 11.0.21 in that branch and was fixed before the June 2026 advisory group. (Apache Tomcat) That is not the same bug, but it reinforces the same engineering habit: if authorization depends on descriptor merging or method-specific constraints, write regression tests for the actual HTTP behavior.

CVE-2025-24813 is a different and more severe default servlet story. NVD describes it as a path-equivalence issue in Apache Tomcat involving a write-enabled Default Servlet, partial PUT support, and additional conditions that could lead to remote code execution, information disclosure, or malicious content injection. NVD’s description also makes clear that writes enabled for the default servlet were disabled by default and that the RCE case required file-based session persistence with the default storage location plus a library usable in a deserialization attack. (NVD) The relevance is not that CVE-2026-55276 is the same. It is not. The relevance is that Tomcat risk often depends on configuration details that generic headlines flatten.

CVE-2026-55957, disclosed in the same broad Tomcat advisory period, is different again. Penligent’s search result summary and Apache-related public records describe it as a Tomcat JNDIRealm GSSAPI authentication bypass path. The lesson for CVE-2026-55276 is not about JNDIRealm specifically. It is that Tomcat vulnerability response needs configuration-aware triage. A Realm bug matters when that Realm path is configured. A default servlet method bug matters when the default servlet and method constraints are in play. An effective web.xml logging bug matters when teams trust that log as evidence.

CVEMain areaWhy it is relevantWhat defenders should test
CVE-2026-55276Logged effective web.xmlLog output may omit special roles and empty authorization constraintsCompare original descriptors, logged output, and live access behavior
CVE-2026-55956Default servlet method constraintsMethod or method omission handling could differ from intended policyTest each method against default servlet paths
CVE-2026-43515Method constraints on extension patternsMultiple constraints could be applied incorrectlyTest overlapping constraints and extension patterns
CVE-2025-24813Default servlet partial PUT and write-enabled conditionsConfiguration can turn default servlet behavior into severe impactKeep default servlet read-only and validate upload/session settings
CVE-2026-55957JNDIRealm GSSAPI authenticationExposure depends on specific Realm configurationConfirm authentication mechanism and Realm path

This comparison prevents two common errors: overstating CVE-2026-55276 as an RCE and understating it as irrelevant. It is a logging correctness flaw with real security-process consequences.

Hardening the review process

The durable fix is not only “install the maintenance release.” The durable fix is to stop treating a single generated log as the only proof of access control.

A strong Tomcat access-control review should preserve four kinds of evidence:

Evidence typeEjemploPor qué es importante
Source descriptorWEB-INF/web.xml, tomcat-web.xml, web-fragment.xmlShows declared policy before Tomcat processing
Runtime versionTomcat branch and exact versionShows whether CVE-2026-55276 applies
Effective descriptor logStartup output if enabledUseful after patch, but not sufficient on affected versions
Live request resultHTTP status and response for users and rolesProves actual enforcement behavior

The review should also separate “configuration exists” from “configuration works.” A descriptor may say a path is denied. A log may say something incomplete. A request test proves what the container and application actually do for a specific path, method, and user state.

For critical applications, turn these checks into regression tests. A Java integration test, a lightweight curl-based staging test, or a CI job against a deployed test environment can validate expected access-control outcomes. The exact tooling matters less than the habit: never rely on a generated descriptor alone when a real request can prove the boundary.

Practical remediation plan

A clean remediation plan for CVE-2026-55276 should have three tracks: patch, evidence review, and process correction.

PasoAcciónOutput
1Identify Tomcat versions across hosts, containers, and embedded appsAffected asset list
2Identify whether logEffectiveWebXml is enabledSystems where the vulnerable logging path matters
3Search original descriptors for *, **, and empty <auth-constraint/>List of affected policy constructs
4Upgrade supported branches to 11.0.23, 10.1.56, or 9.0.119 or laterPatched runtime
5For Tomcat 8.5 and older, document EOL pathMigration, vendor patch, isolation, or compensating controls
6Reproduce startup logging after upgrade where safeCorrected evidence output
7Test live access behavior for sensitive pathsProof that runtime policy matches intent
8Update audit proceduresLogs are no longer treated as sole source of truth
9Archive sanitized before-and-after evidenceCloseable internal ticket

Do not skip step 7. If an access-control policy is important enough to audit, it is important enough to test with real requests under controlled authorization.

Compensating controls for legacy systems

Some teams cannot upgrade immediately. A vendor product may embed Tomcat 8.5. A regulated system may require change windows. An internal app may be stuck on an old Java baseline. That does not make the risk disappear.

For unsupported or hard-to-upgrade systems, use compensating controls while planning migration:

ControlarPara qué sirveLimitación
Preserve original WARs and descriptorsGives reviewers the real source XMLDoes not fix the vulnerable logging behavior
Disable reliance on logged effective descriptorPrevents bad evidence from driving decisionsDoes not update Tomcat
Add live access-control testsConfirms actual behaviorMust be maintained as paths change
Restrict direct backend accessForces traffic through controlled proxy pathsCan be bypassed by internal routes if poorly designed
Limit risky HTTP methods at proxyReduces method-related downstream riskNot a fix for CVE-2026-55276 itself
Vendor escalationMay provide supported backportTimeline may be outside your control
Migration planMoves to supported Tomcat branchRequires engineering work and testing

For Tomcat 8.5, lifecycle status should be explicit in the risk record. Apache’s EOL notice says security vulnerability reports are no longer checked against the 8.5 branch after support ended. (Apache Tomcat) That is bigger than one CVE.

What to put in an internal finding

A good internal report should avoid panic language and avoid minimizing language. The finding should say exactly what is known.

finding:
  title: "Apache Tomcat CVE-2026-55276, incomplete logged effective web.xml"
  severity:
    vendor: "Low"
    internal_priority: "Medium if logged effective web.xml is used for security evidence"
  affected_asset:
    hostname: "app-prod-17"
    application: "customer-portal"
    tomcat_version_before_fix: "10.1.53"
    tomcat_version_after_fix: "10.1.56"
  condition:
    logEffectiveWebXml: true
    special_roles_found:
      - "**"
    empty_auth_constraints_found:
      - "/internal/*"
  evidence:
    original_descriptor: "WEB-INF/web.xml contains deny-all auth-constraint for /internal/*"
    startup_log_before_fix: "Logged effective web.xml did not include the empty auth-constraint"
    live_request_before_fix: "Unauthenticated and authenticated users were denied as expected"
    startup_log_after_fix: "Logged effective web.xml preserved the relevant constraint"
    live_request_after_fix: "Access-control behavior unchanged and correct"
  remediation:
    - "Upgraded Tomcat to fixed branch"
    - "Updated audit procedure to require original descriptors and live request evidence"
    - "Added regression tests for protected paths"
  residual_risk:
    - "No known direct runtime authorization bypass observed for this finding"
    - "Future descriptor reviews cannot rely on startup logs alone"

The strongest sentence in the report should be specific: “The logged evidence was incomplete; live authorization behavior was tested separately.” That gives engineering, compliance, and management the same picture.

How automated validation should handle this CVE

Automated security workflows can help with CVE-2026-55276, but only if they understand what must be validated. A naive workflow that sees an affected Tomcat version and emits “critical exploit confirmed” is worse than no automation. A better workflow collects version evidence, checks context settings, extracts descriptors, identifies special roles and empty authorization constraints, compares startup logs, and runs authorized request tests for representative paths.

That distinction matters for AI-assisted security tooling. In an authorized workflow, a platform should not merely summarize scanner output. It should preserve proof: exact version, configuration location, descriptor snippet, request and response evidence, and remediation retest. Penligent’s public site emphasizes evidence-first results, reproducible artifacts, and turning findings into verified impact rather than scanner noise. (Penligente) That kind of evidence discipline is particularly relevant for CVE-2026-55276 because the vulnerable artifact is itself an evidence source. If the evidence can lie, the validation workflow must cross-check it.

A practical automated validation sequence looks like this:

Automation stageGood behaviorBad behavior
Version detectionIdentify exact Tomcat branch and source of version evidenceTrust only a public banner
Config discoveryCheck context files for logEffectiveWebXmlAssume every affected Tomcat emits the vulnerable log
Descriptor extractionParse original XML and fragmentsScrape only startup logs
Policy analysisIdentifique *, **, and empty constraintsTreat missing role names as open access without context
Live validationTest expected allow and deny cases in scopeFire generic exploit payloads
InformesShow before-and-after evidenceProduce a vague severity label

CVE-2026-55276 rewards careful validation and punishes superficial automation.

Logging is not a control boundary

Security teams often want logs to answer more than logs can answer. Logs are evidence of what a system emitted at a point in time. They are not necessarily the authoritative model of the system’s policy. CVE-2026-55276 is a clean example of that gap.

For Tomcat, the safer review model is:

Original descriptor tells you what was declared.
Tomcat version tells you what implementation processed it.
Startup log tells you what Tomcat printed.
Live request tests tell you what happened.
Only the combination is strong evidence.

If those sources disagree, do not average them. Investigate. The logged effective web.xml from an affected Tomcat version may omit security-relevant constructs. The original descriptor may be correct. The live behavior may still be correct. Or a separate configuration issue may exist. The job is to prove which case you have.

A post-upgrade checklist

After upgrading to a fixed release, do not close the ticket immediately. Run a short post-upgrade checklist:

ConsulteExpected result
Confirm Tomcat versionRuntime reports 11.0.23, 10.1.56, 9.0.119, or later supported release
Confirm application starts cleanlyNo startup errors from descriptor parsing or fragment merging
Confirm logEffectiveWebXml behavior if enabledLogged descriptor includes special roles and empty authorization constraints
Compare original descriptors to logged outputNo unexpected omission of *, **, or deny-all constraints
Test unauthenticated access to protected pathsDenied where expected
Test authenticated low-privilege accessAllowed or denied according to policy
Test correct-role accessAllowed where expected
Retain evidenceTicket includes version, descriptor, request, response, and timestamp
Update process docsStartup logs are not accepted as sole access-control evidence

If you do not use logEffectiveWebXml, the post-upgrade focus can be shorter: confirm version, confirm application behavior, and update inventory. But if the setting is enabled, the before-and-after comparison is valuable because it proves the exact issue is remediated.

PREGUNTAS FRECUENTES

What is CVE-2026-55276?

  • CVE-2026-55276 is an Apache Tomcat vulnerability titled “Logged effective web.xml is incomplete.”
  • Apache describes it as a logic error in effective web.xml generation where special roles and empty authorization constraints were not included in the logged effective descriptor.
  • NVD maps it to CWE-670 and lists affected Tomcat 11, 10.1, 9, and 8.5 version ranges.
  • The recommended fixed versions are Tomcat 11.0.23, 10.1.56, and 9.0.119. (NVD)

Does CVE-2026-55276 mean Tomcat access control is bypassed?

  • Not based on Apache’s public description.
  • The described issue is incomplete logging of the effective web.xml, not direct failure of runtime authorization enforcement.
  • The risk is that humans or tools may make wrong decisions from incomplete startup log evidence.
  • You should still test live access-control behavior because logs alone are not enough evidence.

Which Tomcat versions are affected?

  • Tomcat 11.0.0-M1 through 11.0.22 are listed as affected.
  • Tomcat 10.1.0-M1 through 10.1.55 are listed as affected.
  • Tomcat 9.0.0.M1 through 9.0.118 are listed as affected.
  • Tomcat 8.5.0 through 8.5.100 are listed as affected.
  • Other versions that have reached end of support may also be affected, according to NVD. (NVD)

Why do empty auth constraints matter?

  • An empty <auth-constraint/> usually means deny all access to the constrained requests.
  • It is not the same as having no authorization constraint at all.
  • If the logged effective web.xml omits an empty authorization constraint, a reviewer may miss a deliberate deny-all policy.
  • The safest validation is to inspect the original descriptor and test the actual request behavior.

Why do the special roles * and ** matter?

  • In Servlet security, * is shorthand for all role names defined in the deployment descriptor.
  • ** means any authenticated user, independent of role.
  • These are compact security expressions, not normal decorative role strings.
  • If they are omitted from logged effective web.xml, authentication and authorization intent can be misunderstood. (Jakarta EE)

How should I safely verify whether my environment is affected?

  • Confirm the exact Tomcat version from package metadata, JAR manifests, build dependencies, or container images.
  • Check whether logEffectiveWebXml="true" is enabled in context configuration.
  • Search original descriptors for <role-name>*</role-name>, <role-name>**</role-name>, and empty <auth-constraint/>.
  • Do not rely only on startup logs from affected versions.
  • Test live access-control behavior in an authorized environment and preserve sanitized evidence.

Is there evidence of active exploitation?

  • The public Apache description is about incomplete logging, not a direct exploit path.
  • The CVE record data mirrored by OpenCVE includes CISA ADP SSVC information showing exploitation as “none” in the reviewed record, while also showing scoring data that may appear more severe than Apache’s Low rating. (OpenCVE)
  • Lack of known exploitation does not remove the need to patch supported Tomcat versions.
  • Prioritize higher if your audit, compliance, or deployment approval process relied on logged effective web.xml output from affected versions.

What should I do after upgrading?

  • Confirm the runtime version moved to 11.0.23, 10.1.56, 9.0.119, or a later supported fixed release.
  • Si logEffectiveWebXml is enabled, compare the logged output against original descriptors containing special roles or empty authorization constraints.
  • Retest representative protected paths with unauthenticated users, authenticated users, and correct-role users.
  • Update internal review guidance so startup logs are not accepted as the only proof of access-control configuration.
  • For Tomcat 8.5 or older unsupported branches, document a migration or vendor-supported maintenance plan.

Cerrar

CVE-2026-55276 is a low-severity Tomcat vulnerability with an evidence problem at its center. It does not deserve RCE panic language. It also does not deserve to be ignored. If your team uses logged effective web.xml output to prove access-control configuration, affected Tomcat versions can give you an incomplete story.

The right response is direct: upgrade supported Tomcat branches, identify whether logEffectiveWebXml was enabled, inspect original deployment descriptors for special roles and empty authorization constraints, and verify sensitive paths with real authorized request tests. For legacy Tomcat 8.5 systems, treat the CVE as another sign that the platform needs a lifecycle plan. A fixed Tomcat version closes the logging bug. A better evidence process keeps the same class of mistake from shaping future security decisions.

Comparte el post:
Entradas relacionadas
es_ESSpanish