high · 8.1CVE-2026-54513Jun 26, 2026

CVE-2026-54513: jackson-databind BasicPolymorphicTypeValidator Array Subtype Allowlist Bypass

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

A flaw in jackson-databind's polymorphic type validator lets attackers slip a disallowed class past the allowlist by wrapping it in an array, defeating the security control that was supposed to block

Packagecom.fasterxml.jackson.core:jackson-databind
Ecosystemmaven
Affected>= 2.10.0, < 2.18.8
Fixed in2.18.8
CVE-2026-54513: jackson-databind BasicPolymorphicTypeValidator Array Subtype Allowlist Bypass

The problem

BasicPolymorphicTypeValidator.Builder.allowIfSubTypeIsArray() approves any array type by checking only clazz.isArray(), never inspecting the array's component (element) type against the configured allowlist.

A PTV built with allowIfSubTypeIsArray() plus an explicit type allowlist still permits GadgetClass[] even when GadgetClass itself is not on the list. Jackson then instantiates the component type directly per element with no further PTV check, bypassing the allowlist entirely and re-opening the gadget-instantiation risk PTV exists to prevent.

Proof of concept

java
// Vulnerable mapper configuration (PTV trusts any array type):
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
    .allowIfSubTypeIsArray()
    .allowIfSubType(SafeType.class)  // only SafeType intended
    .build();
ObjectMapper mapper = JsonMapper.builder()
    .activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.NON_FINAL)
    .build();

// Malicious JSON: wraps a disallowed gadget class as the array component type.
// The PTV sees com.example.GadgetClass[] -> isArray() == true -> ALLOWED.
// Jackson then instantiates com.example.GadgetClass per element, no PTV re-check.
[
  "com.example.GadgetClass[]",
  [{"cmd": "calc.exe"}]
]

The root cause (CWE-184) is that allowIfSubTypeIsArray() returned ALLOWED on the raw array class without ever calling validateSubType recursively on the component type. An attacker who controls the type-ID string supplies GadgetClass[] instead of GadgetClass, clearing the one check that would have blocked it.

The fix in commits 24529da (main) and 01d1692 (2.18 backport) adds recursive component-type validation inside validateSubType: when the resolved subtype is an array, it now extracts the component class and runs the full PTV check chain against it before returning ALLOWED.

On patched releases, the malicious payload throws InvalidTypeIdException before any instantiation occurs (per PR #5983 and #5984 diff at line 493 of BasicPolymorphicTypeValidator.java).

The fix

Upgrade to jackson-databind 2.18.8, 2.21.4, or 3.1.4 (or any later release on those lines). If an immediate upgrade is not possible, stop using allowIfSubTypeIsArray() and replace it with explicit allowIfSubType() entries for each permitted array component class.

A custom PolymorphicTypeValidator that validates component types is an alternative short-term workaround.

Reported by Omkhar Arasaratnam (@omkhar).

References: [1][2][3][4][5][6]