CVE-2026-103119 affects Apache Tomcat 11 deployments using AJP and large non-blocking responses. The immediate question is whether the application’s live proxy route reaches that connector. A normal HTTPS homepage, a closed public AJP port, or a patched Tomcat archive elsewhere on the host cannot answer it.
Apache’s Tomcat 11 security advisory lists versions 11.0.0-M25 through 11.0.26 as affected and 11.0.27 as the fixing release. Apache rates the issue Important. Its response should begin with the running artifact and connector configuration, followed by a controlled check of response ownership after the replacement is deployed.
What the advisory establishes
إن maintainer’s October 20 disclosure describes a buffer under-read: a large non-blocking write can split a response body between the current request and the next request on the same connection. The expected consequence is most often failure of the second request; disclosure of the first response’s data to the second is also possible. The notice does not describe remote code execution or establish that a particular customer was compromised.
| سؤال | Confirmed boundary | Operational consequence |
|---|---|---|
| Which upstream branch? | Tomcat 11, 11.0.0-M25–11.0.26 | Identify the actual server artifact rather than infer it from the application’s name. |
| Which fixing release? | 11.0.27 | Use an approved fixed release or documented vendor backport. |
| Which execution path? | AJP and a large non-blocking write | Trace the proxy-to-backend route and relevant response workflow. |
| What security property? | Response data must remain with its request | A status code alone cannot establish isolation. |
Do not apply an unrelated Tomcat fix matrix to this CVE. The same release addresses other issues with different prerequisites. A deployment can need the release for several reasons, but each finding still needs its own affected-surface explanation. Conversely, a Tomcat service with no AJP route is not evidence that the AJP flaw can be exercised there.
Apache records September 16, 2026 as the report date and October 20 as public disclosure. The security page groups the fix under October 12. Keep those events separate when reconciling vulnerability records with package rollout history; a disclosure date is not a deployment date.
Find the backend protocol behind the public URL
A public client can speak HTTPS to a front-end server while that server uses AJP to reach Tomcat. Apache HTTP Server’s mod_proxy_ajp documentation describes this reverse-proxy arrangement and shows backend mappings using the ajp:// scheme. The protocol visible in a browser therefore does not identify the protocol on the internal hop.
Draw the route for the application you operate: listener, virtual host, proxy rule, backend pool, Tomcat instance, and connector. Include fallback routes and less frequently used application paths. A migration to an HTTP backend is incomplete if one legacy export path still selects an AJP worker. This is a deployment review recommendation, not an assertion that such a fallback exists in your environment.
The same distinction applies to HTTP/2. A front-end HTTP/2 session may terminate at the proxy. That does not make a backend AJP problem an HTTP/2 vulnerability. Keep the client-facing session, proxy backend connection, and application request identity separate in the investigation record.
Connection reuse matters because the disclosure concerns the next request on the affected connection. It does not mean that any arbitrary pair of users is guaranteed to share a connection or receive each other’s data. Establish the actual proxy behavior and preserve uncertainty where connection assignment is not visible. A diagram of a possible path is useful for planning; it is not evidence that the path was triggered.

