psf-tomcat-oct2026-check(8)
Apache Tomcat October 2026: request/response mix-up checker (v1)
CVE-2026-103119 (AJP response mix-up, 11.0.x)
CVE-2026-101356 (HTTP/2 request and response mix-up, 9.0 / 10.1 / 11.0)
If this software is helpful, consider a donation to our 501c3 nonprofit:
https://privacysafe.foundation
Two Apache Tomcat bugs disclosed on 20 October 2026 can hand one user's
response, or part of it, to another user.
CVE-2026-103119 A buffer under-read means a large non-blocking write over
AJP can split the response body between the current request
and the next request on the same connection.
Affected: 11.0.0-M25 through 11.0.26. Fixed: 11.0.27.
CVE-2026-101356 Incorrect object recycling in HTTP/2 handling of
asynchronous servlets can mix up requests or responses
between users.
Affected: 11.0.22 - 11.0.26, 10.1.55 - 10.1.60,
9.0.118 - 9.0.122. Fixed: 11.0.27, 10.1.61, 9.0.123.
"check" is read-only; "mitigate" and "rollback" are the only commands that change
anything. "check" finds Tomcat installs, reads the exact version
from lib/catalina.jar, and reads server.xml to see whether the AJP connector
and HTTP/2 are switched on. It never starts or stops Tomcat.
Usage:
./tomcat-oct2026-check.sh [command] [CATALINA_HOME ...]
check (default) find installs (CATALINA_HOME, CATALINA_BASE, running
processes, and common paths such as /opt/tomcat*,
/usr/share/tomcat*, /usr/local/tomcat) or use the
directories you pass. Exit 0 = nothing exposed, 1 = an
affected version is exposed or its config could not be read.
mitigate --ajp | --http2 [...] (root) changes the host. The protective measures from
the README, applied to server.xml. With no option it applies --http2,
the low-impact measure; --ajp is added on request because it can break
something:
--ajp comments out every AJP Connector. Only for 11.x below
11.0.27 (CVE-2026-103119). Anything that reaches
Tomcat over AJP (Apache mod_proxy_ajp or mod_jk) stops
working: move it to HTTP proxying first.
--http2 comments out every UpgradeProtocol element for HTTP/2.
Only for 11.0.22-11.0.26, 10.1.55-10.1.60 and
9.0.118-9.0.122 (CVE-2026-101356). Clients that talk
HTTP/2 straight to Tomcat fall back to HTTP/1.1; a
proxy in front can still speak HTTP/2 to them.
Elements are commented out, never deleted. server.xml is copied
first and checked with xmllint (or python3) before and after; if
the result is not well-formed the original is put back at once.
Nothing is restarted unless you add --restart (Tomcat reads
server.xml at start; a restart ends requests in progress).
Other options: --dry-run, --restart, and CATALINA_HOME
directories to use instead of discovery. These are our
measures from PrivacySafe; the permanent fix is the upgrade.
rollback [--dry-run] [--restart] put back every file mitigate changed.
version print the script version.
STATE_DIR (default /var/lib/psf-security-patches/tomcat) holds the backups and manifest.
Running docker and podman containers are inspected too (see "Containers" below). An image that is
not running is not: check its tag against the fixed versions.
Containers: with no argument the check also looks in running docker and podman containers
(SCAN_CONTAINERS=1, the default; 0 skips them). A read-only probe captures the daemon's version
output and its configuration (secrets are redacted inside the container before anything is
copied) into a private temporary directory, and this script then runs once per container, in
isolation, against that copy. Paths shown as .../docker_NAME/... are inside the container NAME.
PSF_LOCK_WAIT seconds a run that changes the host waits for another one that is already
changing it (default 30), then stops with exit 2; the lock is STATE_DIR/.lockThe Security Patches software and this documentation are dedicated to the public domain under CC0 1.0 Universal. Other pages on privacysafe.app/docs are CC BY-SA 4.0 unless the page says otherwise.