Safeguard
Vulnerability Analysis

Jackson-databind polymorphic deserialization RCE (CVE-2017-15095)

A critical jackson-databind deserialization vulnerability (CVE-2017-15095) lets unauthenticated attackers achieve RCE via HikariCP gadget classes.

Nayan Dey
Security Researcher
7 min read

A critical remote code execution flaw in jackson-databind, tracked as CVE-2017-15095, shows how one incomplete patch can keep a vulnerability class alive for years. The bug lets an unauthenticated attacker who can control JSON input processed by Jackson's polymorphic type handling achieve arbitrary code execution on the host JVM, by smuggling a reference to HikariCP's HikariConfig/HikariDataSource classes into the deserialization stream. Because jackson-databind sits underneath an enormous share of the Java ecosystem — Spring Boot REST controllers, API gateways, message brokers, and countless internal microservices — a flaw like this rarely stays theoretical. It is a textbook example of a "gadget chain" vulnerability: the danger isn't in jackson-databind's own code so much as in what other libraries happen to be sitting on the classpath alongside it.

What the vulnerability actually does

Jackson's databind module supports polymorphic deserialization, where a JSON payload can specify which concrete Java class to instantiate for a given field via type metadata (commonly enabled through @JsonTypeInfo, ObjectMapper.enableDefaultTyping(), or similar configuration). This is a legitimate and widely used feature — but when an application deserializes JSON from an untrusted source using a mapper configured this way, an attacker can name any class on the classpath, not just the ones the developer intended.

If that classpath contains a class with side-effecting setters — a "gadget" — Jackson will happily instantiate it and invoke those setters while populating fields from attacker-controlled JSON. CVE-2017-15095 specifically targets HikariCP's connection-pool configuration classes, com.zaxxer.hikari.HikariConfig and com.zaxxer.hikari.HikariDataSource. These classes expose setters (such as those wiring in a JNDI data source name) that, when driven by an attacker, can trigger a JNDI lookup against a server the attacker controls. A malicious JNDI response can return a reference that causes the victim JVM to load and execute attacker-supplied code — the same fundamental technique later made famous, at much larger scale, by Log4Shell.

This wasn't a novel discovery so much as a new entry in an already-long list. jackson-databind maintains an internal denylist of known-dangerous classes precisely because the "any class on the classpath" design is inherently risky, and that denylist has been extended dozens of times since 2017 as researchers keep finding new gadgets. CVE-2017-15095 is one of the earliest and most cited entries in that ongoing saga, and it set the pattern that would repeat for years: fix one gadget, researcher finds another, patch again.

Affected versions and components

  • jackson-databind versions before 2.8.10
  • jackson-databind 2.9.x before 2.9.2
  • Requires the vulnerable application to have HikariCP (com.zaxxer:HikariCP) on the classpath alongside jackson-databind
  • Requires the application to deserialize untrusted JSON using a Jackson ObjectMapper with polymorphic/default typing enabled (directly, or transitively through a framework default)
  • Fixed in jackson-databind 2.8.10 and 2.9.2, which added the HikariCP classes to the internal gadget denylist

It's worth stressing the "requires HikariCP on the classpath" condition, because it's the single most useful fact for triage. Many organizations run jackson-databind everywhere but only a subset of those services also pull in HikariCP as a connection-pool dependency (common in Spring Boot apps talking to relational databases). Reachability — is the vulnerable class combination actually present and actually exercised — is the difference between "theoretical CVE on a dependency tree" and "exploitable RCE."

Severity, exploitation likelihood, and KEV status

NVD scores CVE-2017-15095 at CVSS v3 base score 9.8 (Critical) — network-exploitable, no privileges required, no user interaction, full compromise of confidentiality, integrity, and availability. The legacy CVSS v2 score sits at 7.5. Those numbers reflect the worst case: an internet-facing endpoint deserializing attacker-controlled JSON with default typing enabled and HikariCP present.