What the published patch changes
Apache links commit f13748ba as the fix. In OutputBuffer.java, the change distinguishes blocking output from non-blocking output when the number of bytes written reaches the configured content length. The accompanying comment explains that the non-blocking case can still have bytes buffered at the socket wrapper. Closing the response at the wrong point can therefore disagree with completion of the underlying write.
إن 11.0.27 changelog also describes allowing an exact-content-length non-blocking write to complete before response closure and ensuring the non-blocking write buffer is empty before an AJP end-response message is sent. These entries make output completion and response termination useful review points.
This is source inspection, not a reproduction of the vulnerability. The diff does not supply a safe universal response size, a guaranteed timing window, or a production detection signature. Do not invent those values from the word “large.” A regression test needs to be tied to a known application path and a controlled environment, while remediation should follow the upstream or supported vendor fix.
The broader engineering lesson is that application-level completion and transport-level completion are distinct states. A request handler may believe it has produced its full body while lower layers still hold work. A review of such code should ask which component owns pending bytes and which event permits the connection to advance. That is a general review question; it does not extend this advisory to every servlet or connector implementation.
Build an exposure record without collecting secrets
For each service, record the running Tomcat build, deployment revision or image digest, connector selected by the route, proxy configuration owner, and relevant application workflow. If a product embeds Tomcat, obtain the product vendor’s affectedness and update guidance. Replacing an unrelated system package does not change the libraries loaded by that product.
Review connector configuration in its effective context. A file from a source repository may be overridden by an environment-specific template or generated configuration. An old, disabled connector declaration may also remain in the file. Establish which configuration the running instance loaded, and keep the evidence narrow enough to review.
Tomcat’s AJP configuration reference highlights address, السر, secretRequiredو allowedRequestAttributesPattern as security-relevant settings. A configured secret requires matching worker credentials; secretRequired controls whether the connector may start without a configured secret. Neither setting is a claim that a valid worker’s response stream is free of this defect.
Keep the secret value out of tickets, screenshots, article comments, and exported reports. The exposure record can say that the configured worker and connector are paired without reproducing their credential. Likewise, avoid copying a full process environment merely to establish a server version. Capture the particular artifact and routing facts the decision requires.
| Evidence obtained | Reasonable conclusion | Conclusion to avoid |
|---|---|---|
| AJP is blocked from the public internet | Direct external access is restricted | The application’s proxy cannot reach the affected path |
| No active AJP connector or route for this service | The documented AJP path has not been identified for that service | Every Tomcat CVE is irrelevant |
| Fixed archive exists on disk | An update artifact is available | The live process has loaded it |
| One normal response is correct | That observation succeeded | Large non-blocking output and connection reuse have been exhaustively tested |
| Vendor confirms a backport for the installed package | The package may be repaired despite an older upstream-looking version | Every similarly numbered package contains that backport |
Replace the affected runtime, then verify the route
Upgrade affected upstream installations to 11.0.27 or a later supported release that includes the correction. For packaged or embedded distributions, use the vendor’s approved update and retain the associated security notice. Apache’s advisory identifies the upstream fix; a downstream version string needs downstream evidence.
In a pool, track each backend separately. Remove an instance from normal traffic, replace its artifact through the deployment process, start the replacement, and verify the running revision before returning it to service. Repeat until no old replica remains eligible for routing. This proposed rollout sequence should be adapted to the application’s availability and change procedures.
If AJP is unnecessary, evaluate removing its connector and proxy route. If you move the backend hop to HTTP, test routing, authentication propagation, redirects, client address handling, and required application behavior. Disabling a connector without updating its callers can replace a security exposure with an outage. Document the resulting topology rather than describing a configuration change as a proven equivalent fix.
Tomcat’s security considerations treats server configuration as one part of a wider control set. Network restriction remains useful containment, but a reachable trusted proxy can still be part of the legitimate response path. Patching and restricting access answer different questions.
Keep rollback artifacts in the review. A rollback that restores the vulnerable runtime also restores the reason for the emergency change. If reverting becomes necessary, make the remaining exposure and temporary routing restriction explicit. A successful deployment job is only the start of the evidence needed to close the vulnerability.

