Blame SOURCES/CVE-2017-17485-1.patch

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
+}