Skip to content

Commit

Permalink
Fix #1599 for 2.8.9
Browse files Browse the repository at this point in the history
Merge branch '2.7' into 2.8
  • Loading branch information
cowtowncoder committed Apr 13, 2017
2 parents b64c773 + 6ce32ff commit 60d459c
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 1 deletion.
2 changes: 2 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Project: jackson-databind
#1585: Invoke ServiceLoader.load() inside of a privileged block when loading
modules using `ObjectMapper.findModules()`
(contributed by Ivo S)
#1599: Jackson Deserializer security vulnerability
(reported by ayound@github)

2.8.8 (05-Apr-2017)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,36 @@ public class BeanDeserializerFactory
private final static Class<?>[] INIT_CAUSE_PARAMS = new Class<?>[] { Throwable.class };

private final static Class<?>[] NO_VIEWS = new Class<?>[0];


/**
* Set of well-known "nasty classes", deserialization of which is considered dangerous
* and should (and is) prevented by default.
*
* @since 2.8.9
*/
protected final static Set<String> DEFAULT_NO_DESER_CLASS_NAMES;
static {
Set<String> s = new HashSet<>();
// Courtesy of [https://github.com/kantega/notsoserial]:
// (and wrt [databind#1599]
s.add("org.apache.commons.collections.functors.InvokerTransformer");
s.add("org.apache.commons.collections.functors.InstantiateTransformer");
s.add("org.apache.commons.collections4.functors.InvokerTransformer");
s.add("org.apache.commons.collections4.functors.InstantiateTransformer");
s.add("org.codehaus.groovy.runtime.ConvertedClosure");
s.add("org.codehaus.groovy.runtime.MethodClosure");
s.add("org.springframework.beans.factory.ObjectFactory");
s.add("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
DEFAULT_NO_DESER_CLASS_NAMES = Collections.unmodifiableSet(s);
}

/**
* Set of class names of types that are never to be deserialized.
*
* @since 2.8.9
*/
protected Set<String> _cfgIllegalClassNames = DEFAULT_NO_DESER_CLASS_NAMES;

/*
/**********************************************************
/* Life-cycle
Expand Down Expand Up @@ -137,6 +166,8 @@ public JsonDeserializer<Object> createBeanDeserializer(DeserializationContext ct
if (!isPotentialBeanType(type.getRawClass())) {
return null;
}
// For checks like [databind#1599]
checkIllegalTypes(ctxt, type, beanDesc);
// Use generic bean introspection to build deserializer
return buildBeanDeserializer(ctxt, type, beanDesc);
}
Expand Down Expand Up @@ -855,4 +886,21 @@ protected boolean isIgnorableType(DeserializationConfig config, BeanDescription
ignoredTypes.put(type, status);
return status.booleanValue();
}

/**
* @since 2.8.9
*/
protected void checkIllegalTypes(DeserializationContext ctxt, JavaType type,
BeanDescription beanDesc)
throws JsonMappingException
{
// There are certain nasty classes that could cause problems, mostly
// via default typing -- catch them here.
String full = type.getRawClass().getName();

if (_cfgIllegalClassNames.contains(full)) {
ctxt.reportBadTypeDefinition(beanDesc,
"Illegal type (%s) to deserialize: prevented for security reasons", full);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.fasterxml.jackson.databind.interop;

import com.fasterxml.jackson.databind.*;

/**
* Test case(s) to guard against handling of types that are illegal to handle
* due to security constraints.
*/
public class IllegalTypesCheckTest extends BaseMapTest
{
static class Bean1599 {
public int id;
public Object obj;
}

public void testIssue1599() throws Exception
{
final String JSON = aposToQuotes(
"{'id': 124,\n"
+" 'obj':[ 'com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl',\n"
+" {\n"
+" 'transletBytecodes' : [ 'AAIAZQ==' ],\n"
+" 'transletName' : 'a.b',\n"
+" 'outputProperties' : { }\n"
+" }\n"
+" ]\n"
+"}"
);
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
try {
mapper.readValue(JSON, Bean1599.class);
fail("Should not pass");
} catch (JsonMappingException e) {
verifyException(e, "Illegal type");
verifyException(e, "to deserialize");
verifyException(e, "prevented for security reasons");
}
}
}

4 comments on commit 60d459c

@JoyChou93
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so, if i want to update to 2.8.9, can i use dependency ways?

@cowtowncoder
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JoyChou93 not sure I understand the question. 2.8.9 not released yet; may take a while since there are only 2 fixes so far. You can build a snapshot, or use one from Maven Central I think.

@niemand-sec
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello there,

I was testing this issue in one application and I found this test, but I would like to know what it tries to do before executing it on the application. Could you please give me more information?

@cowtowncoder
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test verifies that polymorphic deserialization can not be used to execute malicious code.
There is a (relatively) well-known potential hole in certain versions of Apache Xalan, included in some versions of JDK (Xalan itself on many, but newer versions have patched version which does NOT have the problem)), and added code will not allow this class (or couple of other potentially problematic ones) to be deserialized. Hope this helps. Check out comments on issue 1599 for a link to one good article on general problem (article on possible security problems with a number of Java libraries).

Please sign in to comment.