Skip to content

Commit fd8dec2

Browse files
committed
Merge branch '2.8'
2 parents a0863bb + 60d459c commit fd8dec2

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

release-notes/VERSION

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ Project: jackson-databind
8080
#1585: Invoke ServiceLoader.load() inside of a privileged block when loading
8181
modules using `ObjectMapper.findModules()`
8282
(contributed by Ivo S)
83+
#1599: Jackson Deserializer security vulnerability
84+
(reported by ayound@github)
8385

8486
2.8.8 (05-Apr-2017)
8587

src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,35 @@ public class BeanDeserializerFactory
3636
*/
3737
private final static Class<?>[] INIT_CAUSE_PARAMS = new Class<?>[] { Throwable.class };
3838

39+
/**
40+
* Set of well-known "nasty classes", deserialization of which is considered dangerous
41+
* and should (and is) prevented by default.
42+
*
43+
* @since 2.8.9
44+
*/
45+
protected final static Set<String> DEFAULT_NO_DESER_CLASS_NAMES;
46+
static {
47+
Set<String> s = new HashSet<>();
48+
// Courtesy of [https://github.com/kantega/notsoserial]:
49+
// (and wrt [databind#1599]
50+
s.add("org.apache.commons.collections.functors.InvokerTransformer");
51+
s.add("org.apache.commons.collections.functors.InstantiateTransformer");
52+
s.add("org.apache.commons.collections4.functors.InvokerTransformer");
53+
s.add("org.apache.commons.collections4.functors.InstantiateTransformer");
54+
s.add("org.codehaus.groovy.runtime.ConvertedClosure");
55+
s.add("org.codehaus.groovy.runtime.MethodClosure");
56+
s.add("org.springframework.beans.factory.ObjectFactory");
57+
s.add("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
58+
DEFAULT_NO_DESER_CLASS_NAMES = Collections.unmodifiableSet(s);
59+
}
60+
61+
/**
62+
* Set of class names of types that are never to be deserialized.
63+
*
64+
* @since 2.8.9
65+
*/
66+
protected Set<String> _cfgIllegalClassNames = DEFAULT_NO_DESER_CLASS_NAMES;
67+
3968
/*
4069
/**********************************************************
4170
/* Life-cycle
@@ -130,6 +159,8 @@ public JsonDeserializer<Object> createBeanDeserializer(DeserializationContext ct
130159
if (!isPotentialBeanType(type.getRawClass())) {
131160
return null;
132161
}
162+
// For checks like [databind#1599]
163+
checkIllegalTypes(ctxt, type, beanDesc);
133164
// Use generic bean introspection to build deserializer
134165
return buildBeanDeserializer(ctxt, type, beanDesc);
135166
}
@@ -901,4 +932,21 @@ protected boolean isIgnorableType(DeserializationConfig config, BeanPropertyDefi
901932
ignoredTypes.put(type, status);
902933
return status.booleanValue();
903934
}
935+
936+
/**
937+
* @since 2.8.9
938+
*/
939+
protected void checkIllegalTypes(DeserializationContext ctxt, JavaType type,
940+
BeanDescription beanDesc)
941+
throws JsonMappingException
942+
{
943+
// There are certain nasty classes that could cause problems, mostly
944+
// via default typing -- catch them here.
945+
String full = type.getRawClass().getName();
946+
947+
if (_cfgIllegalClassNames.contains(full)) {
948+
ctxt.reportBadTypeDefinition(beanDesc,
949+
"Illegal type (%s) to deserialize: prevented for security reasons", full);
950+
}
951+
}
904952
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.fasterxml.jackson.databind.interop;
2+
3+
import com.fasterxml.jackson.databind.*;
4+
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
5+
6+
/**
7+
* Test case(s) to guard against handling of types that are illegal to handle
8+
* due to security constraints.
9+
*/
10+
public class IllegalTypesCheckTest extends BaseMapTest
11+
{
12+
static class Bean1599 {
13+
public int id;
14+
public Object obj;
15+
}
16+
17+
public void testIssue1599() throws Exception
18+
{
19+
final String NASTY_CLASS = "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl";
20+
final String JSON = aposToQuotes(
21+
"{'id': 124,\n"
22+
+" 'obj':[ '"+NASTY_CLASS+"',\n"
23+
+" {\n"
24+
+" 'transletBytecodes' : [ 'AAIAZQ==' ],\n"
25+
+" 'transletName' : 'a.b',\n"
26+
+" 'outputProperties' : { }\n"
27+
+" }\n"
28+
+" ]\n"
29+
+"}"
30+
);
31+
ObjectMapper mapper = new ObjectMapper();
32+
mapper.enableDefaultTyping();
33+
try {
34+
mapper.readValue(JSON, Bean1599.class);
35+
fail("Should not pass");
36+
} catch (InvalidDefinitionException e) {
37+
verifyException(e, "Illegal type");
38+
verifyException(e, "to deserialize");
39+
verifyException(e, "prevented for security reasons");
40+
BeanDescription desc = e.getBeanDescription();
41+
assertNotNull(desc);
42+
assertEquals(NASTY_CLASS, desc.getBeanClass().getName());
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)