A safe check for response-isolation evidence
Before writing a load test, decide what a meaningful result looks like. In an isolated staging application, give each test response a synthetic marker and a request identifier. Use no customer content. Record which expected marker belongs to each request, whether the body was complete, and whether the route under review was confirmed. Keep rates and sizes within an agreed test envelope.
The following offline helper classifies already-collected observations. It sends no requests, speaks no AJP, and does not reproduce CVE-2026-103119. Its purpose is narrower: preventing a correct-looking status or an incomplete body from becoming a false remediation claim. The markers and records below are invented.
"""Offline evidence classification; no network and no Tomcat exploit."""
def classify(row):
if row.get("request_id") != row.get("response_request_id"):
return "inconclusive"
if row.get("ajp_route_confirmed") is not True:
return "inconclusive"
if row.get("complete") is not True:
return "inconclusive"
marker = row.get("marker")
if marker == row.get("expected_marker") and marker:
return "expected-response"
if marker in row.get("other_markers", ()):
return "cross-response-alert"
return "inconclusive"
base = dict(request_id="req-b", response_request_id="req-b",
ajp_route_confirmed=True, complete=True,
expected_marker="SYNTHETIC-B", marker="SYNTHETIC-B",
other_markers=("SYNTHETIC-A",))
cases = [
(base, "expected-response"),
({**base, "marker": "SYNTHETIC-A"}, "cross-response-alert"),
({**base, "complete": False}, "inconclusive"),
({**base, "ajp_route_confirmed": False}, "inconclusive"),
({**base, "marker": None}, "inconclusive"),
({**base, "response_request_id": "req-a"}, "inconclusive"),
]
for row, expected in cases:
assert classify(row) == expected
print("6/6 synthetic evidence cases passed")
We executed these six synthetic cases locally. The expected outcomes all matched:
6/6 synthetic evidence cases passed
The first case establishes only that one complete synthetic response matched its expected marker through a confirmed route. The second produces an alert for the other response’s marker. In a real investigation that alert would need correlation with backend logs, proxy behavior, caching, and the application itself before attribution to this CVE. An alert is not a diagnosis.
The remaining cases stay inconclusive because the body is incomplete, the route is unconfirmed, the marker is absent, or the request identifiers disagree. That conservative result is intentional. A request that never reached the AJP backend cannot validate the repaired AJP path; a truncated response cannot establish what the missing bytes would have contained.
This helper is not a general parser for arbitrary application data. It assumes a controlled fixture with markers assigned by the evaluator. A production response could legitimately mention another identifier, and an untrusted response field cannot independently prove its own provenance. Preserve request-to-response correlation outside the body and review the fixture before using the classification.
Close the finding with deployment and behavior evidence
A useful closeout joins two records. The deployment record identifies the fixed artifact and every backend that can receive traffic. The behavior record shows that the intended route and synthetic workflows still work under the approved test conditions. Neither record substitutes for the other.
Test an ordinary small response as a positive control, the application’s relevant larger non-blocking response, and a following request with a different marker. Also inspect failure handling and a normal repeat request. Record the observed sequence rather than claim that every possible timing condition was exercised. These are proposed regression checks, not a published exploit recipe or a benchmark of a security product.
If you use an AI-assisted testing workflow, require its report to state the access it actually received. A remote application assessment cannot be assumed to know a private connector configuration, an image digest, or a vendor backport. Have the service owner supply those facts, then correlate them with sanitized application observations. The accompanying video demonstrates a broader Penligent workflow; it is not an AJP exploit demonstration.
Questions Tomcat operators are asking
Which version fixes CVE-2026-103119?
Apache identifies 11.0.27 as the fixing upstream release. Match a packaged or embedded deployment to its vendor notice and confirm the repaired artifact is running.
Does this issue affect every Tomcat version?
The published affected range is 11.0.0-M25 through 11.0.26. Do not copy affected ranges from other Tomcat CVEs into this assessment.
Can an HTTPS application still use the affected AJP path?
Yes. HTTPS can terminate at a proxy that uses AJP for its backend hop. Inspect the actual proxy mapping and Tomcat connector.
Does an AJP secret remove the need to patch?
No. Worker authentication and response-isolation correctness are separate controls. A valid worker can still use the affected processing path.
Is this the same as the HTTP/2 response mix-up?
No. Identify the CVE and protocol path separately. A shared fixing release does not make the mechanisms or exposure prerequisites interchangeable.
Does the offline helper prove that our server is safe?
No. It checks six synthetic evidence records and performs no network test. A matching record does not exhaust the possible behavior of a deployed server.
What should we investigate after an unexpected response body?
Preserve sanitized request correlation, backend identity, timestamps, and the relevant body fragment. Examine application state, caching, proxy routing, and runtime versions before attributing the symptom. Follow the incident process if protected information may have crossed a boundary.
Close this change when the running artifact, effective route, and bounded validation evidence agree. If one remains unknown, keep that gap visible instead of converting an update command or a single successful page load into a security conclusion.

