question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add abstraction `PolymorphicTypeValidator`, for limiting subtypes allowed by default typing, `@JsonTypeInfo`

See original GitHub issue

(note: moved from https://github.com/FasterXML/jackson3-dev/issues/21)

So: there are many CVEs that exploit permissive nature of class-name-based polymorphic deserialization, and especially so-called “default typing”, in which polymorphic handling is applied without annotations and with base type of java.lang.Object. Since set of potentially dangerous class types to exploit (“gadget types”) is unbounded, relying on block-listing (which Jackson does) is not effective in long term. And although there are mechanisms one can use to limit accessibility they are cumbersome and not well documented (Spring framework has built upon this, however, kudos to their persistence and ingenuity 😃 ).

But providing for abstraction that could allow simple strategies such as allow-listing (i.e. enumerating allowed classes), or simple predicate, should not be difficult. Now that we are planning to do one more 2.x release, 2.10, with easier configurability (via ObjectMapper.Builder), we should consider adding an extension point, instead of waiting until 3.0 which was the original plan.


From original issue, some further thoughts:

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.

As to applicability: although we should not make definition of such handler mandatory for 2.x,


Some examples of usage can be found from unit tests src/test/java/com/fasterxml/jackson/databind/jsontype/vld/ValidatePolymBaseTypeTest.java, src/test/java/com/fasterxml/jackson/databind/jsontype/vld/ValidatePolymSubTypeTest.java and ``src/test/java/com/fasterxml/jackson/databind/jsontype/vld/BasicPTVTest.java`

but here is an example:

PolymorphicTypeValidator validator = ...; // build validator
ObjectMapper saferMapper = JsonMapper.builder()
   .activateDefaultTyping(validator) // note the new name of method
   .build();
String json = mapper.writeValueAsString(myDefaultTypeUsingValue);

where validator could be complete custom one, or, instance of BasicPolymorphicTypeValidator like so:

        final PolymorphicTypeValidator validator = BasicPolymorphicTypeValidator.builder()
                .allowIfBaseType(MyBaseType.class)
                .build();

which would then allow all subtypes of MyBaseType, which is something user has control over (and thereby typically has no unsafe subtypes – and definitely no widely shared ones)


EDIT 20-Aug-2019: New methods in ObjectMapper (and MapperBuilder) use name activateDefaultTyping() over old now-deprecated enableDefaultTyping() (and similarly for disable/deactivate). This to make it easier to code-search for old methods without needing argument checks.


EDIT 16-Oct-2019: Further validating this approach a good overview by Sonatype security research team: https://blog.sonatype.com/jackson-databind-the-end-of-the-blacklist

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:4
  • Comments:10 (7 by maintainers)

github_iconTop GitHub Comments

3reactions
cowtowncodercommented, May 21, 2019

@melloware yes, I feel your pain. This is why this is #1 priority for 2.10.

I am still hoping to get 2.10.0.pr1 out within couple of weeks – most likely by early-/mid-June 2019 now.

1reaction
cowtowncodercommented, Oct 3, 2019

Ok. So, the name of the handler used is PolymorphicTypeValidator, and there is one public convenience implementation, BasicPolymorphicTypeValidator with builder-style construction mechanism. Mechanism are allow “opt-in” (allow-match), with one exception of allowing blocking of specific base type (often java.lang.Object). For example:

  • BasicPolymorphicTypeValidator.builder().allowIfBaseType("com.fasterxml.").build()
    • would allow all values of polymorphic properties where declared base type is in com.fasterxml package
  • BasicPolymorphicTypeValidator.builder().allowIfSubType(MyType.class).build()
    • would allow all polymorphic values that are MyType or its sub-class

and so on.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Jackson 2.10: Safe Default Typing - cowtowncoder - Medium
where “subtype” rules must be used as base type ( Object ) is too general to allow determination. PolymorphicTypeValidator with “@JsonTypeInfo”.
Read more >
MapperBuilder (jackson-databind 2.11.0 API) - FasterXML
Method for assigning PolymorphicTypeValidator to use for validating subtypes when using Class name - based polymorphic deserialization using annotations ( ...
Read more >
ObjectMapper (jackson-databind 2.13.2 API) - Javadoc.io
Enumeration used with activateDefaultTyping(PolymorphicTypeValidator) to specify what kind of types (classes) default typing should be used for.
Read more >
Class ObjectMapper - Adobe Developer
Enumeration used with activateDefaultTyping(PolymorphicTypeValidator) to specify what kind of types (classes) default typing should be used for.
Read more >
How to configure Jackson to deserialize named types with ...
@JsonTypeInfo(use = Id.NAME) @JsonSubTypes(value = @Type(value = Balloon.class)) public abstract static class Toy { } @JsonTypeName("Balloon") public static ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found