Vulnerabilities

Tomcat's Missing Method Check at the Default Slash (CVE-2026-55956)

CVE-2026-55956 lets Apache Tomcat select method-specific security collections mapped to the default Servlet path / without checking the request verb, so a public rule intended for one method can weaken a role rule for another; inventory the five named affected ranges plus all EOL branches the CNA says may also be affected, and move supported deployments to 9.0.119, 10.1.56, 11.0.23, or a later verified release.

A warm hand-drawn slash gate receives two distinct request tokens on separate left-to-right rails; the upper public rail reaches an open tray, while the lower protected rail passes through a three-role shield checkpoint.
In this article

Research basisReview of the Apache Tomcat advisory, pinned affected and fixed source, Jakarta Servlet method-constraint semantics, three maintained-branch fixes, regression tests, and deployment proof

SourceApache Tomcat Security Team / Apache Tomcat source / Jakarta Servlet specification / SOSEC source review

On an affected Tomcat build, a POST intended only for ROLE1 can pass container authorization just like the public GET on the same path. The result requires a specific intersection: the deployment descriptor divides the default Servlet pattern / into public and protected operations by HTTP method, and the request reaches the last pass of the security-constraint selector.

The role engine has not forgotten how roles work. It has received one public policy card that does not belong to the current method. In affected releases, RealmBase.findSecurityConstraints() recognizes the slash but omits the findMethod() check used by the exact, prefix, and extension passes. A no-authorization constraint belonging only to GET can therefore enter the POST decision, where Jakarta Servlet combination rules can turn the final result into unauthenticated access.

Following that extra card links mapping, constraint combination, the one-line repair, the six-cell regression, fleet migration, and historical review into one causal chain. The public record establishes the defect and repair, not exploitation of any particular deployment; a local conclusion still requires the running build, effective policy, request principal, business outcome, and resulting state.

1 Two methods on one path inherit the same policy set

The minimal case places two collections on /. The first names only GET and has no authorization constraint, expressing a public read. The second omits GET and requires ROLE1, protecting every other method. Crossing three principals—anonymous, ROLE1, and ROLE2—with GET and POST produces six harmless decision cells. If all three POST outcomes collapse into permission, the question is no longer a vague authorization anomaly: the method dimension vanished during policy selection.

1.1 Code and response map: the default-slash pass omits method membership

1.2 Freeze the decision before calling it a bypass

Begin where the connector hands the request to Catalina and preserve what Tomcat received after trusted proxy processing. A raw client URL may have passed through path normalization, context routing, forwarded-host reconstruction, authentication, and an ingress rewrite. The investigation needs the method and request path visible to Catalina, not merely the browser address. Capture the virtual host, context name and version, connector, normalized context-relative path, dispatch type, selected wrapper, principal, roles, response status, and request identifier that joins these fields to proxy and application logs.

Write the intended policy as an operation matrix before looking at the observed responses. A minimal matrix has three principal states—anonymous, a user holding ROLE1, and a user holding another role—and two methods such as GET and POST. In the upstream regression, every principal may read with GET; anonymous and ROLE2 must not use POST; ROLE1 may. This six-cell statement prevents a successful public read from being mistaken for evidence that the protected write lane also works correctly.

Keep transport and authorization results separate. An unauthenticated request to a role-protected operation may produce an authentication challenge before a final forbidden result, depending on the configured mechanism and whether credentials were supplied. A principal authenticated under the wrong role should normally reach a forbidden decision. A public operation can succeed with no challenge. The exact status can be affected by the authenticator and error handling, but the permitted-versus-rejected matrix must remain stable across those presentation details.

Freeze the effective descriptor alongside the request. Archive the deployed WEB-INF/web.xml, any defaults inherited from conf/web.xml, programmatic registrations, annotations that contribute Servlet security, and the application artifact hash. Do not assume the source repository descriptor equals the running one: build profiles, overlays, container defaults, or vendor repackaging can change it. The decisive configuration contains a security collection whose pattern is exactly the default mapping and whose membership depends on http-method or http-method-omission.

Record negative controls at the same time. Send the benign matrix to an exact pattern such as /admin/report, a prefix pattern such as /admin/*, or an extension pattern such as *.jsp only when the application already exposes safe test resources for them. Affected releases already apply findMethod() in those branches, so a correct result there does not clear the default slash. It does, however, show that the realm, principal mapping, and role data can enforce the same policy when constraint selection is accurate.

A vulnerable version is necessary but not sufficient for this specific path. The deployed web application must contribute a security constraint for the default Servlet pattern /, and at least one relevant web-resource-collection must enumerate methods directly or by omission. A slash constraint that applies to all methods does not depend on the missing predicate. A method-specific constraint on an exact, path-prefix, or extension pattern passes through a branch that already checks the method. Inventory must preserve these distinctions instead of assigning the same exposure state to every Tomcat process.

The affected operation must also be reachable by a principal for whom the method partition matters. Internet exposure raises urgency, but an internal administration portal, artifact browser, documentation service, or embedded appliance can still present the condition to untrusted or lower-privileged users. Conversely, a vulnerable container holding only applications without default-pattern method constraints is version-affected but not configuration-exposed along this route. That conclusion remains conditional on complete deployment-descriptor and runtime coverage.

This issue is not the write-enabled DefaultServlet vulnerability from another advisory. The default Servlet normally serves static resources and is globally mapped to /; its readonly setting controls operations such as PUT and DELETE. CVE-2026-55956 sits in the Realm's security-constraint selector and can affect whatever request reaches a policy on the default mapping. Enabling write methods can increase consequence, but it is not the root precondition and should not replace descriptor inspection.

Apache rates the issue Moderate and the CNA classifies it as CWE-285 Improper Authorization. No numeric CVSS vector appears in the Apache CNA record, so no unsupported score should be added. Priority should combine the public severity with local facts: whether the operation changes state or discloses protected content, which identities can reach it, whether a public collection overlaps the protected method, how many application copies exist, and whether audit logs can reconstruct earlier decisions.

Legacy branches need a separate migration-risk lane. The CNA-confirmed Tomcat 7 and 8.5 ranges, repository-observed 10.0, and any other retired line are often embedded in appliances, commercial middleware, or applications that have not been rebuilt for years, while Java requirements and the Java EE-to-Jakarta namespace transition can complicate a direct move. Record the vendor support channel, JDK constraints, Servlet API generation, dependent frameworks, test data, and rollback window. A temporary method restriction can buy migration time, but it cannot erase unsupported status; every renewal must prove that the rule still covers the backends that actually serve the operation.

A hand-drawn evidence desk compares two identical request paths in separate method lanes, with principal tokens and response seals arranged in a case ledger.
Figure 1. The case becomes testable when path, method, principal, selected policy set, and outcome occupy the same ledger instead of separate logs.

The public chronology anchors that ledger. The issue was reported privately on 15 June 2026; the CVE identifier was reserved and all three repair commits landed on 17 June; Apache's security pages date the 10.1.56 and 11.0.23 fixed releases to 22 June and 9.0.119 to 23 June; and the issue became public on 29 June. The Apache maintainer announcement credits j0hndo as the finder. Commit landing is a source-control event, while the 22–23 June entries are fixed-version release records; neither proves when a local binary changed. Preserve local discovery, first exposure, mitigation, replacement, and validation times separately.

2 The Slash Means Default Servlet, Not the Whole Internet

The glyph at the center of the case is visually simple and semantically crowded. A leading slash can appear in a browser path, a context path, a Servlet mapping, a security-constraint pattern, and a file-system-like resource lookup. Treating those uses as interchangeable produces both false positives and missed exposure. The vulnerable branch is specifically the final default-pattern pass inside findSecurityConstraints(), after Tomcat has already selected a host and web application and is matching the request within that context.

2.1 Context selection ends before default-servlet matching begins

Catalina first chooses a Context by matching the longest context-path prefix for the selected virtual host. A deployment at /docs owns requests beneath that context; the ROOT application owns requests that match no longer context. This is web-application routing. The / relevant to CVE-2026-55956 is evaluated after that choice, against the path inside the chosen context. A ROOT context and a default Servlet mapping are related only by deployment, not by identical matching semantics.

Tomcat declares its DefaultServlet globally in $CATALINA_BASE/conf/web.xml and maps it to /. The Servlet serves static resources and, when enabled, directory listings; applications can override aspects of the declaration. In Servlet mapping rules, the default mapping is the fallback after exact, longest path-prefix, and extension mappings fail. It is not a regular expression and it is not the same pattern as /*, which is a path mapping with different precedence and request-path behavior.

A request for /docs/manual/start.html may therefore be described at several layers. The connector receives a request target; host and context selection choose the /docs application; the context-relative path becomes /manual/start.html; no exact, prefix, or extension Servlet mapping may claim it; the default Servlet mapped to / finally serves the resource. Security constraints are selected for that context-relative operation before dispatch is allowed to continue.

This ordering explains why a reverse proxy rule cannot prove the Tomcat decision. A proxy can authenticate a user, normalize a URL, or block a method, and those controls may be valuable. It does not reconstruct the full set of Servlet deployment-descriptor constraints, Tomcat's best-pattern selection, or the Realm's combination of authorization roles. If the proxy is the temporary enforcement point, its rule must be stated as a separate control with tested method and path coverage, not as evidence that the container is fixed.

It also narrows discovery. Search deployed descriptors and runtime configuration for a url-pattern whose decoded value is exactly /, then inspect the same collection for method elements. Do not flag every leading-slash application route. Do not exclude applications just because their public URL includes a context prefix. The relevant slash is stored in the web resource collection after descriptor processing, and the request is compared within the selected context.

2.2 A web resource is a path-and-method operation

Jakarta Servlet defines a security constraint as authorization and transport requirements attached to web resource collections. Each collection identifies resources through URL patterns and HTTP operations through http-method or http-method-omission. If no methods are listed, the collection applies to every method. If methods are named, only those methods belong. If omissions are named, every method except the omitted values belongs. The method list is therefore part of resource identity, not a late optional filter.

Tomcat stores that identity in SecurityCollection. Its findMethod(String method) contract is direct: return true when the collection applies to the request method. The helper understands explicit methods, omitted methods, and the all-methods case. Descriptor parsing was not missing the data, and no new interpretation was required for the repair. The vulnerable function already had the current request method and invoked this helper in three of its four mapping passes.

Multiple security constraints may describe the same pattern and method, so selection is followed by combination. Role-bearing authorization constraints combine their permitted role names. The special all-authenticated-users role has its defined effect. A constraint with an authorization element that names no roles precludes access and dominates the combination. Crucially for the upstream regression, a matching security constraint with no authorization constraint combines with role constraints to allow unauthenticated access.

The public-read/protected-write pair relies on those rules. The GET collection has no authorization constraint and should be absent from a POST decision. The complementary collection omits GET and requires ROLE1, so it should be the only relevant authorization rule for POST. When the default branch includes the GET collection anyway, the permissive combination is not a bug in hasResourcePermission(); it is the specified outcome for the wrong input set.

Annotations and programmatic registration can produce equivalent method-specific constraints. Servlet 6.1 maps a method-independent @HttpConstraint and its @HttpMethodConstraint entries into security constraints containing method or omission elements. A portable descriptor that exactly matches a Servlet registration can also take precedence over annotation-derived policy. Exposure review must therefore reconstruct the effective constraints after deployment processing and cannot stop at literal XML found in the application repository.

Front-controller applications make these layers especially easy to confuse. External routes may all resemble /api/order while the Servlet registers one broad mapping and static content still falls to the DefaultServlet; the best security-constraint pattern can also differ from the Java method that eventually handles the business operation. Record four decisions separately: the selected Context, the winning constraint-pattern family, the selected Wrapper, and the application handler. Otherwise a framework route table can be mistaken for the container's policy table.

Do not infer HEAD, OPTIONS, or extension-method behavior from GET. A Servlet or application may reuse read logic for HEAD or override it, CORS preflight can take a special authenticator branch, and WebDAV introduces methods such as PROPFIND and LOCK. Derive each expectation from the effective collection and the real handler capability, including the effect of deny-uncovered-http-methods. Leave an unknown method pending until tested instead of assuming that it is equivalent to GET or automatically denied.

Annotation reconstruction must also honor metadata-complete, fragment ordering, and exact-pattern override rules. A library update can introduce a new web-fragment.xml, a build change can alter annotation scanning, and a programmatic registration can have a narrower effective scope when a descriptor already constrains the same Servlet pattern. Track both the contributor and the policy it overrides. That explains why a visible annotation may not produce a runtime row and prevents an inactive declaration from being credited as a compensating control.

A hand-drawn layered map separates virtual host, web application context, inner request path, and the final slash-shaped default servlet doorway.
Figure 2. The affected slash is the final Servlet and constraint pattern inside an already selected web application, not a wildcard for every host and context.

The safe mental model is an operation table keyed by the selected URL pattern and request method. Path matching chooses the best pattern family; method membership chooses the rows that actually occur for the request; combination derives transport and authorization requirements; authentication and role checks then enforce that result. CVE-2026-55956 removes the second step only in the default-pattern family. The next chapter opens that selector and follows the absent predicate line by line.

3 Three Branches Keep the Verb; the Fourth Drops It

The code path now narrows to one method. RealmBase.findSecurityConstraints(Request, Context) receives the current request and the already selected application context. It obtains the context-relative request path and the HTTP method, then walks every configured SecurityConstraint and its SecurityCollection objects in Servlet mapping order. The function's job is selection, not final authorization: it returns the policy objects that later stages must combine and enforce.

3.1 Mapping precedence is implemented as four passes

The first pass looks for an exact match. For each collection, it examines every configured pattern and compares it with the request path. Even when the path is exact, the collection is appended only when securityCollection.findMethod(method) returns true. If at least one exact pattern matches, Tomcat returns the exact-pass result and does not let a less specific family contribute constraints. Path and method are tested together at the point where the object enters the result.

The second pass considers path-prefix patterns ending in /*. It tracks the longest matching prefix, clears results from shorter candidates when a longer match appears, and combines collections at the winning length. Method membership remains in the admission condition. This longest-match bookkeeping matters operationally: a default slash constraint does not participate when a more specific protected prefix wins, while an unexpected mapping change can move a request from one branch to another without changing its externally visible URL.

The third pass considers extension patterns such as *.jsp. It extracts the final path segment and compares the suffix after the last period. Here again, the vulnerable-era code requires securityCollection.findMethod(method) before adding the parent constraint. A separate 2026 Tomcat advisory corrected a multiple-constraint extension-pattern problem, but that issue and CVE-2026-55956 are different defects. A fleet can require both fixes; evidence for one must not be used to close the other.

The fourth pass is the fallback for the pattern exactly equal to /. In affected code, the inner loop sets matched = true as soon as it sees that slash. After the loop, the parent SecurityConstraint is appended. The method variable is still live in the function and the collection still contains its parsed method lists, yet neither participates. The surrounding design did not suppress the check; one conjunction present in the preceding branches is absent from the condition.

Each pass uses the same parent-and-collection shape. A SecurityConstraint can contain several collections, and the function appends the parent once when any of its collections matches the winning family. That detail prevents a naive patch from filtering only after parent objects have been accumulated: the decision belongs while examining the specific collection. The upstream repair places findMethod(method) beside pattern.equals("/"), exactly where collection membership is known.

3.2 The missing conjunction changes the set, not the role algorithm

The vulnerable condition is equivalent to pattern.equals("/"). The repaired condition is pattern.equals("/") && securityCollection.findMethod(method). No request bytes are re-parsed, no role is added, and no authenticator is replaced. The new predicate prevents a collection that excludes the current method from causing its parent constraint to enter the returned array. This small change restores the same path-and-method invariant already enforced in the other pattern families.

For the upstream POST row, the public GET collection returns false from findMethod("POST"); its parent allow constraint now stays out. The collection that omits GET returns true for POST; its parent ROLE1 constraint remains. For the GET row, those results reverse. Selection produces one intended policy set for each operation before any principal is consulted.

Ignoring the method can also attach a constraint that is stricter than intended. An empty authorization constraint on a method-specific collection can preclude access when wrongly combined with another method. A transport guarantee intended for one operation can be presented to the user-data check for another. The public vulnerability focuses on improper authorization because the permissive combination creates a demonstrated role bypass, but incident review should compare every method-specific authorization and transport property on the affected slash.

The source shape supplies useful negative evidence. If the effective winning pattern is exact, a longest prefix, or an extension, this precise missing predicate is not exercised. If the slash collection has neither explicit methods nor omitted methods, findMethod() would return true for every method and the added call does not change selection. If an upstream control blocks the operation before Tomcat, exploitation may be unreachable while the container remains vulnerable. Each statement is a scoped observation, not a substitute for upgrading.

Backport review should therefore avoid searching only for the CVE number or release string. Locate findSecurityConstraints() in the shipped source or decompiled equivalent, identify the final default-pattern loop, and verify that the collection's method predicate dominates the append of its parent constraint. Then inspect vendor changes around the function for alternate selection paths. A renamed helper is acceptable; a late role check that cannot recover collection membership is not equivalent.

If the selected set must be observed in an isolated environment, enable fine-grained Realm tracing for one benign request and a fixed descriptor, then record each pattern pass, the current method, and the final array. Review privacy and performance before changing the log level and restore it immediately after the experiment. A still safer default is a one-off harness derived from the upstream regression that directly asserts which parent constraints are returned. Bind either observation to the object hash and test-code version so behavior seen on a new build is not used to explain an old binary.

Equivalent backport review includes the control flow around the new predicate. Verify the exact-match early return, removal of shorter prefix candidates, retention of peers at the winning extension pattern, entry into the default pass only after the earlier families miss, and the empty-result behavior of resultsToArray(). The same one-line diff can be dead or misplaced after vendor modifications. Preserve both the predicate and the smallest call path that reaches it, together with the corresponding regression result.

Feed the harness the method string Tomcat actually supplies; do not uppercase it on the test side. A proxy, framework, or custom connector may transform a request before the Servlet layer, so record both the raw request line and request.getMethod() and treat any difference as a separate routing or normalization issue. Otherwise the harness can silently repair its own input while leaving the production behavior of findMethod() untested.

A hand-drawn routing cabinet sends requests through exact, prefix, extension, and default drawers; the final drawer is shown receiving a restored method token.
Figure 3. Four pattern passes share one job, but only the vulnerable default drawer admitted a collection without its method token.

This is the point at which source evidence and runtime evidence meet. Source fixes the faulty admission rule. Runtime mapping data proves whether a request reached that rule. The effective descriptor proves whether a non-member collection existed to be admitted. The returned policy set, or a deterministic regression that represents it, proves the consequence. None of those artifacts alone carries the whole claim, but together they reconstruct the exact decision that produced the unexpected success.

4 A Correct Permission Engine Receives the Wrong Policy Set

The selector's return value becomes shared state for the rest of the security pipeline. AuthenticatorBase.invoke() is the useful narrative spine because it shows the order: discover applicable constraints, test user-data requirements, decide whether authentication is required, authenticate when necessary, and ask the Realm whether the principal has resource permission. Once an irrelevant public constraint enters the array, several correct downstream decisions can combine into the wrong final answer.

4.1 AuthenticatorBase carries one array through transport, identity, and roles

The authenticator asks the configured Realm for findSecurityConstraints(request, context) near the start of its security work. A null result means no applicable constraints and permits the pipeline to continue without container-managed authorization. A non-null array is retained for the subsequent checks. The array is therefore not diagnostic metadata; it is the policy input on which the request's transport and identity requirements are computed.

hasUserDataPermission() evaluates any user-data-constraint in that set. Depending on the combined transport guarantees and the current connector, Tomcat may continue, redirect to a protected connection, or reject. An extra collection that carried no transport requirement can change the combination for a method that should have required confidentiality. The CNA describes improper authorization, but the shared selection mechanism warrants checking method-specific transport rules during local impact review.

The authenticator then determines whether the selected constraints require authentication. Login configuration, cached principals, JASPIC integration, preemptive authentication, CORS preflight settings, and the chosen authentication mechanism can affect how identity is established and how a challenge appears. Those branches do not recreate the missing method membership. If the policy set says an operation can remain unauthenticated, a flawless credential verifier may never be asked to prove an identity.

Finally, hasResourcePermission() combines authorization constraints and evaluates the principal's roles. The API contract describes exactly that responsibility: perform access control based on the supplied authorization constraints. In the regression, the supplied array wrongly includes a constraint with no authorization element. Servlet combination rules treat that presence as permission for unauthenticated access, so the function's true result is internally consistent even though the application designer's POST requirement was ROLE1.

This sequence changes what telemetry can prove. An identity-provider log showing no failed authentication does not mean a rejected credential was accepted; authentication may have been skipped. A role service showing correct membership does not clear the request; the permissive combination may have made roles irrelevant. A proxy access log showing a 200 establishes an outcome but not which constraints produced it. The investigation needs container-side mapping, effective policy, and principal state joined to the same request.

4.2 Six benign cells reveal the corrupted combination

The upstream test creates two parent constraints. The first contains a collection for pattern / and method GET, with no authorization roles. The second contains a collection for the same pattern, omits GET, and names ROLE1. It then creates an anonymous request, a principal holding ROLE1, and a principal holding ROLE2. No dangerous application operation or payload is necessary; the test calls selection and permission methods on controlled objects.

For GET, all three principals are allowed. The public collection belongs to the operation. The complementary role collection omits GET and must not enter the set. For POST, anonymous and ROLE2 are denied while ROLE1 is allowed. These expectations exercise both forms of method membership and the role result. A test that checked only anonymous POST would miss whether the allowed role still works.

On vulnerable code, the slash pass admits both parent constraints for both methods. For POST, the presence of the public parent activates the permissive combination and collapses three expected results into allow. For GET, the extra role-bearing parent does not remove the public allowance under the same combination rule, so the public operation can appear normal. That asymmetry is why a basic read-health check gives false reassurance while a protected operation is exposed.

Real descriptors can produce a wider matrix. Add transport guarantees, a deny-all empty role list, the all-roles marker, the all-authenticated-users marker, multiple collections per parent, and overlapping constraints contributed by annotations or deployment overlays. The outcome must be derived from the effective set for each method; it cannot be inferred from one XML fragment. The six upstream cells are a minimal proof of the fixed defect, not a complete application authorization test.

Application side effects determine consequence. A successful POST could be a harmless route that ignores the body, a resource transformation, an administrative action, or a front controller dispatch into business code. CVE-2026-55956 proves container policy may be weaker than declared; it does not prove which application action occurred. Historical review should join unexpectedly permitted methods to application audit events, state changes, downloads, and downstream calls before classifying impact.

Give every matrix row separate authorization and transport outputs. List the parent constraints selected for the operation, derive the combined authorization rule and combined user-data-constraint, and then evaluate anonymous, designated-role, and different-role principals. This exposes three distinct failures: loss of a required role, accidental deny-all, and a weakened transport guarantee. A single allow-or-deny column hides the last two and cannot explain which stage changed.

Evaluate identity at event time. Cached principals, existing sessions, JASPIC, and upstream pre-authentication can make the request-time identity differ from today's directory record. Capture request.getUserPrincipal(), authentication type, effective role mapping, and whether the request reused a session; preserve identity-provider events and event-time groups. When a trusted proxy supplies identity headers, prove which proxy inserted them and which direct routes were closed; the mere presence of a header is not authentication evidence.

Account for caches before assigning a successful response to Tomcat. An authenticator can set headers intended to prevent shared caching, and selecting an irrelevant public constraint may change that behavior; conversely, a proxy or CDN can return a cached success without reaching Catalina at all. Use a unique synthetic object or an authorized cache bypass, inspect Age, Via, cache-hit metadata, and the backend request log, and keep cache delivery separate from the container's decision.

A hand-drawn policy relay shows a selector passing an extra public token into an otherwise orderly transport, identity, and role checkpoint.
Figure 4. The later checkpoints work as designed; the failure is the extra public policy token handed to all of them.

The evidentiary form of a strong local finding is: an affected release processed a reachable request in a context whose effective default-pattern collections divided operations by method; the slash pass admitted a collection that did not contain the request method; Servlet combination rules weakened the authorization requirement; and a principal received an outcome contrary to the intended matrix. Every clause requires local evidence. If one is absent, adjust confidence and scope; when all are proven, the bypass is explainable from descriptor to response.

5 The Fleet Inventory Becomes a Set of Verifiable Objects

Once the single-request mechanism is clear, the question can expand to the fleet. Process names, package versions, application owners, and Internet labels are still insufficient. Exposure belongs to a running combination: a Tomcat implementation from an affected or unresolved retired line, an effective application policy that divides the default pattern by method, and a reachable operation whose authorization changes when the wrong collection is selected. Inventory must preserve all three facts and the evidence for each.

5.1 Runtime identity is stronger than a version label

For maintained lines, record a full version identity. A banner, an orchestration label, and a package database entry are useful leads; each can drift from the classes loaded by the Java process. Capture the executable command, service unit or container digest, Java class path, catalina.home, catalina.base, package provenance, image digest, and the hash of the Catalina JAR that supplies RealmBase. If a vendor shades or repackages Tomcat, retain the vendor build identifier and map the relevant class to upstream code before applying upstream version conclusions.

Multiple application versions can also share a context path through Tomcat parallel deployment. The Context documentation explains that a request carrying an existing session may remain attached to an older deployed version while a new request selects the latest version. A host can therefore contain both a corrected application release and a still-active older copy on one URL. Inventory the context name, context version, sessions, deployment timestamp, and underlying runtime for every active copy. A load balancer reporting that the new pool is healthy does not prove that sticky sessions stopped reaching the old one.

Embedded Tomcat needs the same rigor. Spring-based services, appliances, launchers, and custom Java products may start Catalina without a familiar installation tree. Their dependency lockfiles or software bills of materials identify a candidate version, while the built artifact proves what shipped. Inspect nested JARs, base-image layers, and vendor overlays; then associate each artifact hash with running workloads. A single repository can produce several regional images, and a single image tag can be mutable. The unit of closure is the immutable artifact actually scheduled, not the version declared months earlier.

Once versions are trustworthy, add reachability without reducing it to “public” or “internal.” Preserve the connector and address, virtual host, proxy route, authentication performed before Tomcat, allowed HTTP methods, client population, and whether lower-privileged identities can reach the application. An administration service reachable only from a staff network may still expose protected operations to thousands of authenticated users. A public endpoint whose proxy permits only GET may have a strong temporary control, yet its vulnerable container and policy still need replacement and a tested rollback plan.

The resulting fleet states should remain explicit. “Affected build, policy unknown” is an evidence gap. “Affected build, default pattern present, methods not divided” is a configuration observation. “Affected build, method-specific slash policy, protected operation reachable” is a confirmed exposure condition. “Fixed build, matrix not run” describes incomplete validation. “Fixed build, effective policy captured, six-cell matrix passed” is a defensible technical closure. These labels prevent a missing descriptor from being silently converted into a clean result and make ownership visible during a large migration.

5.2 The effective descriptor reveals where the slash really came from

The application repository is only the beginning of policy reconstruction. Tomcat combines the application’s WEB-INF/web.xml, container defaults, ordered web-fragment.xml files, discovered annotations, programmatic Servlet registrations, and deployment overrides. The Context can also name an alternative deployment descriptor through altDDName. Security roles and role references can be mapped at deployment time. A source search that finds no literal <url-pattern>/</url-pattern> cannot close exposure until these contributors have been resolved for the running application.

Tomcat’s logEffectiveWebXml option can help by logging the combined descriptor at application start, but the June 2026 security release also corrected CVE-2026-55276: earlier effective-web.xml logging could omit special roles and empty authorization constraints. That neighboring flaw matters here because those omitted details change combination results. Use fixed-version output as one evidence source, archive the original contributors, and compare critical security collections with runtime objects or a controlled deployment. Do not treat an old logged descriptor as complete simply because it is labeled effective.

Normalize the result into an operation table. Each row should contain the virtual host, context name and version, decoded URL pattern, pattern family, included methods, omitted methods, authorization-element presence, roles, all-roles markers, all-authenticated-users semantics, empty-role denial, transport guarantee, source contributor, and precedence. Keep “no authorization element” distinct from “an authorization element with no roles”: Servlet combination gives the former a permissive effect and the latter a deny-all effect. A flattened field named “roles: empty” destroys the very difference that explains this case.

Pattern family also deserves its own column. The strings /, /*, an empty context-root pattern, /admin/*, and *.jsp are not stylistic variants. They lead through different selection passes and can have different precedence. Store both the authored value and the decoded value used by Tomcat, then associate a safe representative request path with the winning family. This prevents a search engine, YAML serializer, or spreadsheet cleanup from silently turning the affected default mapping into an unrelated path mapping.

Then join the policy artifact to the release and reachability artifacts by stable identifiers. A useful record contains the Catalina JAR hash, application WAR hash, normalized-policy hash, context version, node or image digest, and capture time. If any one changes, the exposure decision becomes stale and re-evaluation is automatic. This is especially important during rolling deployment: two pods behind one service name can run different JARs or WARs while producing nearly identical access logs.

Match collection methods to each asset. On a host, join the service manager, process, and open files; for a container, retain the runtime digest, image layers, and mounts; in Kubernetes, connect Deployment, ReplicaSet, Pod UID, and imageID; for an appliance, preserve vendor inventory, the administration interface, and the upgrade package. Scanner output must state its permission scope, failures, and assets it could not inspect. Uncovered assets remain unknown instead of becoming implicit clean results.

Policy snapshots also expire. Hot deployment, Context reload, annotation scanning, global conf/web.xml, and role mappings can change the effective table without changing the repository file that an analyst first saw. Capture the boot or deployment event and regenerate the artifact whenever the runtime, WAR, or global configuration hash changes. Retain per-node differences during a rollout; a representative node is not evidence that every active copy loaded the same policy.

A hand-drawn fleet bench shows two retired server lines crossing a migration bridge toward three maintained lines, while version, policy, and reachability evidence converge under magnifying glasses.
Figure 5. Five ranges are expressly affected, other retired lines remain open because the CNA says they may also be affected, and only three maintained release lines receive upstream fixed versions.

By the end of inventory, every row has an owner and a next action. Maintained exposed nodes move to a fixed release and a matrix test. End-of-life nodes enter a supported-platform migration with an interim method control if needed. Unknown policy rows trigger descriptor reconstruction. Unreachable rows retain proof of the upstream control and a plan to detect drift. Fixed rows remain open until their deployed hashes and authorization matrix agree. The fleet has stopped being a list of product names and become a collection of testable claims.

6 One Conjunction Still Demands a Full Release Proof

The source diff is one method check, but production assurance is larger than that line. Three maintained branches carry equivalent commits, applications can depend on adjacent Servlet behavior, and a rolling upgrade can leave old processes serving traffic after the new package is visible. The repair must be traced from upstream source through the shipped binary, the effective policy, the authorization matrix, and the final removal of vulnerable instances.

6.1 Three branch commits restore the same admission rule

The Tomcat 9 repair is commit a0374c450970760efafbd8806a1db278830ba7bd, the 10.1 repair is 9c3b1efb74fd04f77639720af1d48a8f664ad9bb, and the 11 repair is 3f6bd2ba5e53d1f340bbe5ad2d42a28b29440b7a; all three landed on 17 June 2026. Each changes the final default-pattern condition in RealmBase.findSecurityConstraints() from testing only pattern.equals("/") to testing that expression together with securityCollection.findMethod(method). The location differs by a few source lines; the restored invariant is identical.

The placement is as important as the expression. The helper is evaluated while Tomcat is examining one SecurityCollection, before the parent SecurityConstraint enters the result array. This guarantees that a collection excluding the current method cannot nominate its parent. A filter applied after parents are accumulated would lose the association between a parent and the particular collection that matched. A role check later in the pipeline cannot infer which collection should have been absent. Backports need to preserve this point of decision.

Each upstream commit also adds testDefaultServletConstraints() to TestRealmBase. The test constructs one public GET collection on / and one complementary collection on / that omits GET and requires ROLE1. It creates anonymous, ROLE1, and ROLE2 principals, then checks all six combinations. Those 67 added lines explain the intended behavior more fully than the one changed production line because they prove public access, required access, and rejection still coexist after selection is corrected.

Branch equivalence can be recorded as a review table: upstream family, fixed release, full commit hash, changed source path, old predicate, new predicate, test method, and test outcomes. If a distribution supplies a backport under a different commit, map its diff and tests into this table. Binary-only vendors should provide an advisory and build identifier; local teams can decompile or instrument the shipped class in an authorized staging environment to verify the admission rule. A version suffix with no provenance is not strong closure evidence.

6.2 The deployment closes only when the matrix and hashes agree

Build the candidate from a trusted distribution channel or an approved reproducible pipeline. Verify the Apache release signature and digest when consuming upstream binaries, retain the package or image digest, and record the Catalina JAR hash. Generate a software bill of materials that identifies the embedded Tomcat component for packaged applications. Place those values in the change record before testing, so the artifact that passes the matrix is the same artifact promoted to production.

Deploy the candidate with a representative copy of the effective descriptor. Framework-generated annotations, ordered fragments, global defaults, role mappings, authentication mechanism, connector settings, and proxy headers can all affect the observed response even though the source defect lives in one selector. Use synthetic accounts with no production privileges and a benign endpoint whose allowed action has no durable effect. If an application has no safe representative operation, test the upstream object-level regression plus a staging deployment built from the same descriptors and application artifact.

Run the six core cells first. For the public method, anonymous, designated-role, and different-role identities must all receive the expected public outcome. For the protected method, anonymous must not complete the operation, the designated role must succeed, and the different role must not complete it. Record the challenge and final status separately: BASIC, FORM, CLIENT-CERT, JASPIC, or an application error page can present denial differently. The invariant is whether the request reaches the protected operation under each identity.

Then expand the matrix from the normalized policy artifact. Include every explicit method, at least one method admitted by each omission set, safe representatives for application extension methods, and OPTIONS or HEAD where the application defines special behavior. Include overlapping exact, prefix, extension, and default patterns so mapping precedence is exercised. If deny-uncovered-http-methods is configured, add uncovered-method cases and confirm a forbidden result without business execution. This catches policy defects that share the same symptoms but are not fixed by the slash predicate.

Instrument side effects as a first-class assertion. Capture database row counts or test-record versions, object-store writes, file hashes, queue depth and message identifiers, outbound request logs, cache mutations, and application audit events before and after each denied cell. A response status alone cannot prove that processing stopped before a write, especially when error handling or asynchronous work is involved. The protected operation’s designated-role cell should produce one expected controlled effect; denied cells should produce none.

Roll out by immutable replacement, then prove traffic convergence. During a canary, query a diagnostic endpoint or process inventory that reports the exact build through an authenticated administrative channel; sample server-side request identifiers from each pool member; and account for sticky sessions, parallel contexts, blue-green pools, standby nodes, and disaster-recovery images. Remove or quarantine the old image after rollback safety has been established. A drained node that can be reintroduced automatically remains part of the exposure until its artifact is replaced.

Rollback planning must preserve security and availability. Prepare the previous application artifact on the fixed Tomcat runtime when possible, because rolling the entire container back to an affected build reopens the condition. If a compatibility failure forces a temporary rollback, apply an independently tested proxy or application method rule that covers the exact host, context, path, and protected verbs; restrict reachability; monitor the rule; and assign a short expiry. The change record should state what evidence will remove the interim control.

Compatibility testing should cover the Servlet API, JSP compilation, session serialization, custom Realms and Valves, proxy-header handling, static assets, error pages, and startup scanning. Diagnose failures as application, configuration, or new-version behavior before proposing a runtime rollback. For a staged legacy migration, move the highest-consequence operations first, prove that routing cannot reach the old pool, and rerun both the method matrix and side-effect assertions at every stage.

A hand-drawn release bench shows the same restored connector across three maintained rails above a six-cell method-by-identity test board, with a signed package and rollback crate.
Figure 6. The source correction is one repeated connector; release proof still includes three branch identities, six authorization outcomes, an immutable package, and a usable rollback.

Closure is a chain of matching objects: the upstream commit establishes the corrected rule; the release or vendor record associates that rule with a version; package and JAR hashes identify what was tested; the effective-policy hash identifies what was enforced; the matrix proves public and protected operations remain distinct; deployment evidence shows every serving instance uses the candidate; and retirement evidence prevents the old artifact from returning. If any link changes identity, the result must be verified again rather than inherited.

7 History Is Rebuilt from Methods, Principals, and State

Once inventory finds configuration-exposed deployments, the question changes from “can this happen?” to “which earlier requests received authority they should not have had?” CVE-2026-55956 leaves no unique payload, process name, or network signature. Its evidence is relational: method, effective policy, event-time principal, affected runtime, application result, and state must be joined around one decision.

7.1 Hunt for successful operations that should have met a challenge

Define the historical window from each deployment, not from disclosure alone. For a given artifact, begin when the affected Tomcat build and the relevant policy first ran together on a reachable route. End when the last serving copy was replaced or an independently verified method control took effect. Preserve rollout, rollback, autoscaling, disaster-recovery, and parallel-deployment events inside the interval. The public dates—15 June report and 29 June disclosure—help explain awareness, but they do not set a universal first-exposure time.

Generate hunt rows from the normalized operation table. Each row identifies a host and context, winning default pattern, protected method set, permitted roles, transport requirement, application operation, and safe expected outcome. Start with state-changing methods and protected reads that return sensitive content, then cover every explicit or omission-derived method. Include routes reached through a front controller or static/default Servlet behavior. This converts a broad CVE search into a list of concrete decisions that logs can test.

At the proxy layer, recover timestamp, request identifier, source or client identity appropriate to local privacy rules, host, path before and after rewrite, method, authenticated upstream subject, response status, response length, and selected backend. At Tomcat, recover connector, virtual host, context, local request path, method, status, bytes, session token hash if policy permits, remote user, and request identifier. At the identity layer, recover authentication time, subject, role or group snapshot, and changes to membership. Normalize clocks and document any uncertainty before joining records.

A successful response is a lead, not proof of abuse. Some POST handlers perform read-only searches, some return a validation error after authorization, and some applications intentionally permit selected lower-privileged users through programmatic checks. Conversely, a 302 or 200 can wrap an authentication failure in FORM workflows, and a 403 can arrive after an application side effect if custom error handling is unsafe. Interpret status, route behavior, principal, and state together. Retain normal traffic samples to understand retries, health checks, browser prefetch, and automation.

Join candidate requests to application audit and business records. Useful evidence includes object identifiers read or changed, before-and-after record versions, configuration revisions, download audit entries, file hashes, object-store access, queue messages, administrative action logs, and downstream service calls. The request identifier is ideal; where it is absent, use a documented combination of timestamp, session, principal, route, object identifier, and backend. Measure collision risk and avoid claiming a one-to-one join when several requests fit the same window.

Role history can be as important as request history. A user may hold ROLE1 today but not at the time of the event, or a directory-to-role mapping may have changed during an application release. Preserve effective application role mappings, group membership snapshots, identity-provider events, and service-account assignments for the event time. If historical role data is unavailable, classify the request as unresolved instead of importing current membership. The vulnerability affects whether a role was required; impact analysis still needs to know whether the principal already possessed it.

Absence of an authentication event has limited meaning. As the source path shows, the irrelevant public constraint can cause AuthenticatorBase to determine that authentication is unnecessary. The request may therefore reach the application with no failed login to hunt. Search for protected-method successes with a null principal, with a principal outside the permitted role set, or with upstream identity only and no corresponding container identity. Compare those cases with fixed-version behavior in staging to understand which fields disappear or appear when selection is corrected.

Record confidence in layers. A confirmed policy anomaly has affected build evidence, a complete effective descriptor, a request mapped to the default pass, a method outside the public collection, and an unexpected authorization outcome. Confirmed impact adds a protected read or durable state change tied to that request. A suspicious event lacks one or more joins but contradicts the expected matrix. A clean interval has sufficient telemetry for all relevant operations and no contradiction. An unobservable interval is a finding about evidence retention, not a clean bill of health.

7.2 Contain the operation, preserve the record, and retest safely

  1. Containment begins with the highest-consequence operation. If a protected method can change configuration, publish content, alter accounts, or retrieve sensitive artifacts, restrict that host-context-path-method tuple at a trusted proxy or application control while the upgrade is prepared. Validate the rule with the same identity matrix and confirm it does not redirect traffic to an alternate context or backend. A blanket method ban may break legitimate workflows; a narrow rule needs exact rewrite and normalization coverage. Document which layer owns the decision.
  2. Preserve evidence before restarting or redeploying. Capture process command lines, open JAR paths, container and image digests, Catalina and application logs, proxy routing configuration, current deployments and parallel versions, effective descriptor sources, policy artifact, relevant identity mappings, and business-state snapshots. Hash exported files and record collection times. If logs are remote, preserve the query and retention settings as well as results. A restart can rotate local logs, end sticky sessions, and erase the association between an old context version and its requests.
  3. Upgrade supported lines to 9.0.119, 10.1.56, 11.0.23, or a later verified release; migrate applications on the named Tomcat 7 and 8.5 ranges, Tomcat 10.0, and every other retired line to a maintained destination. If an appliance vendor controls the runtime, open a case with the exact product build and ask for the upstream-fix mapping. Keep the compensating method rule active until the supplied artifact passes source or binary review and the operation matrix. An assurance statement that mentions only the CVE without a build, patch mapping, and test evidence leaves the core question unanswered.
  4. Credentials and sessions are handled according to observed impact. The selector flaw does not itself disclose a password or forge an identity, so a fleet-wide password reset has no automatic evidentiary basis. If history shows an unauthorized account change, token creation, secret read, session modification, or administrative action, revoke the affected credentials and sessions, restore trusted configuration, and review dependent systems. If exposure is confirmed but telemetry cannot exclude protected reads, choose rotation based on the sensitivity and lifetime of the potentially accessed material.
  5. Recovery tests begin outside production and then continue as synthetic monitors. Re-run the normalized method-by-identity matrix, verify denied cells create no side effects, confirm the expected transport guarantee, and check every serving instance. Add a production-safe protected probe that uses a non-mutating or disposable object, a designated synthetic role, and a different-role identity. Alert when a denied cell becomes successful, when a fixed runtime hash changes, when the normalized-policy hash drifts, or when an end-of-life node rejoins service.

Business owners need a concrete statement. Name the applications and operations, the affected interval, the identities that could reach them, the protected data or state, the telemetry available, confirmed or unresolved events, current controls, and remaining uncertainty. Avoid translating “Moderate” into a universal business impact. A static documentation service and an administrative deployment console can share the same code defect while carrying very different consequences. The operation table supplies the vocabulary for that distinction.

A practical response cadence keeps source, fleet, and incident work synchronized. In the first hours, freeze evidence, reconstruct policy, and restrict high-consequence operations. During the first day, validate fixed artifacts, migrate serving pools, and start the historical join. During the following days, finish end-of-life migration plans, investigate suspicious state changes, review vendor backports, and convert the matrix into continuous controls. Each handoff includes artifact hashes and policy hashes so a team never validates one object while another is deployed.

The case should also preserve benign negative findings. Exact, prefix, and extension constraints that pass their matrices demonstrate that the Realm and role store can enforce equivalent policy when selection is correct. Applications with no method-specific default collection document why this route does not apply to their configuration. Routes blocked by an upstream method rule retain the rule, test, and monitoring record. These facts narrow impact without implying that an affected runtime can remain indefinitely or that another policy defect is absent.

Use two passes for historical queries. A low-sensitivity first pass filters candidates by backend, Context, path, method, status, and empty-principal state; an authorized second pass joins identities and business objects only for those candidates. Archive the query, index version, time-zone conversion, deduplication rule, and row count. If sampling, truncation, or missing indexes can omit rows, quantify the miss rate or confidence and do not present the returned set as complete.

Mark unobservable intervals from the intersection of proxy, Tomcat, application, identity, and state-record coverage. Notification, credential rotation, added monitoring, and other risk decisions should follow the sensitivity, reachability, and controls for that interval—not an assumed clean result. Improve correlation identifiers across layers, preserve Context version and runtime digest, and monitor clock synchronization. Accept the code repair and the observability debt as separate decisions with separate owners.

Calibrate detections against fixed-build baseline traffic. Bots, probes, browser HEAD, CORS OPTIONS, and retries can all produce a non-GET success without this defect. A higher-value signal combines a protected method, insufficient event-time role, affected runtime, and evidence that the handler executed. Store those conditions separately so analysts can distinguish an unusual request from the policy anomaly and from confirmed application impact.

A hand-drawn evidence wall joins proxy and Tomcat ledgers, identity and method tokens, application audit, database snapshots, and downstream receipts with one sealed request thread.
Figure 7. Historical confidence grows when one request thread joins runtime, policy, principal, outcome, and state; a successful status alone cannot establish the event.

8 Authorization Becomes a Versioned Operation Table

Authorization begins when the container selects policy objects, before any role comparison appears in a log. If release engineering versions only application code and treats effective security policy as ambient configuration, a one-predicate selector defect can remain invisible until an incident forces the method matrix to be rebuilt. The durable control is to make the normalized operation table and its test result ordinary release artifacts.

8.1 Build the policy artifact once and make every gate consume it

Create the normalized operation table during a controlled application deployment or build step that resolves all descriptor sources with the intended Tomcat family. Preserve authored and decoded patterns, pattern family, method inclusion and omission, authorization-element presence, role semantics, transport guarantee, contributor, and precedence. Add the application hash, Tomcat component identity, Java version, and generation-tool version. Canonicalize ordering before hashing so semantically identical output is stable and a genuine policy change produces a reviewable diff.

The compiler must retain distinctions that generic configuration tools often erase. An absent auth-constraint permits unauthenticated access when combined; an empty auth-constraint denies all. The special role names have defined semantics. A missing method list applies to all methods, while an omission list defines a complement. The patterns /, /*, an empty context-root match, a prefix, and an extension choose different paths. Schema validation should fail when any of these states is coerced into the same null or empty value.

Generate tests directly from the table. For every winning pattern, select representative safe paths. For each method partition, create public, designated-role, different-role, and anonymous cases as applicable. Add transport cases and deny-all cases. Generate overlap tests in which exact, longer prefix, extension, and default candidates coexist. The expected result comes from the portable Servlet combination rules and the application’s declared roles, then the deployed container is treated as the system under test. A change to policy or runtime automatically regenerates the matrix.

Keep the upstream six cells as a permanent conformance fixture. They are small enough to run against every approved Tomcat update and vendor build, and they exercise the precise default-pattern defect without touching application state. Add neighboring fixtures for exact, prefix, and extension families so a future refactor cannot fix one pass while dropping the method predicate from another. Add combinations for absent authorization, deny-all, ordinary roles, all roles, all authenticated users, and transport guarantees. The suite becomes a compact executable reading of the specification.

Attach the policy hash and matrix result to the deployment attestation. Admission control can reject a workload whose Tomcat version is outside the approved set, whose Catalina hash is unknown, whose policy hash was not reviewed, or whose test evidence belongs to another artifact. Runtime inventory then compares the loaded classes and application hash with the attestation. This joins build and operations without requiring production to expose a public version banner. Any mismatch opens a targeted investigation with concrete object identities.

Observe decisions in terms useful for the same table. Log a privacy-appropriate request identifier, selected host and context version, normalized request path, method, authenticated principal or anonymous state, role evaluation result, status, and application audit identifier. Where feasible, expose the winning pattern family and a non-sensitive policy version through structured internal telemetry. Protect and retain these records according to data policy. The aim is to reconstruct why an operation was allowed without recording credentials, request bodies, or sensitive response content.

Review policy diffs semantically. A new public method on /, removal of an omission, addition of an authorization-free overlapping constraint, change from /* to /, removal of a transport guarantee, or change in role mapping deserves explicit owner approval. A formatting-only XML change should disappear after canonicalization. This makes security review focus on operation outcomes and reduces noise that teaches reviewers to approve descriptor changes unread.

Drift controls close the loop. A scheduled job compares deployed Tomcat, WAR, and policy hashes with the release record; a synthetic matrix samples the most important public and protected operations; inventory flags end-of-life families and unknown vendor backports; and log-quality checks verify that request identifiers, context versions, methods, and principal states remain joinable. When any control fails, responders begin with the same objects used in this investigation instead of rebuilding the vocabulary during an incident.

Treat the generator and harness as security-sensitive software. Pin their dependencies, review changes to method-set expansion and pattern precedence, and keep golden fixtures derived from the Servlet specification. Feed intentionally tricky descriptors into the compiler: several collections under one parent, identical patterns in several constraints, empty authorization, method omissions, an empty context-root pattern, and a default slash beside a longer prefix. Compare the normalized output with Tomcat runtime objects in a disposable deployment. A policy artifact is valuable only when its transformation is independently testable.

8.2 Close the case with evidence that survives the next deployment

The engineering conclusion converts one defect into code-review questions. Does every pattern-selection pass test both path and method before admitting a collection? Does precedence clear weaker matches without losing valid peers? Can a parent constraint enter through one child collection and then influence another method? Do combination tests cover public, role-restricted, authenticated-only, and deny-all cases? Do downstream components receive an operation-specific set? These questions apply whenever authorization policy is selected in stages, even when the implementation is not a Servlet container.

The story ends with the same two requests: their host and path are identical, their HTTP methods encode different operations, and the descriptor records that distinction correctly. The vulnerable selector erases it while assembling the policy set; the fixed selector preserves it; the six-cell matrix proves the operations have separated again. The missing conjunction becomes visible only when path, method, policy, principal, and state remain in one record.

A hand-drawn circular workshop carries one teal policy artifact from descriptor assembly through signed release, slash-gate deployment, method-role testing, runtime evidence, and archived review.
Figure 8. A normalized operation table can connect build, deployment, validation, telemetry, and incident closure without being reconstructed after every surprise.

The closure criterion is therefore concrete: fixed releases are serving, exposed method partitions pass their expected matrices, retired images cannot return, and historical conclusions state their evidence and confidence. Everything else keeps an owner and a deadline; a new application build, vendor package, or role map sends the affected conclusion back through verification.

Research record

9Evidence, objects, and sources

The material below preserves the identifiers and references used in this report.

9.1Research objects

Products, actors, techniques, affected objects, and control points discussed in the report.

CVECVE-2026-55956

Apache Tomcat default-Servlet method-constraint selection flaw

ProductApache Tomcat 7.0.0-7.0.109

Affected end-of-life Tomcat 7 releases; migrate to a maintained line

ProductApache Tomcat 8.5.0-8.5.100

Affected end-of-life Tomcat 8.5 releases; migrate to a maintained line

ProductOther end-of-life Apache Tomcat versions

The CNA says other retired versions may also be affected; repository analysis finds matching code in Tomcat 10.0, whose CNA status remains unresolved and whose applications require migration

ProductApache Tomcat 9.0.0.M1-9.0.118

Affected Tomcat 9.0 releases; fixed in 9.0.119

ProductApache Tomcat 10.1.0-M1-10.1.55

Affected Tomcat 10.1 releases; fixed in 10.1.56

ProductApache Tomcat 11.0.0-M1-11.0.22

Affected Tomcat 11.0 releases; fixed in 11.0.23

Control9c3b1efb74fd04f77639720af1d48a8f664ad9bb

Tomcat 10.1 commit that restores method filtering for the default mapping

9.2Event chronology

  1. Issue privately reported

    The Tomcat Security Team received the default-Servlet constraint report.

  2. Three source commits land

    The equivalent 9.0, 10.1, and 11 branch fixes entered source control; the CVE identifier was reserved the same day.

  3. Tomcat 10.1.56 and 11.0.23 are recorded as fixed releases

    Apache's security pages date these fixed-version releases to 22 June; their source commits had already landed on 17 June.

  4. Tomcat 9.0.119 is recorded as a fixed release

    Apache's security page dates this fixed-version release to 23 June; commit a0374c45 had already landed on 17 June.

  5. CVE-2026-55956 disclosed

    Apache published the affected ranges and fixed releases.

  6. SOSEC completed source and deployment review

    The review traced request entry, selection, permission checks, three branch patches, the method matrix, and deployment evidence.

9.3Sources and material

  1. Apache Tomcat 9 security advisories and affected rangehttps://tomcat.apache.org/security-9.html
  2. Apache Tomcat 10 security advisories and affected rangehttps://tomcat.apache.org/security-10.html
  3. Apache Tomcat 11 security advisories and affected rangehttps://tomcat.apache.org/security-11.html
  4. Official CVE record from the Apache CNAhttps://www.cve.org/CVERecord?id=CVE-2026-55956
  5. Official Apache maintainer advisoryhttps://lists.apache.org/thread/dcjdcnnnww9hhdm016hr0l7hpw1bzjfp
  6. Apache maintainer announcement mirror with j0hndo finder credithttps://www.openwall.com/lists/oss-security/2026/06/29/25
  7. NVD record carrying the Apache CNA affected ranges and CISA enrichmenthttps://nvd.nist.gov/vuln/detail/CVE-2026-55956
  8. Tomcat 9 branch fix and regression testhttps://github.com/apache/tomcat/commit/a0374c450970760efafbd8806a1db278830ba7bd
  9. Tomcat 10.1 branch fix and regression testhttps://github.com/apache/tomcat/commit/9c3b1efb74fd04f77639720af1d48a8f664ad9bb
  10. Tomcat 11 branch fix and regression testhttps://github.com/apache/tomcat/commit/3f6bd2ba5e53d1f340bbe5ad2d42a28b29440b7a
  11. Tomcat 10.0.27 RealmBase source used for the repository-derived EOL observationhttps://github.com/apache/tomcat/blob/ca8720d41f3be917dc3fcdd03fcca8d3152a13fb/java/org/apache/catalina/realm/RealmBase.java
  12. RealmBase.java at the reviewed revisionhttps://github.com/apache/tomcat/blob/9c3b1efb74fd04f77639720af1d48a8f664ad9bb/java/org/apache/catalina/realm/RealmBase.java
  13. AuthenticatorBase.java request-to-Realm call pathhttps://github.com/apache/tomcat/blob/9c3b1efb74fd04f77639720af1d48a8f664ad9bb/java/org/apache/catalina/authenticator/AuthenticatorBase.java
  14. SecurityCollection.findMethod implementationhttps://github.com/apache/tomcat/blob/9c3b1efb74fd04f77639720af1d48a8f664ad9bb/java/org/apache/tomcat/util/descriptor/web/SecurityCollection.java
  15. TestRealmBase six-cell regression sourcehttps://github.com/apache/tomcat/blob/9c3b1efb74fd04f77639720af1d48a8f664ad9bb/test/org/apache/catalina/realm/TestRealmBase.java
  16. Jakarta Servlet 6.1 specificationhttps://jakarta.ee/specifications/servlet/6.1/jakarta-servlet-spec-6.1
  17. Tomcat Context selection, parallel deployment, and effective-web.xml documentationhttps://tomcat.apache.org/tomcat-10.1-doc/config/context.html
  18. Tomcat Default Servlet declaration and configuration referencehttps://tomcat.apache.org/tomcat-10.1-doc/default-servlet.html
  19. Tomcat security considerationshttps://tomcat.apache.org/tomcat-10.1-doc/security-howto.html
  20. Tomcat 10.1 changelog and repaired release lineagehttps://tomcat.apache.org/tomcat-10.1-doc/changelog.html
  21. MITRE ATT&CK T1190 definitionhttps://attack.mitre.org/techniques/T1190/
  22. MITRE ATT&CK T1210 definitionhttps://attack.mitre.org/techniques/T1210/