
CVE-Reproduktion: cve-2026-34486-tomcat_encrypt_bypass_reproduction
| Feld | Wert |
|---|
| CVE | CVE-2026-34486 |
| CVSS | 7.5 HOCH |
| Typ | Fehlende Verschlüsselung sensibler Daten |
| Komponente | Apache Tomcat Cluster EncryptInterceptor |
| Veröffentlicht | 2026 |
CVE-2026-34486 ist eine Regression, die durch die unvollständige Behebung von CVE-2026-29146 eingeführt wurde. In der Cluster-Replikation von Apache Tomcat ist der EncryptInterceptor für die Verschlüsselung und Authentifizierung von Cluster-Nachrichten zuständig. Ein Refactoring im Fix für CVE-2026-29146 verlagerte versehentlich den Aufruf von super.messageReceived(msg) aus dem try-catch-Block, der Fehler bei der Entschlüsselung behandelt. Infolgedessen wird, wenn eine Nachricht nicht entschlüsselt werden kann (d.h. sie wird im Klartext empfangen, aber der Interceptor erwartet verschlüsselte Daten), die unverschlüsselte Roh-Nachricht trotzdem an die Handler-Kette weitergegeben, anstatt verworfen zu werden.
Die Methode EncryptInterceptor.messageReceived() wird aufgerufen, wenn eine Cluster-Nachricht eintrifft. Der erwartete Ablauf ist:
super.messageReceived(msg) zur Weiterleitung der entschlüsselten NachrichtIn den verwundbaren Versionen bleibt die Entschlüsselungs- und Validierungslogik zwar in einem try-catch eingeschlossen, aber die Aufrufstruktur wurde so umgestellt, dass super.messageReceived(msg) außerhalb des try-catch-Blocks ausgeführt wird, der die Entschlüsselung schützt. Die Variable msg wird vor dem try-catch deklariert und innerhalb dessen zugewiesen. Wenn die Entschlüsselung eine Exception auslöst, behält msg ihren ursprünglichen (unverschlüsselten/rohen) Wert, und der catch-Block protokolliert lediglich den Fehler – er kehrt nicht vorzeitig zurück. Die Ausführung fährt mit super.messageReceived(msg) und den unverarbeiteten Rohdaten fort.
Das bedeutet, ein Angreifer, der den Tomcat-Cluster-Port erreichen kann, kann beliebige unverschlüsselte Nachrichten einschleusen, die der Interceptor akzeptiert und verarbeitet.
public void messageReceived(Message msg) {
// msg arrives raw
try {
// decrypt and populate msg fields
decrypt(msg);
} catch (Exception e) {
log.error("Decryption failed", e);
// BUG: no return statement here
}
// msg is still the original unencrypted object when catch is hit
super.messageReceived(msg); // outside try-catch → passes raw data
}
Die Behebung muss sicherstellen, dass entweder:
super.messageReceived(msg) nur innerhalb des try-Blocks nach erfolgreicher Entschlüsselung aufgerufen wird, oder| Produkt | Versionen |
|---|---|
| Apache Tomcat 11 | 11.0.20 |
| Apache Tomcat 10 | 10.1.53 |
| Apache Tomcat 9 | 9.0.116 |
EncryptInterceptor<Receiver>)EncryptInterceptor in der server.xml konfiguriert hat.Das Skript exploit.py in diesem Verzeichnis demonstriert die Umgehung. Es konstruiert eine minimale Tomcat-Cluster-Nachricht (basierend auf dem Serialisierungsformat von ClusterMessage) und sendet sie direkt ohne Verschlüsselung an den Empfänger-Port. Ein verwundbarer Interceptor akzeptiert und leitet die Nachricht trotz der fehlenden Verschlüsselung weiter.
Upgrade auf eine gepatchte Version von Apache Tomcat:
| Produkt | Gepatchte Version |
|---|---|
| Apache Tomcat 11 | 11.0.21+ |
| Apache Tomcat 10 | 10.1.54+ |
| Apache Tomcat 9 | 9.0.117+ |
Falls ein sofortiges Upgrade nicht möglich ist, schränken Sie den Netzwerkzugriff auf den Tomcat-Cluster-Port auf vertrauenswürdige Hosts ein (z.B. über Firewall-Regeln oder durch Binden des Empfängers an eine Loopback- oder private Schnittstelle).