Lede
CVE-2019-16335 is one entry in the long, notorious series of FasterXML jackson-databind "gadget chain" vulnerabilities disclosed throughout 2019. It affects jackson-databind versions before 2.9.10 and describes a polymorphic (unsafe) deserialization weakness that becomes exploitable specifically when the jackson-dataformat-cbor module is present on an application's classpath alongside a vulnerable jackson-databind version. Left unmitigated, this class of flaw allows an attacker who can control JSON or CBOR input passed to Jackson's ObjectMapper — in an application that has enabled polymorphic ("default") typing — to trigger instantiation of attacker-chosen classes during deserialization, potentially leading to remote code execution, denial of service, or server-side request forgery, depending on which "gadget" class ends up on the classpath and how it behaves when instantiated.
If you've followed Jackson's security history, this pattern will look familiar: jackson-databind maintains a deny-list (SubTypeValidator) of known-dangerous classes that must never be deserialized when default typing is enabled, and roughly two dozen CVEs from 2019 — including CVE-2019-12086, CVE-2019-12384, CVE-2019-14379, CVE-2019-14540, CVE-2019-16942, and CVE-2019-16335 — each represent a newly discovered gadget class that the deny-list failed to block. CVE-2019-16335's distinguishing feature is that the exploitable path is reachable through the CBOR data-format module rather than requiring an unrelated third-party library (like commons-dbcp or EhCache) on the classpath, which meant applications using Jackson's binary CBOR support could be exposed even without other "risky" dependencies present.
Affected Versions and Components
- Component:
com.fasterxml.jackson.core:jackson-databind, in combination withcom.fasterxml.jackson.dataformat:jackson-dataformat-cbor - Affected versions: jackson-databind 2.x branches prior to 2.9.10
- Fixed version: jackson-databind 2.9.10 (and the 2.9.10.x maintenance line), which extended
SubTypeValidator's deny-list to cover the additional gadget class(es) associated with this report - Precondition for exploitability: the application must have polymorphic type handling enabled — via
ObjectMapper.enableDefaultTyping(), an@JsonTypeInfoannotation configured to accept externally controlled type identifiers, or an equivalent mechanism that lets untrusted input dictate which Java class gets instantiated during deserialization. Applications that deserialize into concrete, statically declared types are not exposed by this specific issue.
As with its sibling CVEs, this is not a flaw that requires a Jackson vulnerability scanner to spot the smoking gun of "vulnerable version present." The real risk factor is architectural: any service using default typing on attacker-reachable input is a candidate, and the specific list of blocked gadget classes has grown so many times across 2017-2020 that relying on the deny-list as your primary defense is itself the underlying design flaw the Jackson maintainers have repeatedly acknowledged.
CVSS, EPSS, and KEV Context
NVD's automated CVSS scoring assigned most of the 2019 jackson-databind gadget-class CVEs — CVE-2019-16335 included — into the Critical band under CVSS v3.x, reflecting a network-exploitable vector with no privileges or user interaction required. It's worth noting, and worth being transparent about, that security researchers have long criticized NVD's scoring approach for this entire CVE family: the same boilerplate description ("might allow attackers to have a variety of impacts by leveraging failure to block use of one of the JDK classes...") was reused across dozens of distinct CVE entries, and automated scoring tools frequently defaulted to worst-case confidentiality/integrity/availability impact regardless of the actual gadget's real-world exploitability. In practice, the true severity of any individual entry in this series — including CVE-2019-16335 — depends heavily on whether the target gadget class is reachable, present on the classpath, and capable of causing meaningful impact when instantiated (some gadgets only enable denial of service via resource exhaustion; others enable genuine remote code execution).
CVE-2019-16335 does not appear on CISA's Known Exploited Vulnerabilities (KEV) catalog as of this writing, meaning there is no confirmed record of active, in-the-wild exploitation tracked by CISA specifically for this identifier. EPSS-style exploitation-probability estimates for this CVE sit consistent with the broader 2019 jackson-databind gadget family: exploitation in the wild has historically clustered around a smaller subset of the highest-value gadgets (particularly those tied to commonly bundled JNDI-capable classes), while more narrowly-scoped entries like this one see comparatively little targeted scanning or weaponized tooling, precisely because triggering it requires the victim application to have made a specific, discouraged configuration choice (enabling default typing) rather than being reachable purely by virtue of having the library present.
That said, "less commonly exploited" is not "safe to ignore." Default typing misconfigurations are common enough in legacy Java codebases — often introduced years earlier to solve a serialization convenience problem and never revisited — that any organization running jackson-databind versions from the 2.9.x line predating 2.9.10 should treat this as a real, actionable finding rather than background noise.
Timeline
- Prior to 2019: jackson-databind ships with an internal deny-list (
SubTypeValidator) intended to block known-dangerous classes from being instantiated via polymorphic deserialization, a defense mechanism the project had already been patching reactively since at least 2017 (the original "jackson-databind gadget chain" disclosures). - 2019 (ongoing through the year): Security researchers and the Jackson maintainers work through a steady stream of newly identified gadget classes across libraries commonly found on Java classpaths — EhCache, commons-dbcp, Groovy, Spring, JDOM, xalan, and more — each earning its own CVE identifier as the deny-list is extended.
- September 2019: jackson-databind 2.9.10 is released, consolidating fixes for CVE-2019-16335 alongside numerous other gadget-class CVEs from the same wave, extending
SubTypeValidatorcoverage accordingly. - 2019: CVE-2019-16335 is published in the NVD, documenting the jackson-dataformat-cbor-related gadget gap in versions prior to 2.9.10.
- 2020 and later: Jackson's 2.10 release introduces
PolymorphicTypeValidator, a structural shift away from a purely deny-list-based defense toward allow-list-based type validation — a direct response to the unsustainable pattern of one-off CVEs for each newly discovered gadget class.
Remediation Steps
- Upgrade jackson-databind to 2.9.10 or later (or the current supported 2.x/2.1x line for your project). Confirm the fix version is actually resolved in your dependency tree — transitive dependencies frequently pin an older jackson-databind version even when your direct declaration looks current.
- Audit for default/polymorphic typing usage. Search your codebase for
enableDefaultTyping(),activateDefaultTyping(), and@JsonTypeInfoconfigurations that accept type identifiers from untrusted input. If default typing isn't a genuine business requirement, disable it. - Migrate to allow-list validation. If polymorphic typing is required, upgrade to a Jackson version supporting
PolymorphicTypeValidator(2.10+) and explicitly enumerate the classes permitted for deserialization rather than relying on the deny-list alone. - Inventory your classpath for gadget-capable libraries. Since exploitability of this entire CVE family depends on which libraries happen to be present, use software composition analysis (SCA) to identify whether jackson-dataformat-cbor and other historically implicated modules (commons-dbcp, EhCache, Groovy, etc.) are reachable from deserialization paths, even transitively.
- Re-run your SCA/SBOM scan post-upgrade to confirm no other component in the dependency graph still pulls in a pre-2.9.10 jackson-databind release via a separate path.
- Treat this as a pattern, not a one-off. Given how many CVEs share this root cause, teams should assume similar gadget-class disclosures will continue and build detection/response processes around the pattern (default typing + reachable gadget) rather than chasing individual CVE IDs one at a time.
How Safeguard Helps
CVE-2019-16335 is a textbook example of why point-in-time CVE patching isn't enough for supply chain security: the vulnerable pattern (default typing plus an ever-growing gadget deny-list) outlived any single patch, spawning dozens of related CVEs over several years. Safeguard is built to catch exactly this kind of systemic risk, not just individual CVE IDs.
Safeguard's software composition analysis continuously inventories every transitive dependency in your build — including deeply nested jars like jackson-dataformat-cbor that often escape manual review — and flags jackson-databind versions predating known-safe releases like 2.9.10, mapping them directly to the specific CVEs they resolve. Because Safeguard tracks the full dependency graph rather than just direct declarations, it surfaces cases where a vulnerable jackson-databind version is pulled in transitively through an unrelated framework, a scenario that manual dependency review routinely misses.
Beyond version matching, Safeguard's risk scoring incorporates real exploitability context — EPSS trends, KEV status, and reachability signals — so your team can prioritize the jackson-databind gadget CVEs (and the many CVEs like it across the Java ecosystem) that represent genuine, actionable risk over noise generated by blanket CVSS scoring. Combined with policy gates in CI/CD, Safeguard can block builds that reintroduce unpatched jackson-databind versions before they ever reach production, closing the loop on exactly the kind of long-tail, reappearing vulnerability class that CVE-2019-16335 represents.