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/07/28 03:08:21 UTC

[dubbo-hessian-lite] branch master updated: Add Default Deny List

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 8d49db4  Add Default Deny List
     new bb6ee3b  Merge pull request #41 from AlbumenJ/add_default_list
8d49db4 is described below

commit 8d49db4128aea8fc6e469a25e19b4d50af91e0bd
Author: Albumen Kevin <jh...@gmail.com>
AuthorDate: Wed Jul 28 10:51:54 2021 +0800

    Add Default Deny List
---
 .../com/caucho/hessian/io/ClassFactory.java        |  91 +++++++++++++--
 src/main/resources/DENY_CLASS                      | 124 +++++++++++++++++++++
 .../com/caucho/hessian/io/DenyListTest.java        |  51 +++++++++
 3 files changed, 259 insertions(+), 7 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 98aec15..d5976ba 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
@@ -48,8 +48,17 @@
 
 package com.alibaba.com.caucho.hessian.io;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.regex.Pattern;
@@ -61,16 +70,18 @@ public class ClassFactory
 {
     protected static final Logger log
             = Logger.getLogger(ClassFactory.class.getName());
-    private static ArrayList<Allow> _staticAllowList;
+    private static final ArrayList<Allow> _staticAllowList;
+    private static final Map<String, Object> _allowClassSet = new ConcurrentHashMap<>();
 
     private ClassLoader _loader;
     private boolean _isWhitelist;
 
-    private ArrayList<Allow> _allowList;
+    private LinkedList<Allow> _allowList;
 
     ClassFactory(ClassLoader loader)
     {
         _loader = loader;
+        initAllow();
     }
 
     public Class<?> load(String className)
@@ -87,12 +98,16 @@ public class ClassFactory
 
     private boolean isAllow(String className)
     {
-        ArrayList<Allow> allowList = _allowList;
+        LinkedList<Allow> allowList = _allowList;
 
         if (allowList == null) {
             return true;
         }
 
+        if (_allowClassSet.containsKey(className)) {
+            return true;
+        }
+
         int size = allowList.size();
         for (int i = 0; i < size; i++) {
             Allow allow = allowList.get(i);
@@ -100,6 +115,9 @@ public class ClassFactory
             Boolean isAllow = allow.allow(className);
 
             if (isAllow != null) {
+                if (isAllow) {
+                    _allowClassSet.put(className, className);
+                }
                 return isAllow;
             }
         }
@@ -108,11 +126,13 @@ public class ClassFactory
             return false;
         }
 
+        _allowClassSet.put(className, className);
         return true;
     }
 
     public void setWhitelist(boolean isWhitelist)
     {
+        _allowClassSet.clear();
         _isWhitelist = isWhitelist;
 
         initAllow();
@@ -120,19 +140,21 @@ public class ClassFactory
 
     public void allow(String pattern)
     {
+        _allowClassSet.clear();
         initAllow();
 
         synchronized (this) {
-            _allowList.add(new Allow(toPattern(pattern), true));
+            _allowList.addFirst(new Allow(toPattern(pattern), true));
         }
     }
 
     public void deny(String pattern)
     {
+        _allowClassSet.clear();
         initAllow();
 
         synchronized (this) {
-            _allowList.add(new Allow(toPattern(pattern), false));
+            _allowList.addFirst(new Allow(toPattern(pattern), false));
         }
     }
 
@@ -148,7 +170,7 @@ public class ClassFactory
     {
         synchronized (this) {
             if (_allowList == null) {
-                _allowList = new ArrayList<Allow>();
+                _allowList = new LinkedList<Allow>();
                 _allowList.addAll(_staticAllowList);
             }
         }
@@ -158,6 +180,9 @@ public class ClassFactory
         private Boolean _isAllow;
         private Pattern _pattern;
 
+        public Allow() {
+        }
+
         private Allow(String pattern, boolean isAllow)
         {
             _isAllow = isAllow;
@@ -175,9 +200,61 @@ public class ClassFactory
         }
     }
 
+    static class AllowPrefix extends Allow {
+        private Boolean _isAllow;
+        private String _prefix;
+
+        private AllowPrefix(String prefix, boolean isAllow)
+        {
+            super();
+            _isAllow = isAllow;
+            _prefix = prefix;
+        }
+
+        @Override
+        Boolean allow(String className)
+        {
+            if (className.startsWith(_prefix)) {
+                return _isAllow;
+            }
+            else {
+                return null;
+            }
+        }
+    }
+
     static {
         _staticAllowList = new ArrayList<Allow>();
 
-        _staticAllowList.add(new Allow("java\\..+", true));
+        ClassLoader classLoader = ClassFactory.class.getClassLoader();
+        try {
+            String[] denyClasses = readLines(classLoader.getResourceAsStream("DENY_CLASS"));
+            for (String denyClass : denyClasses) {
+                if (denyClass.startsWith("#")) {
+                    continue;
+                }
+                _staticAllowList.add(new AllowPrefix(denyClass, false));
+            }
+        } catch (IOException ignore) {
+
+        }
+    }
+
+    /**
+     * read lines.
+     *
+     * @param is input stream.
+     * @return lines.
+     * @throws IOException If an I/O error occurs
+     */
+    public static String[] readLines(InputStream is) throws IOException {
+        List<String> lines = new ArrayList<String>();
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                lines.add(line);
+            }
+            return lines.toArray(new String[0]);
+        }
     }
 }
