
log4j 2025/2026: самопроверка по 7 CVE «тихого отказа конфигурации»: определение 4 модулей по паре CVE×модуль, структурный разбор конфигурации log4j2 для снижения шума applicability, и расчёт, до какой версии обновляться, чтобы сделать всё сразу (для 6 записей — 2.25.4, но для одной нужна 2.25.5, а её Dependabot не показывает) CVE-2026-49844 / CVE-2026-34477
Инструмент самопроверки для серии объявлений 2025/2026 годов о «тихом отказе конфигурации» в log4j. Без зависимостей во время выполнения, один jar, без сетевого доступа.
⚠️ Сначала проясним формулировку: всё это medium, ни одной RCE, это не Log4Shell. Их общая черта — конфигурация перестаёт работать без каких-либо сообщений об ошибках — свойства молча игнорируются, свойства молча переименовываются, логи молча теряются. Поэтому по одному номеру версии не понять, затронуты ли вы, нужно читать конфигурацию. Если вы ищете CVE-2021-44228 (Log4Shell), этот инструмент вам не поможет.
java -jar log4j-check.jar app.jar # fat jar 里带配置,一步到位
java -jar log4j-check.jar ./target ./src # 构建产物 + 源码
java -jar log4j-check.jar ~/.m2/repository --no-config
Dependabot сообщает вам «в log4j есть N уязвимостей». Этот инструмент отвечает на три вопроса, на которые он не отвечает:
log4j2.xml, это можно прочитать, и прочитать точно.Из этих 7 записей у 6 исправленная версия ≤ 2.25.4. Поэтому подавляющее большинство приходит к ответу «обновиться до 2.25.4».
Но CVE-2026-49844 требует 2.25.5 (для линии 2.26 — 2.26.1). В тексте его advisory прямо сказано, что он
является неполным исправлением CVE-2026-34481:
Исправление, выпущенное в версии
2.25.4, не охватывало все затронутые пути кода. Для оставшейся проблемы был назначен идентификатор CVE-2026-49844 …
📌 Исправление (2026-08-16)
В этом разделе изначально было написано «а эта запись как раз та, которую Dependabot структурно не может показать» — теперь это утверждение верно лишь наполовину.
GHSA-qv9r-c865-cp4713.08.2026 был переведён GitHub в статусreviewedи дополнен информацией о пакете, добавлены два диапазона:>= 2.13.1, < 2.25.5и>= 2.26.0, < 2.26.1:
- ✅ Те, кто работает на 2.x, теперь получают оповещения Dependabot.
- 🔴 Но для предварительной линии
3.x(3.0.0-alpha1~3.0.0-beta2) до сих пор нет соответствующего диапазона, и по этой линии оповещение по-прежнему не появляется.Вывод об обновлении совершенно не изменился —
log4j-apiпо-прежнему требует 2.25.5 (для линии 2.26 — 2.26.1). Изменилось только то, «видит ли это машина». Таблица решений этого инструмента обновлена построчно по линиям версий; числа, печатаемые в отчёте, вычисляются по таблице, а не захардкожены.🔑 Само это событие заслуживает запоминания больше, чем прежний пример: форма advisory со временем дополняется вышестоящими, а вывод вашего прошлого сканирования сам не обновится, и никто вас не уведомит. «Тогда просканировали» и «сейчас безопасно» — это две разные вещи.
Его GitHub advisory (GHSA-qv9r-c865-cp47) до 13.08.2026 был в статусе unreviewed,
а массив vulnerabilities был пуст — ни имени пакета, ни диапазона версий, ни исправленной версии;
всё это время Dependabot не мог получить никаких данных, которые можно было бы сопоставить с вашим деревом зависимостей.
На OSV.dev тогда было то же самое: остальные 6 записей можно было получить через GHSA alias с координатами Maven, только эту получить было нельзя
(у неё в OSV даже не было GHSA alias). Это независимое подтверждение из третьего источника;
tools/recheck_before_publish.py при каждом перезапуске заново это проверяет
(теперь этот скрипт также сообщает и сам факт «уже дополнено»).
🔴 Не читайте эту запись как «Dependabot плохой». Это «этих данных тогда не существовало», а не «в этом инструменте баг».
unreviewed— нормальное состояние процесса GitHub, и дополнение 13.08 — как раз нормальное завершение этого процесса.
Другая цепочка — CVE-2025-68161 (2.25.3) → CVE-2026-34477 (2.25.4):
свойство verifyHostName было введено с 2.12.0, но вплоть до 2.25.3 молча игнорировалось,
настроить его было равносильно тому, чтобы не настраивать. Те, кто по 68161 обновился до 2.25.3 и настраивал проверку имени хоста через свойство (а не через system property), по-прежнему уязвимы.
| Модуль | Совпавшие записи | Нужно обновиться до |
|---|---|---|
log4j-core | 34477 / 34478 / 34480 / 68161 | 2.25.4 |
log4j-api | 49844 | 2.25.5 (линия 2.26: 2.26.1) |
log4j-1.2-api | 34479 | 2.25.4 |
log4j-layout-template-json | 34481 | 2.25.4 |
Целевая версия — не одно и то же число. А в pom большинства проектов указан только log4j-core
— при проверке по этой одной координате находится лишь 4 записи, остальные 3 для них вообще не существуют.
Этот инструмент сканирует версии четырёх модулей по отдельности и по отдельности выносит решение. Когда версии четырёх модулей расходятся (переопределение BOM, ручное исключение, два поколения jar в старом WAR), он явно об этом сообщает.
| CVE | Условия срабатывания (из официального текста) |
|---|---|
CVE-2026-34477 | свойство verifyHostName у <Ssl> + Socket / Syslog / SMTP appender |
CVE-2025-68161 | SocketAppender + TLS |
CVE-2026-34478 | прямая настройка Rfc5424Layout (использующие SyslogAppender не затронуты) |
CVE-2026-34480 | XmlLayout из log4j-core |
CVE-2026-34479 | Log4j1XmlLayout моста, или слой совместимости с log4j 1 + org.apache.log4j.xml.XMLLayout |
CVE-2026-34481 | JsonTemplateLayout + значения с плавающей точкой в MapMessage/ObjectMessage |
CVE-2026-49844 | message resolver в JsonTemplateLayout, или MapMessage.asJson() |
Проверено на практике (реальные артефакты, см. ниже): в одном наборе установлены четыре модуля затронутых версий,
Console + RollingFile + PatternLayout) → уровень версий сообщает 7 записей, реально подтверждено 0Socket+<Ssl verifyHostName>+Rfc5424Layout+XmlLayout → сообщается 7 записей, реально подтверждено 4Два отрицательных критерия прямо указаны в официальном тексте, выделены в отдельный пункт:
Использующие SyslogAppender не попадают под 34478; использующие только HTTP appender с verifyHostname не попадают под 34477.
Достоверность этого пункта и пункта «я не нашёл» совершенно разная — первый подкреплён официальным текстом, второй лишь означает, что мы не увидели.
🔴
verifyHostName(заглавная N,<Ssl>, уязвим) иverifyHostname(строчная n, HTTP appender, официально указано как не затронут) различаются лишь регистром одной буквы, а выводы полностью противоположны. АналогичноXmlLayout(34480, log4j-core) является подстрокойLog4j1XmlLayout(34479, мост). Простой grep по именам заставит людей дополнительно нести ответственность за чужие CVE. Поэтому на уровне конфигурации выполняется структурный разбор, а не текстовое сопоставление.