1

Coverity shows the block of code as unsafe deserialization:

String str = OBJECT_MAPPER.writeValueAsString(body);    //Body is user controlled
Ferarri myclassobj = OBJECT_MAPPER.readValue(str, Ferarri.class);
(Coverity: The virtual call resolves to com.fasterxml.jackson.databind.ObjectMapper.readValue(java.lang.String, com.fasterxml.jackson.core.type.TypeReference).)

ObjectMapper Definition:

private static final ThreadLocal<ObjectMapper> OBJECT_MAPPER = ThreadLocal.withInitial(() -> JsonMapper.builder()
        .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
        .disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES)
        .enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)
        .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
        .enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS)
        .serializationInclusion(JsonInclude.Include.NON_NULL)
        .build());
  • The Ferrari.java contains the below line:

    JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "someClassType")

  • I have not enabled the enableDefaultTyping();

2 Answers 2

1

No, this is not a vulnerability. If default typing is disabled (either explicitly or by default), and if you only use JsonTypeInfo.Id.NAME, this is the safest possible option, because you only allow a specific set of classes to be deserialized. An attacker cannot inject an arbitrary class to get a deserialization gadget.

Code scanners are typically bad at correctly classifying deserialization findings, because they have a simplistic model and don't take the context into account. For example, they only check if the deserialization input is user-controlled, which is not sufficient to actually carry out an attack. This will produce lots of false positives.

1

For Jackson Vulnerability to be exploited all these 4 conditions must be true:

  1. Accept Json input controlled by Attacker

  2. Enable Polymorphic Type Handling:

    • om.enableDefaultTyping() and om.readValue(userInput, Bruh.class) where Bruh.java should have a property of Object. (java.io.Serializable, java.util.Comparable)
    • mapper.setDefaultTyping(null) and om.readValue(userInput, Bruh.class) where Bruh.java should have a property of Object. (java.io.Serializable, java.util.Comparable)
    • om.readValue(userInput, Bruh.class) where Bruh.class has a property of type of Object with @JsonTypeInfo(use = Id.CLASS) set on that property.
  3. Has at least one specific “gadget” class to exploit in the Java classpath and also that Gadget Class must work with Jackson.

  4. Use version of Jackson that does not (yet) block “gadget” class in question (set of published exploits grows over time so it is a race between exploits and patches)

Checkout this lab: https://github.com/sickuritywizard/jackson-deserialization-lab

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .