
jackson-databind 2026: autovalutazione delle 11 advisory di sicurezza — scansiona le annotazioni del codice sorgente per filtrare il rumore e ti dice a quante sei realmente esposto; incrociando le singole advisory indica le versioni davvero adeguate (2.18.9/2.21.5/3.1.5, non la 2.21.4 più comune nelle advisory) CVE-2026-54515 / CVE-2026-54512
Strumento di autocontrollo per gli 11 advisory di sicurezza jackson-databind 2026. Un singolo jar a zero dipendenze, senza connessione di rete.
Risponde a due domande a cui Dependabot non sa rispondere:
@JsonView / tipi polimorfici / corrispondenza senza distinzione maiuscole/minuscole...), riducendo il rumore da «versione vulnerabile installata» a «funzionalità davvero toccata».java -jar jackson-check.jar ./target ./src
Degli 11 advisory del 2026, 8 indicano come versione corretta 2.21.4 / 2.18.8 / 3.1.4. Chi aggiorna seguendo queste indicazioni crede di aver risolto tutto.
La risposta reale, calcolando l'intersezione voce per voce, è:
A far salire l'obiettivo sono queste tre:
CVE-2026-54515 —— la deserializzazione senza distinzione maiuscole/minuscole aggira @JsonIgnoreProperties per singola proprietà
CVE-2026-59889 —— @JsonView non ha effetto sulle proprietà contenitore @JsonUnwrapped
🔴 GHSA-mhm7-754m-9p8w —— senza numero CVE, il testo originale dell'advisory lo dichiara da solo:
the fix was never backported to 2.21 or 2.18 … Users on 2.21.4 and 2.18.8 who upgraded per the published advisories remain vulnerable
È un gap di patch: la linea 3.x è stata corretta, ma il backport alle linee 2.18 / 2.21 è stato saltato. Non avendo un numero CVE, cercandolo per numero CVE non lo si trova.
Basta eseguirlo una volta per vederlo:
# Progetto già aggiornato a 2.21.4
java -jar jackson-check.jar ./lib ./src
# Dependabot ti segnala: 3 voci
# 🔥 Attenzione: se aggiorni alla versione più frequente negli advisory, queste 3 voci restano ancora valide
| Coordinata | Pubblicato effettivamente su Maven Central |
|---|---|
com.fasterxml.jackson.core:jackson-databind | solo 2.x |
tools.jackson.core:jackson-databind | solo 3.x |
Nei campi strutturati degli advisory, invece:
com.fasterxml.jackson.core risultano 6 intervalli 3.x, la cui versione corretta 3.1.4 → HTTP 404 sotto quella coordinatatools.jackson.core risulta 1 intervallo 2.x, la cui versione corretta 2.21.4 → anch'esso HTTP 404Uno strumento che copia gli advisory alla lettera ti farebbe installare qualcosa che non esiste. Questo strumento, quando genera la tabella di giudizio, verifica la disponibilità con richieste HEAD una per una; ciò che non è reperibile viene evidenziato nel report, non stampato come suggerimento di aggiornamento.
Le due coordinate hanno artifactId e nome del file jar identici; solo il contenuto di META-INF permette di distinguerli —— per questo lo strumento giudica in base alla coordinata, non al nome del file.
Con lo stesso 2.18.5, due basi di codice danno risultati completamente diversi:
Un codice che usa tipi polimorfici + @JsonView → Dependabot segnala 7 voci, realmente esposti 6
Un codice che fa solo new ObjectMapper → Dependabot segnala 7 voci, realmente esposti 0
Vanno chiariti entrambi i lati; descriverne solo uno sarebbe fuorviante:
① «Nessuna condizione di attivazione trovata» non equivale a essere al sicuro. Tre situazioni possono trasformarlo in una falsa rassicurazione:
ObjectMapper.addMixIn) e simili, e quella parola nel sorgente non c'è affatto;② «Tutte le condizioni di attivazione sono soddisfatte» non equivale alla conferma dell'esposizione. I flag sono aggregati per l'intera codebase, non per la stessa classe o lo stesso campo. Per esempio, una voce può richiedere che @JsonView e @JsonUnwrapped siano applicati alla stessa proprietà, mentre noi possiamo solo vedere che entrambe le parole compaiono nel tuo codice.
Questo strumento fa solo corrispondenza testuale, non parsing AST. È una scelta deliberata: il percorso critico deve poter essere letto e verificato da una persona —— quando un verdetto AST incomprensibile è sbagliato, nessuno può accorgersene.
Il giudizio sulla versione (primo passo) è determinante; il giudizio sulle condizioni di attivazione (secondo passo) serve solo a stabilire le priorità, non a escludere il rischio.
Sui punti ciechi di Dependabot: in questa serie di 11 non ce n'è nemmeno uno. La pagina degli advisory del repository ufficiale ne conta 11, la ricerca inversa sulle due coordinate ne restituisce in totale 11, differenza 0 —— è una conclusione tratta dopo aver consultato due fonti, non il valore predefinito di chi ne consulta una sola (ASSERT2 di tools/gen_rules.py lo riverifica a ogni riesecuzione). Per questa serie, quindi, gli avvisi di versione di Dependabot sono accurati; il valore di questo strumento sta nella riduzione del rumore e nell'intersezione, non nel tappare i buchi.
java -jar jackson-check.jar <percorso...> [opzioni]
<percorso> jar / war / directory. Per le directory cerca sia gli artefatti di build (per la versione) sia i sorgenti .java (per le condizioni di attivazione)
--src <percorso> directory di sorgenti aggiuntiva
--no-src non scansionare i sorgenti (giudizio solo per versione, stessa granularità di Dependabot)
--all elenca anche le voci non corrisposte
-v, --version numero di versione
-h, --help aiuto
Codici di uscita: 0 = versione non esposta · 2 = versione esposta ma nessuna condizione di attivazione trovata nel sorgente (o sorgente non scansionato) · 3 = anche le condizioni di attivazione sono soddisfatte. Utilizzabile direttamente in CI.
Formati riconosciuti: jar normale, fat jar Spring Boot (BOOT-INF/lib/), WAR tradizionale (WEB-INF/lib/), jackson incorporato via shade nel jar ospite (le coordinate di dipendenza non sono visibili, ma META-INF/maven è ancora presente).
# Progetto Maven
mvn package && java -jar jackson-check.jar target src
# Solo un jar già pronto
java -jar jackson-check.jar app.jar
# Progetto Gradle
java -jar jackson-check.jar build/libs src/main/java
Richiede Java 17+. Zero dipendenze a runtime —— in particolare non dipende da jackson stesso.
tools/gen_rules.py genera CveTable.java da due fonti primarie:
/repos/FasterXML/jackson-databind/security-advisories —— l'insieme completo delle voci pubblicate dai manutentori + il testo originale delle descrizioni/advisories?ecosystem=maven&affects=<coordinata> —— l'indice di coordinate usato realmente da Dependabot (una query per ciascuno dei due groupId)Gli 11 advisory si espandono in 37 regole «advisory × coordinata × intervallo di versione», con 13 asserzioni: se una qualsiasi non è soddisfatta, l'esecuzione si interrompe e il file non viene scritto —— per evitare che «un parsing fallito generi una tabella vuota e i test risultino comunque tutti verdi»:
python tools/gen_rules.py # richiede una gh CLI con login effettuato
56 test unitari + 7 scenari end-to-end con artefatti reali (jar reali: 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 di manutenzione | Più frequente negli advisory | Versione davvero adeguata |
|---|
| 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 |
| Condizione di attivazione | Voci collegate |
|---|
@JsonView | CVE-2026-54517 / 54518 / 59889 / GHSA-mhm7 |
@JsonTypeInfo / activateDefaultTyping / PolymorphicTypeValidator | CVE-2026-54512 / 54513 |
@JsonIgnoreProperties + ACCEPT_CASE_INSENSITIVE_PROPERTIES | CVE-2026-54515 |
@JsonIgnore + rinomina con @JsonProperty | CVE-2026-54516 |
Java Record + PropertyNamingStrategy + @JsonIgnore | CVE-2026-59888 |
Campo InetSocketAddress | CVE-2026-54514 |
readTree() + JsonNode.toString() | CVE-2026-50193 |
| Asserzione | Cosa verifica |
|---|
| ASSERT2 | ⭐ Confronto dei punti ciechi tra le due fonti: la differenza deve essere 0 o spiegata voce per voce |
| ASSERT6 | Devono essere coperti entrambi i groupId |
| ASSERT7 | Ogni versione corretta viene sondata con richieste HEAD una per una per la disponibilità su Maven Central |
| ASSERT8 | Fantasma bidirezionale: recupera maven-metadata.xml per dimostrare che l'intera linea di versione maggiore non esiste su quella coordinata |
| ASSERT9 | Intersezione ramo per ramo, e deve essere davvero superiore alla versione corretta minima dello stesso ramo |
| ASSERT11 | La stringa di ancoraggio di ogni condizione di attivazione deve comparire parola per parola nel testo originale della descrizione ufficiale |
| ASSERT12 | Ogni voce deve avere un punteggio CVSS (unione delle due fonti) |
| ID | Livello | Tema |
|---|
| CVE-2026-54512 | high 8.1 | Bypass del parametro di tipo generico di PolymorphicTypeValidator |
| CVE-2026-54513 | high 8.1 | Bypass dell'allowlist dei sottotipi array tramite allowIfSubTypeIsArray() |
| CVE-2026-50193 | medium 7.5 | Stack overflow di JsonNode.toString() annidato in profondità |
| CVE-2026-54514 | medium 5.3 | La deserializzazione di InetSocketAddress innesca DNS (SSRF) |
| CVE-2026-54515 | medium 5.3 | La ricostruzione senza distinzione maiuscole/minuscole sovrascrive @JsonIgnoreProperties |
| CVE-2026-54516 | medium 5.3 | Il setter @JsonIgnore rinominato può essere comunque scritto tramite il campo privato |
| CVE-2026-54517 | medium 5.3 | @JsonView non ha effetto sulle proprietà creator senza setter |
| CVE-2026-54518 | medium 6.5 | @JsonView non ha effetto sui parametri creator unwrapped |
| CVE-2026-59888 | medium 6.5 | @JsonIgnore sulle proprietà Record aggirato dalla strategia di naming |
| CVE-2026-59889 | medium 6.5 | @JsonView non ha effetto sulle proprietà contenitore @JsonUnwrapped |
| GHSA-mhm7-754m-9p8w | medium 6.5 | Senza numero CVE · gap di patch @JsonView + As.EXTERNAL_PROPERTY |