
Autoverificação dos 11 avisos de segurança de 2026 do jackson-databind: escaneie as anotações do código-fonte para reduzir o ruído e descubra quantas realmente afetam você; calcule a interseção item a item e indique as versões realmente adequadas (2.18.9/2.21.5/3.1.5, não a 2.21.4, a mais comum no advisory) CVE-2026-54515 / CVE-2026-54512
Ferramenta de auto-verificação dos 11 avisos de segurança de 2026 do jackson-databind. Jar único com zero dependências, sem acesso à rede.
Ela responde a duas perguntas que o Dependabot não consegue responder:
@JsonView / tipos polimórficos / correspondência sem diferenciar maiúsculas de minúsculas……), reduzindo o ruído de "versão afetada instalada" para "realmente atingiu esse recurso".java -jar jackson-check.jar ./target ./src
Dos 11 avisos de 2026, 8 indicam como versão corrigida 2.21.4 / 2.18.8 / 3.1.4. Quem atualiza seguindo isso acha que estava tudo resolvido.
A resposta real, calculando a interseção aviso por aviso, é:
Os que elevam a versão-alvo são estes três:
CVE-2026-54515 — desserialização sem diferenciar maiúsculas de minúsculas contorna o @JsonIgnoreProperties por propriedade
CVE-2026-59889 — @JsonView não funciona em propriedades de contêiner @JsonUnwrapped
🔴 GHSA-mhm7-754m-9p8w — não tem número CVE, e o próprio texto do advisory diz:
a correção nunca foi portada para 2.21 ou 2.18 … Usuários nas versões 2.21.4 e 2.18.8 que atualizaram conforme os advisories publicados continuam vulneráveis
É uma lacuna de patch: a linha 3.x foi corrigida, mas o backport para as linhas 2.18 / 2.21 ficou faltando. Como não há número CVE, procurar por número de CVE não a encontra.
Basta rodar uma vez para ver:
# 已经升到 2.21.4 的项目
java -jar jackson-check.jar ./lib ./src
# Dependabot 会报给你:3 条
# 🔥 注意:如果你照着 advisory 里出现最多的那个修复版升,以下 3 条仍然中
| Coordenada | O que foi realmente publicado no Maven Central |
|---|---|
com.fasterxml.jackson.core:jackson-databind | apenas 2.x |
tools.jackson.core:jackson-databind | apenas 3.x |
Já nos campos estruturados do advisory:
com.fasterxml.jackson.core estão 6 intervalos de 3.x, com versão corrigida 3.1.4 → HTTP 404 nessa coordenadatools.jackson.core está 1 intervalo de 2.x, com versão corrigida 2.21.4 → igualmente HTTP 404Uma ferramenta que copia os advisories ao pé da letra fará você instalar algo que não existe. Esta ferramenta verifica a disponibilidade de cada item com requisições HEAD ao gerar a tabela de decisão; o que não estiver disponível é sinalizado no relatório, sem ser impresso como sugestão de atualização.
O artifactId e o nome do arquivo jar das duas coordenadas são idênticos; só dá para diferenciar pelo META-INF — por isso esta ferramenta decide pela coordenada, e não pelo nome do arquivo.
Para o mesmo 2.18.5, duas bases de código dão resultados completamente diferentes:
一份用了多态类型 + @JsonView 的代码 → Dependabot 报 7 条,真中 6 条
一份只 new 了个 ObjectMapper 的代码 → Dependabot 报 7 条,真中 0 条
É preciso deixar claros os dois lados; falar apenas de um lado é enganoso:
① "Nenhuma condição de disparo encontrada" não significa segurança. Três situações transformam isso numa falsa tranquilidade:
ObjectMapper.addMixIn) etc.; essa palavra simplesmente não existe no código-fonte;② "Todas as condições de disparo estão presentes" tampouco confirma a vulnerabilidade. As marcações são agregadas em toda a base de código, não pela mesma classe nem pelo mesmo campo. Por exemplo, um aviso exige que @JsonView e @JsonUnwrapped estejam anotados na mesma propriedade, mas só conseguimos ver que essas duas palavras apareceram no seu código.
Esta ferramenta faz apenas correspondência de texto, não análise de AST. É uma escolha deliberada: o caminho crítico precisa ser legível para que alguém possa conferir por conta própria — quando uma decisão baseada em AST incompreensível dá errado, ninguém consegue perceber.
A determinação de versão (primeira etapa) é rígida; a determinação de condições de disparo (segunda etapa) serve apenas para priorizar, não para isentar de risco.
Sobre o ponto cego do Dependabot: nenhum dos 11 avisos deste lote está nele. A página de advisories do repositório oficial tem 11 avisos; a consulta reversa pelas duas coordenadas totaliza 11; a diferença é 0 — essa é uma conclusão obtida depois de consultar as duas fontes, não um valor padrão de quem consultou apenas uma fonte (o ASSERT2 de tools/gen_rules.py re-verifica isso a cada execução). Portanto, os alertas de versão do Dependabot neste lote são precisos; o valor desta ferramenta está na redução de ruído e no cálculo de interseção, não em tapar lacunas.
java -jar jackson-check.jar <路径...> [选项]
<路径> jar / war / 目录。目录会同时找构建产物(定版本)和 .java 源码(定触发条件)
--src <路径> 额外指定源码目录
--no-src 不扫源码(只按版本判,粒度等同 Dependabot)
--all 把未命中的条目也列出来
-v, --version 版本号
-h, --help 帮助
Códigos de saída: 0 = versão não afetada · 2 = versão afetada, mas nenhuma condição de disparo encontrada no código-fonte (ou o código-fonte não foi escaneado) · 3 = as condições de disparo também estão presentes. Pode ser usado diretamente em CI.
Formatos reconhecidos: jar comum, fat jar do Spring Boot (BOOT-INF/lib/), WAR tradicional (WEB-INF/lib/) e jackson embutido via shade no jar hospedeiro (as coordenadas da dependência não ficam visíveis, mas o META-INF/maven continua lá).
# Maven 项目
mvn package && java -jar jackson-check.jar target src
# 只有一个成品 jar
java -jar jackson-check.jar app.jar
# Gradle 项目
java -jar jackson-check.jar build/libs src/main/java
Requer Java 17+. Zero dependências em tempo de execução — em especial, não depende do próprio jackson.
O tools/gen_rules.py gera o CveTable.java a partir de duas fontes primárias:
/repos/FasterXML/jackson-databind/security-advisories — conjunto completo de entradas publicadas pelos mantenedores + texto original das descrições/advisories?ecosystem=maven&affects=<coordenada> — índice de coordenadas que o Dependabot realmente usa (uma consulta para cada groupId)Os 11 advisories se expandem em 37 regras "advisory × coordenada × intervalo de versão", com 13 asserções; se qualquer uma não for satisfeita, o processo é interrompido e nenhum arquivo é gravado — para evitar "gerar uma tabela vazia após falha de parsing e os testes continuarem todos verdes":
python tools/gen_rules.py # 需要已登录的 gh CLI
56 testes unitários + 7 cenários de ponta a ponta com artefatos reais (jars reais: 2.13.0 / 2.18.5 / 2.21.2 / 2.21.4 / 2.21.5 / 3.1.2 / 3.1.5).
Apache-2.0
| Ramo de manutenção | Mais comum nos advisories | Versão realmente adequada |
|---|
| 2.18.x | 2.18.8 | 2.18.9 |
| 2.21.x | 2.21.4 | 2.21.5 |
| 2.22.x | — | 2.22.1 |
| 3.1.x | 3.1.4 | 3.1.5 |
| 3.2.x | — | 3.2.1 |
| Condição de disparo | Avisos relacionados |
|---|
@JsonView | CVE-2026-54517 / 54518 / 59889 / GHSA-mhm7 |
@JsonTypeInfo / activateDefaultTyping / PolymorphicTypeValidator | CVE-2026-54512 / 54513 |
@JsonIgnoreProperties + ACCEPT_CASE_INSENSITIVE_PROPERTIES | CVE-2026-54515 |
@JsonIgnore + renomeação de @JsonProperty | CVE-2026-54516 |
Java Record + PropertyNamingStrategy + @JsonIgnore | CVE-2026-59888 |
campo InetSocketAddress | CVE-2026-54514 |
readTree() + JsonNode.toString() | CVE-2026-50193 |
| Asserção | O que verifica |
|---|
| ASSERT2 | ⭐ Comparação de ponto cego entre as duas fontes; a diferença deve ser 0 ou ser explicada item por item |
| ASSERT6 | Os dois groupIds devem ser cobertos |
| ASSERT7 | Faz uma requisição HEAD para cada versão corrigida verificando a disponibilidade no Maven Central |
| ASSERT8 | Fantasma bidirecional: baixa o maven-metadata.xml para provar que toda a linha de versão principal não existe naquela coordenada |
| ASSERT9 | Calcula a interseção por ramo, e ela deve ser realmente superior à menor versão corrigida do mesmo ramo |
| ASSERT11 | A string âncora de cada condição de disparo deve aparecer literalmente no texto original da descrição oficial |
| ASSERT12 | Cada aviso deve ter pontuação CVSS (união das duas fontes) |
| ID | Severidade | Tema |
|---|
| CVE-2026-54512 | high 8.1 | Bypass do parâmetro genérico de PolymorphicTypeValidator |
| CVE-2026-54513 | high 8.1 | Bypass da allowlist de subtipos de array em allowIfSubTypeIsArray() |
| CVE-2026-50193 | medium 7.5 | Estouro de pilha em JsonNode.toString() profundamente aninhado |
| CVE-2026-54514 | medium 5.3 | Desserialização de InetSocketAddress dispara DNS (SSRF) |
| CVE-2026-54515 | medium 5.3 | Reconstrução sem diferenciar maiúsculas de minúsculas sobrescreve o @JsonIgnoreProperties por propriedade |
| CVE-2026-54516 | medium 5.3 | Setter renomeado com @JsonIgnore ainda pode ser gravado por meio do campo privado |
| CVE-2026-54517 | medium 5.3 | @JsonView não funciona em propriedades de creator sem setter |
| CVE-2026-54518 | medium 6.5 | @JsonView não funciona em parâmetros de creator unwrapped |
| CVE-2026-59888 | medium 6.5 | @JsonIgnore em propriedades de Record é contornado pela estratégia de nomenclatura |
| CVE-2026-59889 | medium 6.5 | @JsonView não funciona em propriedades de contêiner @JsonUnwrapped |
| GHSA-mhm7-754m-9p8w | medium 6.5 | Sem número CVE · lacuna de patch em @JsonView + As.EXTERNAL_PROPERTY |