From an exploitation-probability standpoint, CVE-2017-15095 belongs to a family of jackson-databind deserialization CVEs that score very high in FIRST.org's EPSS model, generally landing in the upper percentiles among all scored CVEs — unsurprising given how mechanical and well-tooled Jackson gadget-chain exploitation has become (public gadget collections and scanners have targeted this class of bug for years). CVE-2017-15095 itself is not currently listed in CISA's Known Exploited Vulnerabilities (KEV) catalog, but that should not be read as "low risk." Several sibling CVEs in the same jackson-databind polymorphic-deserialization lineage have been tied to real-world exploitation attempts against exposed Java services, and the underlying technique — JNDI-triggering gadgets reachable through unsafe deserialization — is one of the most consistently weaponized bug classes in the Java ecosystem over the past decade.

Timeline

  • 2015 — CVE-2015-8562 discloses the foundational jackson-databind polymorphic deserialization RCE issue and introduces the first gadget denylist, kicking off years of "whack-a-mole" patching.
  • 2017 (mid-year) — CVE-2017-7525 broadens awareness of the underlying default-typing gadget-chain problem and drives further denylist hardening in the 2.8.x and 2.9.x branches.
  • Early October 2017 — Researchers report that the existing denylist does not cover HikariCP's HikariConfig/HikariDataSource classes, demonstrating a working RCE bypass.
  • October 2017 — jackson-databind ships 2.8.10 and 2.9.2, adding the HikariCP classes to the denylist. CVE-2017-15095 is assigned and published in NVD shortly after.
  • 2017–present — The same pattern recurs repeatedly across the jackson-databind ecosystem (additional CVEs targeting different gadget classes such as those in Spring, Groovy, and various commons libraries), reinforcing that denylisting is a mitigation, not a permanent fix, for polymorphic deserialization risk.

Remediation steps

  1. Upgrade jackson-databind immediately. Move to at least 2.8.10 (if pinned to the 2.8.x line) or 2.9.2+ (2.9.x line). In practice, most teams should target a current, actively maintained jackson-databind release rather than the minimum patched version, since the denylist has been extended many times since 2017 and older "patched" versions are still missing later fixes.
  2. Inventory where default typing is actually enabled. Search your codebase for enableDefaultTyping(), activateDefaultTyping(), @JsonTypeInfo with Id.CLASS or Id.MINIMAL_CLASS, and any custom PolymorphicTypeValidator configuration. Default typing on an ObjectMapper that also processes untrusted input is the actual root cause; the denylist is a safety net, not a fix.
  3. Prefer safe polymorphic patterns. Where polymorphic deserialization is genuinely required, use an explicit allowlist of expected subtypes via PolymorphicTypeValidator (Jackson 2.10+) rather than relying on the library's built-in denylist to catch every dangerous class that might ever ship in a transitive dependency.
  4. Check for HikariCP (and other known gadgets) on affected classpaths. Even after upgrading jackson-databind, confirm whether HikariCP or other historically abused gadget libraries are present in services that also deserialize external JSON — this tells you which services were genuinely exploitable versus merely carrying the vulnerable library version.
  5. Constrain what deserializes untrusted input. Isolate ObjectMapper instances that handle external, attacker-influenced JSON from those used for internal, trusted serialization, and disable default typing on the former entirely if polymorphism isn't required there.
  6. Add egress controls for JNDI/LDAP/RMI lookups from application servers. Because this exploitation path depends on the victim JVM reaching an attacker-controlled JNDI endpoint, network egress restrictions meaningfully reduce blast radius even on systems that haven't yet been patched.
  7. Re-scan and re-generate your SBOM after remediation to confirm the fixed jackson-databind version is actually deployed everywhere it's declared, including in shaded/fat JARs and transitive pulls that dependency manifests alone can miss.

How Safeguard Helps

Safeguard is built for exactly this kind of triage problem: a widely-deployed library CVE where severity depends entirely on classpath context. Our reachability analysis pinpoints which of your services actually load jackson-databind's default-typing code paths and carry a co-resident gadget class like HikariCP, so security teams can separate "patch this week" from "patch this quarter" instead of treating every hit as equally urgent. Griffin AI correlates that reachability signal with your deployment topology to explain, in plain language, why a given service is or isn't exploitable, cutting through the noise that pure dependency-scanning generates for legacy CVEs like this one. Continuous SBOM generation and ingest give you a living inventory that catches jackson-databind wherever it's declared, shaded, or transitively pulled in — including the copies dependency manifests alone tend to miss. And when remediation is confirmed, Safeguard can open an auto-fix pull request that bumps jackson-databind to a current, fully-patched release, so the fix ships without a manual hunt through every affected repository.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.