CVE-2026-34486
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 Server Pages, Jakarta Expression Language, Jakarta WebSocket, Jakarta Annotations, and Jakarta Authentication specifications, providing a pure Java HTTP web server environment for running Java code. It is one of the most widely used Java application servers.
A high-severity vulnerability (CVE-2026-34486) has been identified in Apache Tomcat as a regression introduced by the fix for CVE-2026-29146. The fix for the padding oracle vulnerability inadvertently allowed the EncryptInterceptor to be bypassed entirely, meaning unencrypted cluster messages could pass through even when encryption is configured.
Per OWASP: Incorrectly Configured Access Control occurs when security controls are not properly configured, leading to weakened security postures. In this case, a code change intended to fix one security issue introduced a new issue that completely bypasses the encryption protection for cluster communication.
This issue is fixed in NES for Apache Tomcat 8.5.105, and affects versions 9.0.116, 10.1.53, and 11.0.20 of Apache Tomcat.
Details
Module Info
- Product: Apache Tomcat
- Affected packages: tomcat-tribes
- Affected versions: 9.0.116, 10.1.53, 11.0.20
- GitHub repository: https://github.com/apache/tomcat
- Published packages: https://repo1.maven.org/maven2/org/apache/tomcat/tomcat-tribes/
- Package manager: Maven
- Fixed in:
- NES for Apache Tomcat 8.5.105
- Apache Tomcat 11.0.21, 10.1.54, 9.0.117 (OSS)
Vulnerability Info
The vulnerability is a regression in the EncryptInterceptor.java class, specifically in the messageReceived() method. The fix for CVE-2026-29146 (commit 0112ed22) moved the super.messageReceived(msg) call outside the try-catch block:
// Vulnerable code (super.messageReceived outside try):
public void messageReceived(ChannelMessage msg) {
try {
byte[] data = msg.getMessage().getBytes();
data = encryptionManager.decrypt(data);
XByteBuffer xbb = msg.getMessage();
xbb.clear();
xbb.append(data, 0, data.length);
} catch (GeneralSecurityException gse) {
log.error(...);
}
super.messageReceived(msg);
}
When decryption fails (throwing a GeneralSecurityException), the exception is caught and logged, but execution continues to super.messageReceived(msg). This means the original unencrypted or malformed message is forwarded to the application, completely bypassing the EncryptInterceptor's protection.
The fix (commit 776e12b3) moves super.messageReceived(msg) back inside the try block, so it is only called when decryption succeeds:
// Fixed code (super.messageReceived inside try):
public void messageReceived(ChannelMessage msg) {
try {
byte[] data = msg.getMessage().getBytes();
data = encryptionManager.decrypt(data);
XByteBuffer xbb = msg.getMessage();
xbb.clear();
xbb.append(data, 0, data.length);
super.messageReceived(msg);
} catch (GeneralSecurityException gse) {
log.error(...);
}
}
In the upstream OSS releases, only a single version per branch is affected (9.0.116, 10.1.53, 11.0.20) because the regression was introduced and fixed in consecutive releases. The NES for Apache Tomcat 8.5.x branch is also affected because the CVE-2026-29146 fix was backported and contains the same super.messageReceived(msg) placement outside the try-catch block, but fixes for both CVEs were released in the same version (nes-v8.5.105) so there are no vulnerable releases.
Mitigation
Only recent versions of Apache Tomcat are community-supported. Older versions (8.5.x and earlier) will not receive any updates to address this issue. NES for Tomcat includes an update to 8.5.x to address this issue. For more information, see here.
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
- Bartlomiej Dmitruk from striga.ai (finder)