You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2021/08/04 14:33:43 UTC

[dubbo-hessian-lite] branch master updated: Add super class check

This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-hessian-lite.git


The following commit(s) were added to refs/heads/master by this push:
     new 15e85b0  Add super class check
     new 5694224  Merge pull request #43 from AlbumenJ/0802_opt_check
15e85b0 is described below

commit 15e85b01d51dbbd1981d1f311cd7eff4add1c67e
Author: Albumen Kevin <jh...@gmail.com>
AuthorDate: Mon Aug 2 13:50:33 2021 +0800

    Add super class check
---
 .../com/caucho/hessian/io/ClassFactory.java        | 61 ++++++++++++++++++----
 .../com/caucho/hessian/io/DenyListTest.java        | 11 ++++
 .../alibaba/com/caucho/hessian/io/TestClass.java   |  4 ++
 .../io/{TestClass.java => TestInterface.java}      |  8 +--
 4 files changed, 70 insertions(+), 14 deletions(-)

diff --git a/src/main/java/com/alibaba/com/caucho/hessian/io/ClassFactory.java b/src/main/java/com/alibaba/com/caucho/hessian/io/ClassFactory.java
index d5976ba..d64b6fe 100644
--- a/src/main/java/com/alibaba/com/caucho/hessian/io/ClassFactory.java
+++ b/src/main/java/com/alibaba/com/caucho/hessian/io/ClassFactory.java
@@ -54,6 +54,7 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -71,6 +72,7 @@ public class ClassFactory
     protected static final Logger log
             = Logger.getLogger(ClassFactory.class.getName());
     private static final ArrayList<Allow> _staticAllowList;
+    private static final Map<String, Object> _allowSubClassSet = new ConcurrentHashMap<>();
     private static final Map<String, Object> _allowClassSet = new ConcurrentHashMap<>();
 
     private ClassLoader _loader;
@@ -88,10 +90,43 @@ public class ClassFactory
             throws ClassNotFoundException
     {
         if (isAllow(className)) {
-            return Class.forName(className, false, _loader);
+            Class<?> aClass = Class.forName(className, false, _loader);
+
+            if (_allowClassSet.containsKey(className)) {
+                return aClass;
+            }
+
+            if (aClass.getInterfaces().length > 0) {
+                for (Class<?> anInterface : aClass.getInterfaces()) {
+                    if(!isAllow(anInterface.getName())) {
+                        log.log(Level.SEVERE, className + "'s interfaces: " + anInterface.getName() + " in blacklist or not in whitelist, deserialization with type 'HashMap' instead.");
+                        return HashMap.class;
+                    }
+                }
+            }
+
+            List<Class<?>> allSuperClasses = new LinkedList<>();
+
+            Class<?> superClass = aClass.getSuperclass();
+            while (superClass != null) {
+                // add current super class
+                allSuperClasses.add(superClass);
+                superClass = superClass.getSuperclass();
+            }
+
+            for (Class<?> aSuperClass : allSuperClasses) {
+                if(!isAllow(aSuperClass.getName())) {
+                    log.log(Level.SEVERE, className + "'s superClass: " + aSuperClass.getName() + " in blacklist or not in whitelist, deserialization with type 'HashMap' instead.");
+                    return HashMap.class;
+                }
+
+            }
+
+            _allowClassSet.put(className, className);
+            return aClass;
         }
         else {
-            log.log(Level.SEVERE, className + " in blacklist or not in whitelist, deserialization  with type 'HashMap' instead.");
+            log.log(Level.SEVERE, className + " in blacklist or not in whitelist, deserialization with type 'HashMap' instead.");
             return HashMap.class;
         }
     }
@@ -104,19 +139,16 @@ public class ClassFactory
             return true;
         }
 
