
Reproduction CVE : cve-2026-34486-tomcat_encrypt_bypass_reproduction
| Champ | Valeur |
|---|---|
| CVE | CVE-2026-34486 |
| CVSS | 7.5 ÉLEVÉ |
| Type | Absence de chiffrement des données sensibles |
| Composant | Apache Tomcat Cluster EncryptInterceptor |
| Publié | 2026 |
CVE-2026-34486 est une régression introduite par le correctif incomplet de la CVE-2026-29146. Dans la réplication de cluster d'Apache Tomcat, l'EncryptInterceptor est chargé de chiffrer et d'authentifier les messages du cluster. Un refactoring effectué dans le correctif de la CVE-2026-29146 a déplacé par inadvertance l'appel super.messageReceived(msg) hors du bloc try-catch qui gère les échecs de déchiffrement. Ainsi, lorsqu'un message échoue au déchiffrement (c.-à-d. qu'il est reçu en clair alors que l'intercepteur s'attend à des données chiffrées), le message brut non chiffré est toujours transmis à la chaîne de gestionnaires au lieu d'être rejeté.
La méthode EncryptInterceptor.messageReceived() est invoquée à l'arrivée d'un message de cluster. Le flux attendu est le suivant :
super.messageReceived(msg) pour transmettre le message déchiffréDans les versions vulnérables, la logique de déchiffrement/validation reste encapsulée dans un try-catch, mais la chaîne d'appels a été restructurée de sorte que super.messageReceived(msg) s'exécute en dehors du bloc try-catch qui protège le déchiffrement. La variable msg est déclarée avant le try-catch et affectée à l'intérieur de celui-ci. Lorsque le déchiffrement lève une exception, msg conserve sa valeur initiale (non chiffrée/brute) et le bloc catch ne fait que journaliser l'erreur — il n'effectue pas de retour anticipé. L'exécution se poursuit avec super.messageReceived(msg) et les données brutes non traitées.
Cela signifie qu'un attaquant pouvant atteindre le port de cluster Tomcat peut injecter des messages arbitraires non chiffrés que l'intercepteur acceptera et traitera.
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
}
Le correctif doit garantir que soit :
super.messageReceived(msg) n'est appelé qu'à l'intérieur du bloc try après un déchiffrement réussi, soit| Produit | Versions |
|---|---|
| Apache Tomcat 11 | 11.0.20 |
| Apache Tomcat 10 | 10.1.53 |
| Apache Tomcat 9 | 9.0.116 |
EncryptInterceptor<Receiver>)EncryptInterceptor configuré dans server.xml.Le script exploit.py de ce répertoire illustre le contournement. Il construit un message de cluster Tomcat minimal (basé sur le format de sérialisation ClusterMessage) et l'envoie directement au port du récepteur sans aucun chiffrement. Un intercepteur vulnérable acceptera et transmettra le message malgré l'absence de chiffrement.
Mettez à jour vers une version corrigée d'Apache Tomcat :
| Produit | Version corrigée |
|---|---|
| Apache Tomcat 11 | 11.0.21+ |
| Apache Tomcat 10 | 10.1.54+ |
| Apache Tomcat 9 | 9.0.117+ |
Si une mise à jour immédiate n'est pas possible, limitez l'accès réseau au port du cluster Tomcat aux seuls hôtes de confiance (par exemple, via des règles de pare-feu ou en liant le récepteur à une interface de bouclage ou privée).