Fedora Account System
Red Hat Associate
Red Hat Customer
PolymorphicTypeValidator bypass via generic type arguments and array element types in jackson-databind allows arbitrary class instantiation (incomplete fix for CVE-2026-54512) [CVE-2026-110879] A public GitHub Security Advisory (GHSA-m8xf-2cr7-77ph) describes the following issue: ### Summary Jackson checks the outer class in a class-name type ID but accepts attacker-selected classes inside its generic arguments even when they violate the declared type or would be rejected as direct type IDs. This bypasses the generic-argument validation added for [CVE-2026-54512](https://github.com/FasterXML/jackson-databind/security/advisories/GHSA-j3rv-43j4-c7qm). The affected paths include annotation-based class-name polymorphism with a default Jackson 3.x `JsonMapper`, configured default typing in Jackson 2.x and 3.x, and integrations that expose that default typing. With class-name default typing and an outer-base rule that permits `Map`, a property declared as `Map<String,String>` accepts `HashMap<FileSystemXmlApplicationContext,String>`. Map-key discovery passes the attacker-controlled JSON property name to the selected class's one-string constructor. With Spring on the classpath and attacker-controlled XML that the application can load, the constructor loads that XML and invokes `ProcessBuilder.start()` under the application account. Direct selection of the same Spring class is rejected before the XML resource is opened. ### Details `DatabindContext._resolveAndValidateGeneric()` checks the outer class against the declared base type, then passes each argument from the class-name type ID to `_validateTypeParameter()`. That method validates the argument against the outer base type rather than enforcing its corresponding declared generic binding. It also calls validators with arguments that have not passed the subtype check those validators expect. Under the default `DefaultBaseTypeLimitingValidator`, this accepts an unrelated class inside a generic subtype even when the same class is rejected as a direct type ID. When an `allowIfBaseType(...)` rule approves the outer type, Jackson substitutes `LaissezFaireSubTypeValidator`, so the configured validator no longer restricts the embedded arguments. The element type of a plain array type ID such as `[Lpkg.Gadget;` is likewise not validated once the array's base type is approved, for example under `allowIfBaseType(Serializable.class)`. The relevant code is in [`DatabindContext`](https://github.com/FasterXML/jackson-databind/blob/1da96ddfc6342b2b6fe2842977d51de66e255364/src/main/java/tools/jackson/databind/DatabindContext.java#L255-L321), [`DefaultBaseTypeLimitingValidator`](https://github.com/FasterXML/jackson-databind/blob/1da96ddfc6342b2b6fe2842977d51de66e255364/src/main/java/tools/jackson/databind/jsontype/DefaultBaseTypeLimitingValidator.java#L59-L66), and [`StdTypeResolverBuilder`](https://github.com/FasterXML/jackson-databind/blob/1da96ddfc6342b2b6fe2842977d51de66e255364/src/main/java/tools/jackson/databind/jsontype/impl/StdTypeResolverBuilder.java#L401-L403). The default-validator case needs no application-authored validator. With `@JsonTypeInfo(use = Id.CLASS) interface Msg`, `class Env<T> implements Msg` containing a public `T payload`, and a default Jackson 3.x `JsonMapper`, a direct `Gadget` type ID for `Msg` is rejected as "Not a subtype". A type ID naming `Env<Gadget>` is accepted and deserializes `Gadget` into `payload`, including attacker-supplied bean properties. A nested `Env<ArrayList<Timer>>` type ID creates `Timer` objects that start live non-daemon threads. The same generic-argument bypass reproduces with `Id.MINIMAL_CLASS` on annotated `Iterable<String>` and `Map<String,List<String>>` properties, and with `allowIfBaseType(Msg.class)`. Other affected paths are Jackson 2.x or 3.x default typing with an outer-base rule such as `allowIfBaseType(Map.class)`, and Spring Security's legacy Jackson 2 module whose resolver checks only the raw allowlisted `HashMap`. A related default-validator control uses a declared `Box<?>`: Jackson rejects a selected class directly below `Object` but accepts it inside `Box<SelectedClass>`. Spring Data Redis 4.0.7's `RedisSerializer.json()` and the legacy `GenericJackson2JsonRedisSerializer()` expose the vulnerable default-typing path through public convenience APIs without an application-authored mapper or validator. The incompatible map-key binding reaches `FileSystemXmlApplicationContext`'s constructor even though the direct type ID is rejected. Stock-JDK demonstrations also create or truncate a file through `FileOutputStream(String)` and issue a URL request with response retention through the exact-denylisted `JEditorPane(String)` class. Executed affected releases include 2.10.0, 2.19.2, 2.22.3, 3.0.0, 3.1.5, and 3.2.3, plus 3.x revision `0505ef4a6ad19ca1ae19328a56dafcca73816ed6`. The advertised CVE-2026-54512 fixed releases 2.18.8, 2.21.4, and 3.1.4 also accept the remaining path. ### PoC For the default Jackson 3.x `JsonMapper` case above, bind JSON to a property of type `Msg` and compare these type IDs: - `{"msg":{"@class":"pkg.Gadget","cmd":"x"}}` is rejected with "Not a subtype". - `{"msg":{"@class":"pkg.Env<pkg.Gadget>","payload":{"cmd":"x"}}}` is accepted; the `Gadget` constructor and its attacker-controlled setter run. - `{"msg":{"@class":"pkg.Env<java.util.ArrayList<java.util.Timer>>","payload":[{},{},{}]}}` is accepted; three `Timer` values start three non-daemon threads in the reproduced example. These outcomes, plus the `Id.MINIMAL_CLASS` and `allowIfBaseType(Msg.class)` variants, were reproduced on the unmodified 3.x revision above. A plain `Env` type ID and a hand-written `Env<String>` type ID also deserialize on that revision and serve as compatibility controls. The supplied [standalone reproducer](https://github.com/user-attachments/files/32810364/jackson-databind-jd05-reproducer.tar.gz) runs against unmodified released artifacts. Its default entry point demonstrates `JEditorPane` URL access and `FileOutputStream` truncation. Separate entry points exercise a memory-backed Spring XML context, Spring Data Redis, and Spring Security's legacy allowlist. Each Spring entry point verifies that direct selection is rejected without o [truncated] Affected: - maven:com.fasterxml.jackson.core:jackson-databind affected >= 2.10.0, <= 2.18.11; fixed unknown - maven:tools.jackson.core:jackson-databind affected >= 3.0.0, <= 3.1.7; fixed unknown - maven:com.fasterxml.jackson.core:jackson-databind affected >= 2.19.0, <= 2.21.7; fixed unknown - maven:com.fasterxml.jackson.core:jackson-databind affected >= 2.22.0, <= 2.22.3; fixed unknown - maven:tools.jackson.core:jackson-databind affected >= 3.2.0, <= 3.2.3; fixed unknown Fixed versions: see advisory Advisory: https://github.com/FasterXML/jackson-databind/security/advisories/GHSA-m8xf-2cr7-77ph
https://github.com/FasterXML/jackson-databind/security/advisories/GHSA-m8xf-2cr7-77ph already mentions fixed versions