Permalink
Browse files

Merge branch '2.8'

  • Loading branch information...
cowtowncoder committed Apr 13, 2017
2 parents a0863bb + 60d459c commit fd8dec2c7fab8b4b4bd60502a0f1d63ec23c24da
@@ -80,6 +80,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)
@@ -36,6 +36,35 @@
*/
private final static Class<?>[] INIT_CAUSE_PARAMS = new Class<?>[] { Throwable.class };
/**
* 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
@@ -130,6 +159,8 @@ public DeserializerFactory withConfig(DeserializerFactoryConfig config)
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);
}
@@ -901,4 +932,21 @@ protected boolean isIgnorableType(DeserializationConfig config, BeanPropertyDefi
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);
}
}
}
@@ -0,0 +1,45 @@
package com.fasterxml.jackson.databind.interop;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
/**
* 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 NASTY_CLASS = "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";
final String JSON = aposToQuotes(
"{'id': 124,\n"
+" 'obj':[ '"+NASTY_CLASS+"',\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 (InvalidDefinitionException e) {
verifyException(e, "Illegal type");
verifyException(e, "to deserialize");
verifyException(e, "prevented for security reasons");
BeanDescription desc = e.getBeanDescription();
assertNotNull(desc);
assertEquals(NASTY_CLASS, desc.getBeanClass().getName());
}
}
}

0 comments on commit fd8dec2

Please sign in to comment.