Description
Due to multiple CVEs for possible exploits via "default typing" (or, @JsonTypeInfo
with base type of java.lang.Object
) AND a small set of common "serialization gadgets", we have added blacklist of such gadgets. Blacklist is a moving target, with steady trickle of new types, and fundamentally can never be 100% complete.
Inclusion of black list is then problematic in a few ways:
- As protection it is unlikely to ever be complete for everybody, everywhere
- Since it's part of
jackson-databind
(for now at least), update requires new release, update by app/service developers - Although there are ways around (2) (by subclassing), those are cumbersome and not well known
As to (3), it is worth noting that:
- Subclassing
BeanDeserializerFactory
(used by databind itself for applying blacklist) - Custom
Module
(beforeDeserializerFactory
is invoked) - Implementing custom
com.fasterxml.jackson.databind.jsontype.impl.ClassNameIdResolver
, even before deserializer, when resolving polymorphic type id as a class
can all be used for protection; but are either not module (sub-classing of deserializer factory), or otherwise cumbersome (module, type id resolver).
But it should be possible to take another approach: define a new small handler API, to be invoked when:
- Resolving subtype to serialize / deserialize
- Attempting to construct serializer / deserializer
This would allow many things, like:
- Preventing deserialization and/or serialization of types deemed unsafe (or undesired?)
- Changing of type on deserialization (or, for purpose of locating serializer, also serialization?)
one use of which is security check.
Callback(s) could then:
- translate type as-is, for "that's fine"
- substitute type (subtype for deserialization; supertype for serialization)
- throw exception to indicate that type is illegal to serialize/deserialize
In theory it might even be possible to perhaps allow some special handling like "always deserialize as null"; but at this point this is speculation.
After defining such handler interface, it should be applied in two ways:
- For default typing, REQUIRE passing of such validator. While default implementation ("just block known serialiation gadgets") should be available, it SHOULD NOT be passed implicitly. Caller must pass it, to document their choice.
- For
@JsonTypeInfo
approach, a new property, with default choice, should suffice. Here defaulting should be ok since exploit only applies to case ofjava.lang.Object
(and perhapsjava.io.Serializable
,java.util.Comparable
?)- possibly require non-default choice for
java.lang.Object
et al?
- possibly require non-default choice for
and then polymorphic handler would need to be passed validator to use.
Net effect of this would be to allow finer-grained control of blocking certain types from polymorphic handling (esp. deserialization).