
jackson-databind 2026 年 11 条安全公告自查:扫源码注解降噪,告诉你真中几条;逐条求交集给出真正到位的版本(2.18.9/2.21.5/3.1.5,不是 advisory 上最常见的 2.21.4) CVE-2026-54515 / CVE-2026-54512
Self-check tool for the 11 jackson-databind security advisories of 2026. Zero-dependency single jar, no network required.
It answers two questions Dependabot can't answer:
@JsonView / polymorphic types / case-insensitive matching…), reducing "vulnerable version installed" down to "actually hit that feature".java -jar jackson-check.jar ./target ./src
Of these 11 advisories in 2026, 8 state the fixed version as 2.21.4 / 2.18.8 / 3.1.4. People who upgrade accordingly assume they're fully patched.
The actual answer after intersecting one by one:
The three that raise the bar are:
CVE-2026-54515 — case-insensitive deserialization bypasses per-property @JsonIgnoreProperties
CVE-2026-59889 — @JsonView is ineffective on @JsonUnwrapped container properties
🔴 GHSA-mhm7-754m-9p8w — no CVE ID, and the advisory text itself says:
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
It's a patch gap: fixed on the 3.x line, but the backport to the 2.18 / 2.21 lines was missed. Since there's no CVE ID, searching by CVE number won't find it.
You can see it with a single run:
# Project already upgraded to 2.21.4
java -jar jackson-check.jar ./lib ./src
# Dependabot would report: 3 items
# 🔥 Note: if you upgraded to the most common fixed version in the advisories, the following 3 still apply
| Coordinate | Actually published on Maven Central |
|---|---|
com.fasterxml.jackson.core:jackson-databind | 2.x only |
tools.jackson.core:jackson-databind | 3.x only |
But in the advisories' structured fields:
com.fasterxml.jackson.core carries 6 3.x ranges, with the fixed version 3.1.4 → HTTP 404 under that coordinatetools.jackson.core carries 1 2.x range, with the fixed version 2.21.4 → likewise HTTP 404Tools that blindly copy advisories will have you install something that doesn't exist. When generating the decision table, this tool makes a HEAD request for each one to actually verify availability; anything unobtainable is flagged in the report instead of being printed as an upgrade suggestion.
The two coordinates' artifactId and jar filenames are identical — only META-INF can tell them apart — so this tool judges by coordinate, not by filename.
The same 2.18.5, two codebases, completely different results:
Code using polymorphic types + @JsonView → Dependabot reports 7, actually affected: 6
Code that only does new ObjectMapper() → Dependabot reports 7, actually affected: 0
Both directions must be stated clearly; presenting only one side is misleading.
① "Trigger condition not found" does not mean safe. Three situations can turn it into false reassurance:
ObjectMapper.addMixIn) and similar mechanisms, with that keyword nowhere in the source;② "All trigger conditions met" doesn't confirm you're affected either. The flags are aggregated across the entire codebase, not by the same class or the same field. For example, one advisory requires @JsonView and @JsonUnwrapped to be on the same property, while we can only see that both words appear somewhere in your code.
This tool only does text matching, not AST parsing. That's a deliberate trade-off: the critical path must be human-readable and self-verifiable — if an opaque AST-based decision is wrong, no one would notice.
Version determination (step 1) is hard; trigger-condition determination (step 2) is only for prioritization, not for absolving risk.
On Dependabot blind spots: there are none in this batch of 11. The official repo's advisory page lists 11; reverse lookups under the two coordinates total 11; the difference is 0 — a conclusion reached after checking two sources, not a default from checking only one (tools/gen_rules.py's ASSERT2 re-verifies it on every run). So for this batch, Dependabot's version alerts are accurate; this tool's value is in noise reduction and intersection, not in gap-filling.
java -jar jackson-check.jar <path...> [options]
<path> jar / war / directory. A directory is scanned for both build artifacts (version) and .java sources (trigger conditions)
--src <path> additional source directory
--no-src do not scan sources (version-only judgment, same granularity as Dependabot)
--all also list entries that were not hit
-v, --version version number
-h, --help help
Exit codes: 0 = version not affected · 2 = version affected but no trigger conditions found in source (or source not scanned) · 3 = trigger conditions also met. Can be used directly in CI.
Recognized forms: plain jar, Spring Boot fat jar (BOOT-INF/lib/), traditional WAR (WEB-INF/lib/), jackson shaded into a host jar (dependency coordinates invisible, but META-INF/maven still present).
# Maven project
mvn package && java -jar jackson-check.jar target src
# Only a built jar
java -jar jackson-check.jar app.jar
# Gradle project
java -jar jackson-check.jar build/libs src/main/java
Requires Java 17+. Zero runtime dependencies — in particular, it does not depend on jackson itself.
tools/gen_rules.py generates CveTable.java from two primary sources:
/repos/FasterXML/jackson-databind/security-advisories — the maintainers' complete set of published entries + original descriptions/advisories?ecosystem=maven&affects=<coordinate> — the coordinate index Dependabot actually uses (query each groupId once)The 11 advisories expand into 37 "advisory × coordinate × version range" rules, backed by 13 assertions; if any one fails, it aborts without writing a file — preventing "parse failure generates an empty shell table while tests still pass all green":
python tools/gen_rules.py # requires a logged-in gh CLI
56 unit tests + 7 end-to-end scenarios with real artifacts (real jars: 2.13.0 / 2.18.5 / 2.21.2 / 2.21.4 / 2.21.5 / 3.1.2 / 3.1.5).
Apache-2.0
| Maintenance branch | Most common in advisories | Truly sufficient version |
|---|
| 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 |
| Trigger condition | Related entries |
|---|
@JsonView | CVE-2026-54517 / 54518 / 59889 / GHSA-mhm7 |
@JsonTypeInfo / activateDefaultTyping / PolymorphicTypeValidator | CVE-2026-54512 / 54513 |
@JsonIgnoreProperties + ACCEPT_CASE_INSENSITIVE_PROPERTIES | CVE-2026-54515 |
@JsonIgnore + @JsonProperty renamed | CVE-2026-54516 |
Java Record + PropertyNamingStrategy + @JsonIgnore | CVE-2026-59888 |
InetSocketAddress field | CVE-2026-54514 |
readTree() + JsonNode.toString() | CVE-2026-50193 |
| Assertion | What it checks |
|---|
| ASSERT2 | ⭐ Two-source blind-spot comparison; difference must be 0 or explained entry by entry |
| ASSERT6 | Both groupIds must be covered |
| ASSERT7 | HEAD-request every fixed version to probe availability on Maven Central |
| ASSERT8 | Two-way ghost check: pull maven-metadata.xml to prove the entire major-version line doesn't exist under that coordinate |
| ASSERT9 | Intersect branch by branch, and it must actually be higher than the lowest fixed version in the same branch |
| ASSERT11 | Each trigger condition's anchor string must appear verbatim in the original official description |
| ASSERT12 | Every entry must have a CVSS score (union of the two sources) |
| ID | Severity | Topic |
|---|
| CVE-2026-54512 | high 8.1 | PolymorphicTypeValidator generic parameter bypass |
| CVE-2026-54513 | high 8.1 | allowIfSubTypeIsArray() array subtype allowlist bypass |
| CVE-2026-50193 | medium 7.5 | deeply nested JsonNode.toString() stack overflow |
| CVE-2026-54514 | medium 5.3 | InetSocketAddress deserialization triggers DNS (SSRF) |
| CVE-2026-54515 | medium 5.3 | case-insensitive rebuild overrides @JsonIgnoreProperties |
| CVE-2026-54516 | medium 5.3 | renamed @JsonIgnore setter still writable via private field |
| CVE-2026-54517 | medium 5.3 | @JsonView ineffective on setterless creator properties |
| CVE-2026-54518 | medium 6.5 | @JsonView ineffective on unwrapped creator parameters |
| CVE-2026-59888 | medium 6.5 | @JsonIgnore on Record properties bypassed by naming strategy |
| CVE-2026-59889 | medium 6.5 | @JsonView ineffective on @JsonUnwrapped container properties |
| GHSA-mhm7-754m-9p8w | medium 6.5 | no CVE ID · @JsonView + As.EXTERNAL_PROPERTY patch gap |