Skip to content

Commit 2235894

Browse files
committed
Fix #1855
1 parent f031f27 commit 2235894

File tree

2 files changed

+103
-49
lines changed

2 files changed

+103
-49
lines changed

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

+5-49
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.fasterxml.jackson.databind.deser.std.ThrowableDeserializer;
1313
import com.fasterxml.jackson.databind.introspect.*;
1414
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
15+
import com.fasterxml.jackson.databind.jsontype.impl.SubTypeValidator;
1516
import com.fasterxml.jackson.databind.util.ArrayBuilders;
1617
import com.fasterxml.jackson.databind.util.ClassUtil;
1718
import com.fasterxml.jackson.databind.util.SimpleBeanPropertyDefinition;
@@ -40,44 +41,6 @@ public class BeanDeserializerFactory
4041

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

43-
/**
44-
* Set of well-known "nasty classes", deserialization of which is considered dangerous
45-
* and should (and is) prevented by default.
46-
*/
47-
protected final static Set<String> DEFAULT_NO_DESER_CLASS_NAMES;
48-
static {
49-
Set<String> s = new HashSet<String>();
50-
// Courtesy of [https://github.com/kantega/notsoserial]:
51-
// (and wrt [databind#1599])
52-
s.add("org.apache.commons.collections.functors.InvokerTransformer");
53-
s.add("org.apache.commons.collections.functors.InstantiateTransformer");
54-
s.add("org.apache.commons.collections4.functors.InvokerTransformer");
55-
s.add("org.apache.commons.collections4.functors.InstantiateTransformer");
56-
s.add("org.codehaus.groovy.runtime.ConvertedClosure");
57-
s.add("org.codehaus.groovy.runtime.MethodClosure");
58-
s.add("org.springframework.beans.factory.ObjectFactory");
59-
s.add("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
60-
s.add("org.apache.xalan.xsltc.trax.TemplatesImpl");
61-
// [databind#1680]: may or may not be problem, take no chance
62-
s.add("com.sun.rowset.JdbcRowSetImpl");
63-
// [databind#1737]; JDK provided
64-
s.add("java.util.logging.FileHandler");
65-
s.add("java.rmi.server.UnicastRemoteObject");
66-
// [databind#1737]; 3rd party
67-
s.add("org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor");
68-
s.add("org.springframework.beans.factory.config.PropertyPathFactoryBean");
69-
s.add("com.mchange.v2.c3p0.JndiRefForwardingDataSource");
70-
s.add("com.mchange.v2.c3p0.WrapperConnectionPoolDataSource");
71-
// [databind#1855]: more 3rd party
72-
s.add("org.apache.tomcat.dbcp.dbcp2.BasicDataSource");
73-
s.add("com.sun.org.apache.bcel.internal.util.ClassLoader");
74-
DEFAULT_NO_DESER_CLASS_NAMES = Collections.unmodifiableSet(s);
75-
}
76-
77-
/**
78-
* Set of class names of types that are never to be deserialized.
79-
*/
80-
protected Set<String> _cfgIllegalClassNames = DEFAULT_NO_DESER_CLASS_NAMES;
8144

8245
/*
8346
/**********************************************************
@@ -179,7 +142,7 @@ public JsonDeserializer<Object> createBeanDeserializer(DeserializationContext ct
179142
return null;
180143
}
181144
// For checks like [databind#1599]
182-
checkIllegalTypes(ctxt, type, beanDesc);
145+
_validateSubType(ctxt, type, beanDesc);
183146
// Use generic bean introspection to build deserializer
184147
return buildBeanDeserializer(ctxt, type, beanDesc);
185148
}
@@ -877,19 +840,12 @@ protected boolean isIgnorableType(DeserializationConfig config, BeanDescription
877840
}
878841

879842
/**
880-
* @since 2.8.9
843+
* @since 2.8.11
881844
*/
882-
protected void checkIllegalTypes(DeserializationContext ctxt, JavaType type,
845+
protected void _validateSubType(DeserializationContext ctxt, JavaType type,
883846
BeanDescription beanDesc)
884847
throws JsonMappingException
885848
{
886-
// There are certain nasty classes that could cause problems, mostly
887-
// via default typing -- catch them here.
888-
String full = type.getRawClass().getName();
889-
890-
if (_cfgIllegalClassNames.contains(full)) {
891-
throw JsonMappingException.from(ctxt,
892-
String.format("Illegal type (%s) to deserialize: prevented for security reasons", full));
893-
}
849+
SubTypeValidator.instance().validateSubType(ctxt, type);
894850
}
895851
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.fasterxml.jackson.databind.jsontype.impl;
2+
3+
import java.util.Collections;
4+
import java.util.HashSet;
5+
import java.util.Set;
6+
7+
import com.fasterxml.jackson.databind.DeserializationContext;
8+
import com.fasterxml.jackson.databind.JavaType;
9+
import com.fasterxml.jackson.databind.JsonMappingException;
10+
11+
/**
12+
* Helper class used to encapsulate rules that determine subtypes that
13+
* are invalid to use, even with default typing, mostly due to security
14+
* concerns.
15+
* Used by <code>BeanDeserializerFacotry</code>
16+
*
17+
* @since 2.8.11
18+
*/
19+
public class SubTypeValidator
20+
{
21+
protected final static String PREFIX_STRING = "org.springframework.";
22+
/**
23+
* Set of well-known "nasty classes", deserialization of which is considered dangerous
24+
* and should (and is) prevented by default.
25+
*/
26+
protected final static Set<String> DEFAULT_NO_DESER_CLASS_NAMES;
27+
static {
28+
Set<String> s = new HashSet<String>();
29+
// Courtesy of [https://github.com/kantega/notsoserial]:
30+
// (and wrt [databind#1599])
31+
s.add("org.apache.commons.collections.functors.InvokerTransformer");
32+
s.add("org.apache.commons.collections.functors.InstantiateTransformer");
33+
s.add("org.apache.commons.collections4.functors.InvokerTransformer");
34+
s.add("org.apache.commons.collections4.functors.InstantiateTransformer");
35+
s.add("org.codehaus.groovy.runtime.ConvertedClosure");
36+
s.add("org.codehaus.groovy.runtime.MethodClosure");
37+
s.add("org.springframework.beans.factory.ObjectFactory");
38+
s.add("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
39+
s.add("org.apache.xalan.xsltc.trax.TemplatesImpl");
40+
// [databind#1680]: may or may not be problem, take no chance
41+
s.add("com.sun.rowset.JdbcRowSetImpl");
42+
// [databind#1737]; JDK provided
43+
s.add("java.util.logging.FileHandler");
44+
s.add("java.rmi.server.UnicastRemoteObject");
45+
// [databind#1737]; 3rd party
46+
//s.add("org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor"); // deprecated by [databind#1855]
47+
s.add("org.springframework.beans.factory.config.PropertyPathFactoryBean");
48+
s.add("com.mchange.v2.c3p0.JndiRefForwardingDataSource");
49+
s.add("com.mchange.v2.c3p0.WrapperConnectionPoolDataSource");
50+
// [databind#1855]: more 3rd party
51+
s.add("org.apache.tomcat.dbcp.dbcp2.BasicDataSource");
52+
s.add("com.sun.org.apache.bcel.internal.util.ClassLoader");
53+
DEFAULT_NO_DESER_CLASS_NAMES = Collections.unmodifiableSet(s);
54+
}
55+
56+
/**
57+
* Set of class names of types that are never to be deserialized.
58+
*/
59+
protected Set<String> _cfgIllegalClassNames = DEFAULT_NO_DESER_CLASS_NAMES;
60+
61+
private final static SubTypeValidator instance = new SubTypeValidator();
62+
63+
protected SubTypeValidator() { }
64+
65+
public static SubTypeValidator instance() { return instance; }
66+
67+
public void validateSubType(DeserializationContext ctxt, JavaType type) throws JsonMappingException
68+
{
69+
// There are certain nasty classes that could cause problems, mostly
70+
// via default typing -- catch them here.
71+
final Class<?> raw = type.getRawClass();
72+
String full = raw.getName();
73+
74+
do {
75+
if (_cfgIllegalClassNames.contains(full)) {
76+
break;
77+
}
78+
79+
// 18-Dec-2017, tatu: As per [databind#1855], need bit more sophisticated handling
80+
// for some Spring framework types
81+
if (full.startsWith(PREFIX_STRING)) {
82+
for (Class<?> cls = raw; cls != Object.class; cls = cls.getSuperclass()) {
83+
String name = cls.getSimpleName();
84+
// looking for "AbstractBeanFactoryPointcutAdvisor" but no point to allow any is there?
85+
if ("AbstractPointcutAdvisor".equals(name)
86+
// ditto for "FileSystemXmlApplicationContext": block all ApplicationContexts
87+
|| "AbstractApplicationContext.equals".equals(name)) {
88+
break;
89+
}
90+
}
91+
}
92+
return;
93+
} while (false);
94+
95+
throw JsonMappingException.from(ctxt,
96+
String.format("Illegal type (%s) to deserialize: prevented for security reasons", full));
97+
}
98+
}

0 commit comments

Comments
 (0)