\ No newline at end of file
diff --git a/src/main/resources/DENY_CLASS b/src/main/resources/DENY_CLASS
new file mode 100644
index 0000000..87eeb7b
--- /dev/null
+++ b/src/main/resources/DENY_CLASS
@@ -0,0 +1,124 @@
+#
+#
+#   Licensed to the Apache Software Foundation (ASF) under one or more
+#   contributor license agreements.  See the NOTICE file distributed with
+#   this work for additional information regarding copyright ownership.
+#   The ASF licenses this file to You under the Apache License, Version 2.0
+#   (the "License"); you may not use this file except in compliance with
+#   the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+#
+bsh.
+ch.qos.logback.core.db.
+clojure.
+com.alibaba.citrus.springext.support.parser.
+com.alibaba.citrus.springext.util.SpringExtUtil.
+com.alibaba.druid.pool.
+com.alibaba.hotcode.internal.org.apache.commons.collections.functors.
+com.alipay.custrelation.service.model.redress.
+com.alipay.oceanbase.obproxy.druid.pool.
+com.caucho.config.types.
+com.caucho.hessian.test.
+com.caucho.naming.
+com.ibm.jtc.jax.xml.bind.v2.runtime.unmarshaller.
+com.ibm.xltxe.rnm1.xtq.bcel.util.
+com.mchange.v2.c3p0.
+com.mysql.jdbc.util.
+com.rometools.rome.feed.
+com.sun.corba.se.impl.
+com.sun.corba.se.spi.orbutil.
+com.sun.jndi.rmi.
+com.sun.jndi.toolkit.
+com.sun.org.apache.bcel.internal.
+com.sun.org.apache.xalan.internal.
+com.sun.rowset.
+com.sun.xml.internal.bind.v2.
+com.taobao.vipserver.commons.collections.functors.
+groovy.lang.
+java.beans.
+java.lang.ProcessBuilder
+java.lang.Runtime
+java.rmi.server.
+java.security.
+java.util.ServiceLoader
+javassist.bytecode.annotation.
+javassist.tools.web.Viewer
+javassist.util.proxy.
+javax.imageio.
+javax.imageio.spi.
+javax.management.
+javax.media.jai.remote.
+javax.naming.
+javax.script.
+javax.sound.sampled.
+javax.xml.transform.
+net.bytebuddy.dynamic.loading.
+oracle.jdbc.connector.
+oracle.jdbc.pool.
+org.apache.aries.transaction.jms.
+org.apache.bcel.util.
+org.apache.carbondata.core.scan.expression.
+org.apache.commons.beanutils.
+org.apache.commons.codec.binary.
+org.apache.commons.collections.functors.
+org.apache.commons.collections4.functors.
+org.apache.commons.configuration.
+org.apache.commons.configuration2.
+org.apache.commons.dbcp.datasources.
+org.apache.commons.dbcp2.datasources.
+org.apache.commons.fileupload.disk.
+org.apache.ibatis.executor.loader.
+org.apache.ibatis.javassist.bytecode.
+org.apache.ibatis.javassist.tools.
+org.apache.ibatis.javassist.util.
+org.apache.ignite.cache.
+org.apache.log.output.db.
+org.apache.log4j.receivers.db.
+org.apache.myfaces.view.facelets.el.
+org.apache.openjpa.ee.
+org.apache.openjpa.ee.
+org.apache.shiro.
+org.apache.tomcat.dbcp.
+org.apache.velocity.runtime.
+org.apache.velocity.
+org.apache.wicket.util.
+org.apache.xalan.xsltc.trax.
+org.apache.xbean.naming.context.
+org.apache.xpath.
+org.apache.zookeeper.
+org.aspectj.apache.bcel.util.
+org.codehaus.groovy.runtime.
+org.datanucleus.store.rdbms.datasource.dbcp.datasources.
+org.eclipse.jetty.util.log.
+org.geotools.filter.
+org.h2.value.
+org.hibernate.tuple.component.
+org.hibernate.type.
+org.jboss.ejb3.
+org.jboss.proxy.ejb.
+org.jboss.resteasy.plugins.server.resourcefactory.
+org.jboss.weld.interceptor.builder.
+org.mockito.internal.creation.cglib.
+org.mortbay.log.
+org.quartz.
+org.springframework.aop.aspectj.
+org.springframework.beans.BeanWrapperImpl$BeanPropertyHandler
+org.springframework.beans.factory.
+org.springframework.expression.spel.
+org.springframework.jndi.
+org.springframework.orm.
+org.springframework.transaction.
+org.yaml.snakeyaml.tokens.
+pstore.shaded.org.apache.commons.collections.
+sun.rmi.server.
+sun.rmi.transport.
+weblogic.ejb20.internal.
+weblogic.jms.common.
\ No newline at end of file
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
new file mode 100644
index 0000000..d05a0c7
--- /dev/null
+++ b/src/test/java/com/alibaba/com/caucho/hessian/io/DenyListTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.com.caucho.hessian.io;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.lang.reflect.Array;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+public class DenyListTest {
+
+    @Test
+    public void testDeny() throws ClassNotFoundException {
+        ClassFactory classFactory = new ClassFactory(this.getClass().getClassLoader());
+        Assert.assertEquals(HashMap.class, classFactory.load("java.lang.Runtime"));
+        Assert.assertEquals(HashMap.class, classFactory.load("java.beans.A"));
+        Assert.assertEquals(HashMap.class, classFactory.load("java.beans.B"));
+        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"));
+    }
+
+    @Test
+    public void testAllow() throws ClassNotFoundException {
+        ClassFactory classFactory = new ClassFactory(this.getClass().getClassLoader());
+        Assert.assertEquals(Integer.class, classFactory.load(Integer.class.getName()));
+        Assert.assertEquals(Long.class, classFactory.load(Long.class.getName()));
+        Assert.assertEquals(TestClass.class, classFactory.load(TestClass.class.getName()));
+        Assert.assertEquals(DenyListTest.class, classFactory.load(DenyListTest.class.getName()));
+        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()));
+    }
+}