
CVE Reproduction: cve-2026-34486-tomcat_encrypt_bypass_reproduction
| Поле | Значение |
|---|---|
| CVE | CVE-2026-34486 |
| CVSS | 7.5 HIGH |
| Тип | Отсутствие шифрования конфиденциальных данных |
| Компонент | Apache Tomcat Cluster EncryptInterceptor |
| Опубликовано | 2026 |
CVE-2026-34486 — это регрессия, вызванная неполным исправлением для CVE-2026-29146. В кластерной репликации Apache Tomcat за шифрование и аутентификацию кластерных сообщений отвечает EncryptInterceptor. Рефакторинг в исправлении для CVE-2026-29146 случайно переместил вызов super.messageReceived(msg) за пределы блока try-catch, который обрабатывает ошибки расшифровки. В результате, когда сообщение не удаётся расшифровать (т.е. оно получено в открытом виде, но перехватчик ожидает зашифрованные данные), исходное незашифрованное сообщение всё равно передаётся по цепочке обработчиков вместо того, чтобы быть отброшенным.
Метод EncryptInterceptor.messageReceived() вызывается при поступлении кластерного сообщения. Ожидаемый поток:
super.messageReceived(msg) для передачи расшифрованного сообщенияВ уязвимых версиях логика расшифровки/проверки остаётся обёрнутой в try-catch, но цепочка вызовов была перестроена так, что super.messageReceived(msg) выполняется за пределами блока try-catch, защищающего расшифровку. Переменная msg объявляется до try-catch и присваивается внутри него. Когда расшифровка вызывает исключение, msg сохраняет своё исходное (незашифрованное/сырое) значение, а блок catch только записывает ошибку — он не выполняет досрочный возврат. Выполнение продолжается до super.messageReceived(msg) с необработанными сырыми данными.
Это означает, что злоумышленник, имеющий доступ к порту кластера Tomcat, может отправлять произвольные незашифрованные сообщения, которые перехватчик примет и обработает.
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
}
Исправление должно гарантировать, что либо:
super.messageReceived(msg) вызывается только внутри блока try после успешной расшифровки, либо| Продукт | Версии |
|---|---|
| Apache Tomcat 11 | 11.0.20 |
| Apache Tomcat 10 | 10.1.53 |
| Apache Tomcat 9 | 9.0.116 |
EncryptInterceptor<Receiver>)EncryptInterceptor в server.xml.Скрипт exploit.py в этом каталоге демонстрирует обход. Он создаёт минимальное кластерное сообщение Tomcat (на основе формата сериализации ClusterMessage) и отправляет его напрямую на порт приёмника без какого-либо шифрования. Уязвимый перехватчик примет и передаст сообщение, несмотря на отсутствие шифрования.
Обновитесь до исправленной версии Apache Tomcat:
| Продукт | Исправленная версия |
|---|---|
| Apache Tomcat 11 | 11.0.21+ |
| Apache Tomcat 10 | 10.1.54+ |
| Apache Tomcat 9 | 9.0.117+ |
Если немедленное обновление невозможно, ограничьте сетевой доступ к порту кластера Tomcat только доверенными узлами (например, с помощью правил брандмауэра или привязки приёмника к интерфейсу loopback или частному интерфейсу).