CVE-2026-93446
Patch Available.
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Apache Tomcat is an open-source implementation of the Jakarta Servlet, Jakarta Pages, Jakarta Expression Language, Jakarta WebSocket, Jakarta Annotations, and Jakarta Authentication specifications. It serves Java web applications either as a standalone servlet container and HTTP server or embedded inside an application through the tomcat-embed-core artifact. Its Catalina servlet container (org.apache.tomcat:tomcat-catalina) supplies the request-processing pipeline, including Valves such as RewriteValve, along with connectors, realms, and session management.
A denial of service vulnerability (CVE-2026-93446) has been identified in the TLS handling of the Apache Tomcat NIO connector, which can cause TLS 1.3 connections to fail intermittently. A flag that tracks pending TLS handshake data is not cleared when it should be, so a later connection or a later stage of the same connection can be closed with an I/O error.
Per OWASP: The Denial of Service (DoS) attack is focused on making a resource (site, application, server) unavailable for the purpose it was designed. There are many ways to make a service unavailable for legitimate users by manipulating network packets, programming, logical, or resources handling vulnerabilities, among others.
This issue affects multiple versions of Apache Tomcat.
Details
Module Info
- Product: Apache Tomcat
- Affected packages:
org.apache.tomcat:tomcat-coyote,org.apache.tomcat.embed:tomcat-embed-core - Affected versions: >=9.0.90 <=9.0.122, >=10.1.25 <=10.1.60, >=11.0.0-M21 <=11.0.26
- GitHub repository: https://github.com/apache/tomcat
- Published packages: https://central.sonatype.com/artifact/org.apache.tomcat/tomcat-coyote, https://central.sonatype.com/artifact/org.apache.tomcat.embed/tomcat-embed-core
- Package manager: Maven
- Fixed in:
- OSS Apache Tomcat 9.0.123, 10.1.61, 11.0.27
- NES for Apache Tomcat 8.5.100-tomcat-8.5.113
Vulnerability Info
This Low-severity vulnerability is found in the org.apache.tomcat:tomcat-coyote and org.apache.tomcat.embed:tomcat-embed-core packages in multiple versions of Apache Tomcat. The NIO connector encrypts and decrypts TLS traffic in org.apache.tomcat.util.net.SecureNioChannel. To support TLS 1.3 re-keying, the channel keeps a needHandshakeWrap flag. When a read leaves the SSLEngine needing to send handshake data while application data is still waiting to go out, the read path records that the handshake data is pending. If the flag is already set at that point, the read fails:
} else if (unwrap.getHandshakeStatus() == HandshakeStatus.NEED_WRAP) {
if (getOutboundRemaining() == 0) {
handshakeWrap(true);
} else if (needHandshakeWrap) {
throw new IOException(sm.getString("channel.nio.ssl.handshakeWrapPending"));
} else {
needHandshakeWrap = true;
}
}
The flag is meant to be cleared once the pending handshake data has been sent. The single-buffer write(ByteBuffer) method does this after calling sslEngine.wrap(), which includes any required handshake data. The gathering write(ByteBuffer[], int, int) method calls sslEngine.wrap() without clearing it, and reset(), which prepares a pooled channel for reuse by a new connection, resets the other handshake state but leaves needHandshakeWrap alone:
public void reset(SocketChannel channel, NioSocketWrapper socketWrapper) throws IOException {
super.reset(channel, socketWrapper);
sslEngine = null;
if (channel != null) {
sniComplete = false;
handshakeComplete = false;
closed = false;
closing = false;
netInBuffer.clear();
}
}
A stale true value therefore survives a gathering write that has already sent the handshake data, or carries over to the next connection that reuses the pooled channel. The next time a TLS 1.3 read on that channel reaches the NEED_WRAP state with outbound data pending, Tomcat throws an IOException and the connection is closed, even though no handshake data is actually outstanding. The result is intermittent TLS 1.3 connection failures for legitimate clients. Community Apache Tomcat 8.5.x does not include this TLS 1.3 re-keying code and is not affected. NES for Apache Tomcat backported it in its first release, so NES for Apache Tomcat 8.5.100-tomcat-8.5.101 through 8.5.100-tomcat-8.5.112 have the same reset() and gathering write() behavior.
Mitigation
Only recent versions of Apache Tomcat are community-supported. The community support version will not receive any updates to address this issue. For more information, see here. Apache Tomcat release lines that are no longer community-supported are End-of-Life.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a patched version of Apache Tomcat.
- Leverage a commercial support partner like HeroDevs for post-EOL security support.
Credits
- FHMTT (finder)