Permalink
Browse files

Fix #1599 for 2.8.9

Merge branch '2.7' into 2.8
  • Loading branch information...
cowtowncoder committed Apr 13, 2017
2 parents b64c773 + 6ce32ff commit 60d459cedcf079c6106ae7da2ac562bc32dcabe1
@@ -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)
@@ -38,7 +38,36 @@
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
@@ -137,6 +166,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);
}
@@ -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);
}
}
}
@@ -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

This comment has been minimized.

JoyChou93 replied Apr 17, 2017

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

@cowtowncoder

This comment has been minimized.

Member

cowtowncoder replied Apr 17, 2017

@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

This comment has been minimized.

niemand-sec replied Aug 31, 2017

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

This comment has been minimized.

Member

cowtowncoder replied Aug 31, 2017

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.