-        if (_allowClassSet.containsKey(className)) {
+        if (_allowSubClassSet.containsKey(className)) {
             return true;
         }
 
-        int size = allowList.size();
-        for (int i = 0; i < size; i++) {
-            Allow allow = allowList.get(i);
-
+        for (Allow allow : allowList) {
             Boolean isAllow = allow.allow(className);
 
             if (isAllow != null) {
                 if (isAllow) {
-                    _allowClassSet.put(className, className);
+                    _allowSubClassSet.put(className, className);
                 }
                 return isAllow;
             }
@@ -126,13 +158,14 @@ public class ClassFactory
             return false;
         }
 
-        _allowClassSet.put(className, className);
+        _allowSubClassSet.put(className, className);
         return true;
     }
 
     public void setWhitelist(boolean isWhitelist)
     {
         _allowClassSet.clear();
+        _allowSubClassSet.clear();
         _isWhitelist = isWhitelist;
 
         initAllow();
@@ -141,6 +174,7 @@ public class ClassFactory
     public void allow(String pattern)
     {
         _allowClassSet.clear();
+        _allowSubClassSet.clear();
         initAllow();
 
         synchronized (this) {
@@ -151,6 +185,7 @@ public class ClassFactory
     public void deny(String pattern)
     {
         _allowClassSet.clear();
+        _allowSubClassSet.clear();
         initAllow();
 
         synchronized (this) {
@@ -158,7 +193,7 @@ public class ClassFactory
         }
     }
 
-    private String toPattern(String pattern)
+    private static String toPattern(String pattern)
     {
         pattern = pattern.replace(".", "\\.");
         pattern = pattern.replace("*", ".*");
@@ -233,7 +268,11 @@ public class ClassFactory
                 if (denyClass.startsWith("#")) {
                     continue;
                 }
-                _staticAllowList.add(new AllowPrefix(denyClass, false));
+                if (denyClass.endsWith(".")) {
+                    _staticAllowList.add(new AllowPrefix(denyClass, false));
+                } else {
+                    _staticAllowList.add(new Allow(toPattern(denyClass), false));
+                }
             }
         } catch (IOException ignore) {
 
diff --git a/src/test/java/com/alibaba/com/caucho/hessian/io/DenyListTest.java b/src/test/java/com/alibaba/com/caucho/hessian/io/DenyListTest.java
index d05a0c7..3c8375d 100644
--- a/src/test/java/com/alibaba/com/caucho/hessian/io/DenyListTest.java
+++ b/src/test/java/com/alibaba/com/caucho/hessian/io/DenyListTest.java
@@ -18,6 +18,7 @@ package com.alibaba.com.caucho.hessian.io;
 
 import org.junit.Assert;
 import org.junit.Test;
+import sun.rmi.transport.StreamRemoteCall;
 
 import java.lang.reflect.Array;
 import java.util.HashMap;
@@ -35,6 +36,15 @@ public class DenyListTest {
         Assert.assertEquals(HashMap.class, classFactory.load("java.beans.C"));
         Assert.assertEquals(HashMap.class, classFactory.load("java.beans.D"));
         Assert.assertEquals(HashMap.class, classFactory.load("java.beans.E"));
+        Assert.assertEquals(HashMap.class, classFactory.load("sun.rmi.transport.StreamRemoteCall"));
+
+        classFactory.deny(TestClass.class.getName());
+        Assert.assertEquals(HashMap.class, classFactory.load(TestClass.class.getName()));
+        Assert.assertEquals(HashMap.class, classFactory.load(TestClass1.class.getName()));
+
+        classFactory.deny(TestInterface.class.getName());
+        Assert.assertEquals(HashMap.class, classFactory.load(TestInterface.class.getName()));
+        Assert.assertEquals(HashMap.class, classFactory.load(TestImpl.class.getName()));
     }
 
     @Test
@@ -47,5 +57,6 @@ public class DenyListTest {
         Assert.assertEquals(List.class, classFactory.load(List.class.getName()));
         Assert.assertEquals(Array.class, classFactory.load(Array.class.getName()));
         Assert.assertEquals(LinkedList.class, classFactory.load(LinkedList.class.getName()));
+        Assert.assertEquals(RuntimeException.class, classFactory.load(RuntimeException.class.getName()));
     }
 }
diff --git a/src/test/java/com/alibaba/com/caucho/hessian/io/TestClass.java b/src/test/java/com/alibaba/com/caucho/hessian/io/TestClass.java
index 43907b3..0420962 100644
--- a/src/test/java/com/alibaba/com/caucho/hessian/io/TestClass.java
+++ b/src/test/java/com/alibaba/com/caucho/hessian/io/TestClass.java
@@ -20,3 +20,7 @@ import java.io.Serializable;
 
 public class TestClass implements Serializable {
 }
+
+class TestClass1 extends TestClass {
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/alibaba/com/caucho/hessian/io/TestClass.java b/src/test/java/com/alibaba/com/caucho/hessian/io/TestInterface.java
similarity index 91%
copy from src/test/java/com/alibaba/com/caucho/hessian/io/TestClass.java
copy to src/test/java/com/alibaba/com/caucho/hessian/io/TestInterface.java
index 43907b3..72d6d3c 100644
--- a/src/test/java/com/alibaba/com/caucho/hessian/io/TestClass.java
+++ b/src/test/java/com/alibaba/com/caucho/hessian/io/TestInterface.java
@@ -16,7 +16,9 @@
  */
 package com.alibaba.com.caucho.hessian.io;
 
-import java.io.Serializable;
-
-public class TestClass implements Serializable {
+public interface TestInterface {
 }
+
+class TestImpl implements TestInterface {
+
+}
\ No newline at end of file