Autoverificação dos 7 CVEs de "falha silenciosa de configuração" do log4j em 2025/2026: determina 4 módulos pela combinação CVE×módulo, analisa estruturalmente a configuração do log4j2 para reduzir o ruído de aplicabilidade e calcula para qual versão atualizar de uma só vez (6 indicam 2.25.4, mas uma exige 2.25.5, e o Dependabot não a reporta) CVE-2026-49844 / CVE-2026-34477
Ferramenta de autoverificação para os avisos de "falha silenciosa de configuração" do log4j de 2025/2026. Sem dependências de runtime, um único jar, sem acesso à rede.
⚠️ Vamos deixar claro desde já: todos estes são medium, nenhum é RCE, não é como o Log4Shell. O ponto em comum entre eles é que a configuração falha sem nenhum erro — propriedades são silenciosamente ignoradas, propriedades são silenciosamente renomeadas, logs são silenciosamente descartados. Portanto, só olhar o número da versão não diz se você foi afetado; é preciso ler a configuração. Se você está procurando o CVE-2021-44228 (Log4Shell), esta ferramenta não vai ajudar.
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
O Dependabot informa «o log4j tem N vulnerabilidades». Esta ferramenta responde a três coisas que ele não responde:
log4j2.xml, dá para ler, e dá para ler com precisão.Nessas 7 entradas, as versões corrigidas de 6 são ≤ 2.25.4. Então a grande maioria das pessoas chega à resposta «atualizar para 2.25.4».
Mas CVE-2026-49844 exige 2.25.5 (na linha 2.26 exige 2.26.1). O texto original do seu advisory diz que ele é
uma correção incompleta de CVE-2026-34481:
A correção lançada na versão
2.25.4não cobria todos os caminhos de código afetados. CVE-2026-49844 foi atribuído ao problema restante …
📌 Correção (2026-08-16)
Esta seção originalmente dizia «e esta é justamente a que o Dependabot, por razões estruturais, não consegue reportar» —— essa frase agora só está meio certa.
O
GHSA-qv9r-c865-cp47foi convertido pelo GitHub parareviewedem 2026-08-13 e teve as informações de pacote completadas, os dois intervalos adicionados são>= 2.13.1, < 2.25.5e>= 2.26.0, < 2.26.1:
- ✅ Quem roda 2.x agora recebe o alerta do Dependabot.
- 🔴 Mas a linha de prévia
3.x(3.0.0-alpha1~3.0.0-beta2) até hoje não tem intervalo correspondente, essa linha continua sem conseguir reportar.A conclusão de atualização não mudou em nada —— o
log4j-apicontinua exigindo 2.25.5 (a linha 2.26 exige 2.26.1). O que mudou foi apenas «se a máquina consegue vê-lo». A tabela de decisão desta ferramenta foi atualizada linha por linha conforme as linhas de versão, os números impressos no relatório são calculados pela tabela, não mais hardcoded.🔑 Esse fato em si merece mais ser registrado do que o exemplo original: a forma do advisory pode ser completada pela upstream com o tempo, e a conclusão da sua última varredura não se atualiza sozinha, nem ninguém te avisa. «Varri na época» e «agora está seguro» são duas coisas diferentes.
O seu GitHub advisory (GHSA-qv9r-c865-cp47)antes de 2026-08-13 era unreviewed,
e o array vulnerabilities estava vazio —— sem nome de pacote, sem intervalo de versões, sem versão corrigida,
durante esse período o Dependabot não tinha nenhum dado para comparar com a sua árvore de dependências.
No OSV.dev na época era igual: as outras 6 conseguiam obter as coordenadas Maven via alias GHSA, só ele não conseguia
(ele nem tem alias GHSA no OSV). Esta é uma terceira evidência independente de outra fonte,
o tools/recheck_before_publish.py re-verifica a cada execução
(o script agora também reporta o próprio fato de «já ter sido completado»).
🔴 Não leia isto como «o Dependabot é ruim». É «esse dado não existia na época», não «essa ferramenta tem bug».
unreviewedé um estado normal do fluxo do GitHub, e a complementação de 08-13 é justamente esse fluxo sendo concluído normalmente.
A outra cadeia é CVE-2025-68161 (2.25.3) → CVE-2026-34477 (2.25.4):
a propriedade verifyHostName foi introduzida desde 2.12.0, mas foi silenciosamente ignorada até 2.25.3,
configurar era o mesmo que não configurar. Quem atualizou para 2.25.3 seguindo o 68161 e configurou a verificação de hostname pela propriedade (e não por system property) continua vulnerável.
| Módulo | Entradas atingidas | Deve atualizar para |
|---|---|---|
log4j-core | 34477 / 34478 / 34480 / 68161 | 2.25.4 |
log4j-api | 49844 | 2.25.5 (linha 2.26: 2.26.1) |
log4j-1.2-api | 34479 | 2.25.4 |
log4j-layout-template-json | 34481 | 2.25.4 |
A versão alvo não é o mesmo número. E a grande maioria dos projetos só escreve log4j-core no pom
—— consultando por essa única coordenada só se encontram 4, as outras 3 simplesmente não existem para eles.
Esta ferramenta varre as versões dos quatro módulos separadamente e decide separadamente. Quando as versões dos quatro módulos estão defasadas (cobertura de BOM, exclusão manual, WAR antigo com duas gerações de jars enfiadas) ela reporta explicitamente.
| CVE | Condição de disparo (extraída do texto oficial) |
|---|---|
CVE-2026-34477 | propriedade verifyHostName de <Ssl> + appender Socket / Syslog / SMTP |
CVE-2025-68161 | SocketAppender + TLS |
CVE-2026-34478 | configurar diretamente Rfc5424Layout (os que usam SyslogAppender não são afetados) |
CVE-2026-34480 | XmlLayout do log4j-core |
CVE-2026-34479 | Log4j1XmlLayout da ponte, ou camada de compatibilidade log4j 1 + org.apache.log4j.xml.XMLLayout |
CVE-2026-34481 | JsonTemplateLayout + valores de ponto flutuante em MapMessage/ObjectMessage |
CVE-2026-49844 | message resolver do JsonTemplateLayout, ou MapMessage.asJson() |
Testado de verdade (artefato real, veja abaixo): no mesmo conjunto, quatro módulos da versão afetada foram instalados,
Console + RollingFile + PatternLayout) → a camada de versão reporta 7 itens, verdadeiros positivos 0Socket+<Ssl verifyHostName>+Rfc5424Layout+XmlLayout → reporta 7 itens, verdadeiros positivos 4Dois critérios negativos são declarados explicitamente no texto oficial e documentados separadamente:
Quem usa SyslogAppender não é afetado pelo 34478; quem usa apenas o verifyHostname do appender HTTP não é afetado pelo 34477.
O grau de confiabilidade deste item é completamente diferente do de "não encontrei" — o primeiro tem respaldo no texto oficial, o segundo é apenas algo que não vimos.
🔴
verifyHostName(N maiúsculo,<Ssl>, afetado) everifyHostname(n minúsculo, appender HTTP, declarado oficialmente como não afetado) diferem apenas na caixa de uma letra, e a conclusão é completamente oposta. Da mesma forma,XmlLayout(34480, log4j-core) é substring deLog4j1XmlLayout(34479, bridge). Apenas fazer grep pelo nome fará com que as pessoas carreguem CVEs que não são delas. Por isso a camada de configuração faz análise estrutural em vez de correspondência textual.