|
|
f79a0c |
From 2235894210c75f624a3d0cd60bfb0434a20a18bf Mon Sep 17 00:00:00 2001
|
|
|
f79a0c |
From: Tatu Saloranta <tatu.saloranta@iki.fi>
|
|
|
f79a0c |
Date: Mon, 18 Dec 2017 21:41:51 -0800
|
|
|
f79a0c |
Subject: [PATCH] Fix #1855
|
|
|
f79a0c |
|
|
|
f79a0c |
---
|
|
|
f79a0c |
.../databind/deser/BeanDeserializerFactory.java | 54 ++----------
|
|
|
f79a0c |
.../databind/jsontype/impl/SubTypeValidator.java | 98 ++++++++++++++++++++++
|
|
|
f79a0c |
2 files changed, 103 insertions(+), 49 deletions(-)
|
|
|
f79a0c |
create mode 100644 src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SubTypeValidator.java
|
|
|
f79a0c |
|
|
|
f79a0c |
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java
|
|
|
f79a0c |
index 217ffd9c6..b462c0c74 100644
|
|
|
f79a0c |
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java
|
|
|
f79a0c |
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java
|
|
|
f79a0c |
@@ -12,6 +12,7 @@
|
|
|
f79a0c |
import com.fasterxml.jackson.databind.deser.std.ThrowableDeserializer;
|
|
|
f79a0c |
import com.fasterxml.jackson.databind.introspect.*;
|
|
|
f79a0c |
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
|
|
|
f79a0c |
+import com.fasterxml.jackson.databind.jsontype.impl.SubTypeValidator;
|
|
|
f79a0c |
import com.fasterxml.jackson.databind.util.ArrayBuilders;
|
|
|
f79a0c |
import com.fasterxml.jackson.databind.util.ClassUtil;
|
|
|
f79a0c |
import com.fasterxml.jackson.databind.util.SimpleBeanPropertyDefinition;
|
|
|
f79a0c |
@@ -40,44 +41,6 @@
|
|
|
f79a0c |
|
|
|
f79a0c |
private final static Class[] NO_VIEWS = new Class[0];
|
|
|
f79a0c |
|
|
|
f79a0c |
- /**
|
|
|
f79a0c |
- * Set of well-known "nasty classes", deserialization of which is considered dangerous
|
|
|
f79a0c |
- * and should (and is) prevented by default.
|
|
|
f79a0c |
- */
|
|
|
f79a0c |
- protected final static Set<String> DEFAULT_NO_DESER_CLASS_NAMES;
|
|
|
f79a0c |
- static {
|
|
|
f79a0c |
- Set<String> s = new HashSet<String>();
|
|
|
f79a0c |
- // Courtesy of [https://github.com/kantega/notsoserial]:
|
|
|
f79a0c |
- // (and wrt [databind#1599])
|
|
|
f79a0c |
- s.add("org.apache.commons.collections.functors.InvokerTransformer");
|
|
|
f79a0c |
- s.add("org.apache.commons.collections.functors.InstantiateTransformer");
|
|
|
f79a0c |
- s.add("org.apache.commons.collections4.functors.InvokerTransformer");
|
|
|
f79a0c |
- s.add("org.apache.commons.collections4.functors.InstantiateTransformer");
|
|
|
f79a0c |
- // 05-Aug-2017, tatu: as per [https://github.com/mbechler/marshalsec/blob/master/marshalsec.pdf]
|
|
|
f79a0c |
- // this is NOT likely to be exploitable via Jackson. But keep excluded just in case.
|
|
|
f79a0c |
- s.add("org.codehaus.groovy.runtime.ConvertedClosure");
|
|
|
f79a0c |
- s.add("org.codehaus.groovy.runtime.MethodClosure");
|
|
|
f79a0c |
- s.add("org.springframework.beans.factory.ObjectFactory");
|
|
|
f79a0c |
- s.add("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
|
|
|
f79a0c |
- s.add("org.apache.xalan.xsltc.trax.TemplatesImpl");
|
|
|
f79a0c |
- // [databind#1680]: may or may not be problem, take no chance
|
|
|
f79a0c |
- s.add("com.sun.rowset.JdbcRowSetImpl");
|
|
|
f79a0c |
- // [databind#1737]; JDK provided
|
|
|
f79a0c |
- s.add("java.util.logging.FileHandler");
|
|
|
f79a0c |
- s.add("java.rmi.server.UnicastRemoteObject");
|
|
|
f79a0c |
- // [databind#1737]; 3rd party
|
|
|
f79a0c |
- s.add("org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor");
|
|
|
f79a0c |
- s.add("org.springframework.beans.factory.config.PropertyPathFactoryBean");
|
|
|
f79a0c |
- s.add("com.mchange.v2.c3p0.JndiRefForwardingDataSource");
|
|
|
f79a0c |
- s.add("com.mchange.v2.c3p0.WrapperConnectionPoolDataSource");
|
|
|
f79a0c |
-
|
|
|
f79a0c |
- DEFAULT_NO_DESER_CLASS_NAMES = Collections.unmodifiableSet(s);
|
|
|
f79a0c |
- }
|
|
|
f79a0c |
-
|
|
|
f79a0c |
- /**
|
|
|
f79a0c |
- * Set of class names of types that are never to be deserialized.
|
|
|
f79a0c |
- */
|
|
|
f79a0c |
- protected Set<String> _cfgIllegalClassNames = DEFAULT_NO_DESER_CLASS_NAMES;
|
|
|
f79a0c |
|
|
|
f79a0c |
/*
|
|
|
f79a0c |
/**********************************************************
|
|
|
f79a0c |
@@ -179,7 +142,7 @@ public DeserializerFactory withConfig(DeserializerFactoryConfig config)
|
|
|
f79a0c |
return null;
|
|
|
f79a0c |
}
|
|
|
f79a0c |
// For checks like [databind#1599]
|
|
|
f79a0c |
- checkIllegalTypes(ctxt, type, beanDesc);
|
|
|
f79a0c |
+ _validateSubType(ctxt, type, beanDesc);
|
|
|
f79a0c |
// Use generic bean introspection to build deserializer
|
|
|
f79a0c |
return buildBeanDeserializer(ctxt, type, beanDesc);
|
|
|
f79a0c |
}
|
|
|
f79a0c |
@@ -878,17 +841,10 @@
|
|
|
f79a0c |
return (status == null) ? false : status.booleanValue();
|
|
|
f79a0c |
}
|
|
|
f79a0c |
|
|
|
f79a0c |
- protected void checkIllegalTypes(DeserializationContext ctxt, JavaType type,
|
|
|
f79a0c |
+ protected void _validateSubType(DeserializationContext ctxt, JavaType type,
|
|
|
f79a0c |
BeanDescription beanDesc)
|
|
|
f79a0c |
throws JsonMappingException
|
|
|
f79a0c |
{
|
|
|
f79a0c |
- // There are certain nasty classes that could cause problems, mostly
|
|
|
f79a0c |
- // via default typing -- catch them here.
|
|
|
f79a0c |
- String full = type.getRawClass().getName();
|
|
|
f79a0c |
-
|
|
|
f79a0c |
- if (_cfgIllegalClassNames.contains(full)) {
|
|
|
f79a0c |
- throw JsonMappingException.from(ctxt.getParser(),
|
|
|
f79a0c |
- String.format("Illegal type (%s) to deserialize: prevented for security reasons", full));
|
|
|
f79a0c |
- }
|
|
|
f79a0c |
+ SubTypeValidator.instance().validateSubType(ctxt, type);
|
|
|
f79a0c |
}
|
|
|
f79a0c |
}
|
|
|
f79a0c |
diff --git a/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SubTypeValidator.java b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SubTypeValidator.java
|
|
|
f79a0c |
new file mode 100644
|
|
|
f79a0c |
index 000000000..8a273cc15
|
|
|
f79a0c |
--- /dev/null
|
|
|
f79a0c |
+++ b/src/main/java/com/fasterxml/jackson/databind/jsontype/impl/SubTypeValidator.java
|
|
|
f79a0c |
@@ -0,0 +1,98 @@
|
|
|
f79a0c |
+package com.fasterxml.jackson.databind.jsontype.impl;
|
|
|
f79a0c |
+
|
|
|
f79a0c |
+import java.util.Collections;
|
|
|
f79a0c |
+import java.util.HashSet;
|
|
|
f79a0c |
+import java.util.Set;
|
|
|
f79a0c |
+
|
|
|
f79a0c |
+import com.fasterxml.jackson.databind.DeserializationContext;
|
|
|
f79a0c |
+import com.fasterxml.jackson.databind.JavaType;
|
|
|
f79a0c |
+import com.fasterxml.jackson.databind.JsonMappingException;
|
|
|
f79a0c |
+
|
|
|
f79a0c |
+/**
|
|
|
f79a0c |
+ * Helper class used to encapsulate rules that determine subtypes that
|
|
|
f79a0c |
+ * are invalid to use, even with default typing, mostly due to security
|
|
|
f79a0c |
+ * concerns.
|
|
|
f79a0c |
+ * Used by BeanDeserializerFacotry
|
|
|
f79a0c |
+ *
|
|
|
f79a0c |
+ * @since 2.8.11
|
|
|
f79a0c |
+ */
|
|
|
f79a0c |
+public class SubTypeValidator
|
|
|
f79a0c |
+{
|
|
|
f79a0c |
+ protected final static String PREFIX_STRING = "org.springframework.";
|
|
|
f79a0c |
+ /**
|
|
|
f79a0c |
+ * Set of well-known "nasty classes", deserialization of which is considered dangerous
|
|
|
f79a0c |
+ * and should (and is) prevented by default.
|
|
|
f79a0c |
+ */
|
|
|
f79a0c |
+ protected final static Set<String> DEFAULT_NO_DESER_CLASS_NAMES;
|
|
|
f79a0c |
+ static {
|
|
|
f79a0c |
+ Set<String> s = new HashSet<String>();
|
|
|
f79a0c |
+ // Courtesy of [https://github.com/kantega/notsoserial]:
|
|
|
f79a0c |
+ // (and wrt [databind#1599])
|
|
|
f79a0c |
+ s.add("org.apache.commons.collections.functors.InvokerTransformer");
|
|
|
f79a0c |
+ s.add("org.apache.commons.collections.functors.InstantiateTransformer");
|
|
|
f79a0c |
+ s.add("org.apache.commons.collections4.functors.InvokerTransformer");
|
|
|
f79a0c |
+ s.add("org.apache.commons.collections4.functors.InstantiateTransformer");
|
|
|
f79a0c |
+ s.add("org.codehaus.groovy.runtime.ConvertedClosure");
|
|
|
f79a0c |
+ s.add("org.codehaus.groovy.runtime.MethodClosure");
|
|
|
f79a0c |
+ s.add("org.springframework.beans.factory.ObjectFactory");
|
|
|
f79a0c |
+ s.add("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
|
|
|
f79a0c |
+ s.add("org.apache.xalan.xsltc.trax.TemplatesImpl");
|
|
|
f79a0c |
+ // [databind#1680]: may or may not be problem, take no chance
|
|
|
f79a0c |
+ s.add("com.sun.rowset.JdbcRowSetImpl");
|
|
|
f79a0c |
+ // [databind#1737]; JDK provided
|
|
|
f79a0c |
+ s.add("java.util.logging.FileHandler");
|
|
|
f79a0c |
+ s.add("java.rmi.server.UnicastRemoteObject");
|
|
|
f79a0c |
+ // [databind#1737]; 3rd party
|
|
|
f79a0c |
+//s.add("org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor"); // deprecated by [databind#1855]
|
|
|
f79a0c |
+ s.add("org.springframework.beans.factory.config.PropertyPathFactoryBean");
|
|
|
f79a0c |
+ s.add("com.mchange.v2.c3p0.JndiRefForwardingDataSource");
|
|
|
f79a0c |
+ s.add("com.mchange.v2.c3p0.WrapperConnectionPoolDataSource");
|
|
|
f79a0c |
+ // [databind#1855]: more 3rd party
|
|
|
f79a0c |
+ s.add("org.apache.tomcat.dbcp.dbcp2.BasicDataSource");
|
|
|
f79a0c |
+ s.add("com.sun.org.apache.bcel.internal.util.ClassLoader");
|
|
|
f79a0c |
+ DEFAULT_NO_DESER_CLASS_NAMES = Collections.unmodifiableSet(s);
|
|
|
f79a0c |
+ }
|
|
|
f79a0c |
+
|
|
|
f79a0c |
+ /**
|
|
|
f79a0c |
+ * Set of class names of types that are never to be deserialized.
|
|
|
f79a0c |
+ */
|
|
|
f79a0c |
+ protected Set<String> _cfgIllegalClassNames = DEFAULT_NO_DESER_CLASS_NAMES;
|
|
|
f79a0c |
+
|
|
|
f79a0c |
+ private final static SubTypeValidator instance = new SubTypeValidator();
|
|
|
f79a0c |
+
|
|
|
f79a0c |
+ protected SubTypeValidator() { }
|
|
|
f79a0c |
+
|
|
|
f79a0c |
+ public static SubTypeValidator instance() { return instance; }
|
|
|
f79a0c |
+
|
|
|
f79a0c |
+ public void validateSubType(DeserializationContext ctxt, JavaType type) throws JsonMappingException
|
|
|
f79a0c |
+ {
|
|
|
f79a0c |
+ // There are certain nasty classes that could cause problems, mostly
|
|
|
f79a0c |
+ // via default typing -- catch them here.
|
|
|
f79a0c |
+ final Class raw = type.getRawClass();
|
|
|
f79a0c |
+ String full = raw.getName();
|
|
|
f79a0c |
+
|
|
|
f79a0c |
+ do {
|
|
|
f79a0c |
+ if (_cfgIllegalClassNames.contains(full)) {
|
|
|
f79a0c |
+ break;
|
|
|
f79a0c |
+ }
|
|
|
f79a0c |
+
|
|
|
f79a0c |
+ // 18-Dec-2017, tatu: As per [databind#1855], need bit more sophisticated handling
|
|
|
f79a0c |
+ // for some Spring framework types
|
|
|
f79a0c |
+ if (full.startsWith(PREFIX_STRING)) {
|
|
|
f79a0c |
+ for (Class cls = raw; cls != Object.class; cls = cls.getSuperclass()) {
|
|
|
f79a0c |
+ String name = cls.getSimpleName();
|
|
|
f79a0c |
+ // looking for "AbstractBeanFactoryPointcutAdvisor" but no point to allow any is there?
|
|
|
f79a0c |
+ if ("AbstractPointcutAdvisor".equals(name)
|
|
|
f79a0c |
+ // ditto for "FileSystemXmlApplicationContext": block all ApplicationContexts
|
|
|
f79a0c |
+ || "AbstractApplicationContext.equals".equals(name)) {
|
|
|
f79a0c |
+ break;
|
|
|
f79a0c |
+ }
|
|
|
f79a0c |
+ }
|
|
|
f79a0c |
+ }
|
|
|
f79a0c |
+ return;
|
|
|
f79a0c |
+ } while (false);
|
|
|
f79a0c |
+
|
|
|
f79a0c |
+ throw JsonMappingException.from(ctxt.getParser(),
|
|
|
f79a0c |
+ String.format("Illegal type (%s) to deserialize: prevented for security reasons", full));
|
|
|
f79a0c |
+ }
|
|
|
f79a0c |
+}
|