diff --git a/src/main/java/com/caucho/hessian/io/Hessian2Input.java b/src/main/java/com/caucho/hessian/io/Hessian2Input.java index 0ce8e64..dba2917 100644 --- a/src/main/java/com/caucho/hessian/io/Hessian2Input.java +++ b/src/main/java/com/caucho/hessian/io/Hessian2Input.java @@ -2200,12 +2200,6 @@ public Object readObject(Class cl) if (cl == null || cl == Object.class) return readObject(); - // add by zhiyuan @2018-7-10 if in blacklist will throw exception - ClassNameResolver resolver = findSerializerFactory().getClassNameResolver(); - if (resolver != null) { - resolver.resolve(cl.getCanonicalName()); - } - int tag = _offset < _length ? (_buffer[_offset++] & 0xff) : read(); switch (tag) { @@ -2214,9 +2208,6 @@ public Object readObject(Class cl) case 'M': { String type = readType(); - if (resolver != null) { - type = resolver.resolve(type); - } // hessian/3bb3 if ("".equals(type)) { @@ -2652,11 +2643,6 @@ public Object readObject() case 'M': { String type = readType(); - // add by zhiyuan @2018-7-10 - ClassNameResolver resolver = findSerializerFactory().getClassNameResolver(); - if (resolver != null) { - type = resolver.resolve(type); - } return findSerializerFactory().readMap(this, type); } @@ -2720,12 +2706,6 @@ private void readObjectDefinition(Class cl) { String type = readLenString(); - // add by zhanggeng @2017-7-23 - ClassNameResolver resolver = findSerializerFactory().getClassNameResolver(); - if (resolver != null) { - type = resolver.resolve(type); - } - int len = readInt(); String[] fieldNames = new String[len]; @@ -2745,12 +2725,6 @@ private Object readObjectInstance(Class cl, ObjectDefinition def) { String type = def.getType(); - // add by zhanggeng @2017-7-23 - ClassNameResolver resolver = findSerializerFactory().getClassNameResolver(); - if (resolver != null) { - type = resolver.resolve(type); - } - String[] fieldNames = def.getFieldNames(); if (cl != null) { diff --git a/src/main/java/com/caucho/hessian/io/Hessian2Output.java b/src/main/java/com/caucho/hessian/io/Hessian2Output.java index fdf9ba8..c032697 100644 --- a/src/main/java/com/caucho/hessian/io/Hessian2Output.java +++ b/src/main/java/com/caucho/hessian/io/Hessian2Output.java @@ -458,16 +458,7 @@ public void writeObject(Object object) return; } - Serializer serializer; - - // add by zhanggeng @2017-7-23 - Class clazz = object.getClass(); - ClassNameResolver resolver = findSerializerFactory().getClassNameResolver(); - if (resolver != null) { - resolver.resolve(clazz.getName()); - } - - serializer = findSerializerFactory().getSerializer(clazz); + Serializer serializer = findSerializerFactory().getSerializer(object.getClass()); serializer.writeObject(object, this); } diff --git a/src/main/java/com/caucho/hessian/io/HessianInput.java b/src/main/java/com/caucho/hessian/io/HessianInput.java index b1c5bfc..5481b80 100644 --- a/src/main/java/com/caucho/hessian/io/HessianInput.java +++ b/src/main/java/com/caucho/hessian/io/HessianInput.java @@ -1052,12 +1052,6 @@ public Object readObject(Class cl) case 'M': { String type = readType(); - // add by zhiyuan @2018-7-10 - ClassNameResolver resolver = findSerializerFactory().getClassNameResolver(); - if (resolver != null) { - type = resolver.resolve(type); - } - // hessian/3386 if ("".equals(type)) { Deserializer reader; @@ -1191,12 +1185,6 @@ public Object readObject() case 'M': { String type = readType(); - // add by zhiyuan @2018-7-10 - ClassNameResolver resolver = findSerializerFactory().getClassNameResolver(); - if (resolver != null) { - type = resolver.resolve(type); - } - return _serializerFactory.readMap(this, type); } diff --git a/src/main/java/com/caucho/hessian/io/SerializerFactory.java b/src/main/java/com/caucho/hessian/io/SerializerFactory.java index 400efcd..7648501 100644 --- a/src/main/java/com/caucho/hessian/io/SerializerFactory.java +++ b/src/main/java/com/caucho/hessian/io/SerializerFactory.java @@ -162,6 +162,14 @@ public Serializer getSerializer(Class cl) if (serializer != null) return serializer; + if (classNameResolver != null) { + try { + classNameResolver.resolve(cl.getName()); + } catch (Exception e) { + throw new HessianProtocolException(e); + } + } + for (int i = 0; serializer == null && _factories != null && i < _factories.size(); i++) { AbstractSerializerFactory factory; @@ -265,6 +273,14 @@ public Deserializer getDeserializer(Class cl) if (deserializer != null) return deserializer; + if (classNameResolver != null) { + try { + classNameResolver.resolve(cl.getName()); + } catch (Exception e) { + throw new HessianProtocolException(e); + } + } + for (int i = 0; deserializer == null && _factories != null && i < _factories.size(); i++) { AbstractSerializerFactory factory; factory = (AbstractSerializerFactory) _factories.get(i); @@ -428,6 +444,14 @@ public Deserializer getDeserializer(String type) if (deserializer != null) return deserializer; + if (classNameResolver != null) { + try { + type = classNameResolver.resolve(type); + } catch (Exception e) { + throw new HessianProtocolException(e); + } + } + if (type.startsWith("[")) { Deserializer subDeserializer = getDeserializer(type.substring(1)); deserializer = new ArrayDeserializer(subDeserializer); diff --git a/src/test/java/com/alipay/stc/ArrayInjectTest.java b/src/test/java/com/alipay/stc/ArrayInjectTest.java new file mode 100644 index 0000000..c1eca51 --- /dev/null +++ b/src/test/java/com/alipay/stc/ArrayInjectTest.java @@ -0,0 +1,101 @@ +/* + * 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.alipay.stc; + +import com.caucho.hessian.io.Hessian2Input; +import com.caucho.hessian.io.HessianInput; +import com.caucho.hessian.io.SerializerFactory; +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * 通过数组等其他方式绕过安全黑名单的case + */ +public class ArrayInjectTest { + + @Test + public void testHessian2Array() throws IOException { + SerializerFactory factory = new SerializerFactory(); + String s = "567400075b6f626a6563746e025674001e5b636f6d2e73756e2e726f777365742e4a646263526f77536574496d706c6e014fad786f6d2e73756e2e726f777365742e4a646263526f77536574496d706cac07636f6d6d616e640355524c0a64617461536f757263650a726f77536574547970650b73686f7744656c657465640c717565727954696d656f7574076d6178526f77730c6d61784669656c6453697a650b636f6e63757272656e637908726561644f6e6c791065736361706550726f63657373696e670969736f6c6174696f6e08666574636844697209666574636853697a6504636f6e6e02707302727306726f77734d44057265734d440d694d61746368436f6c756d6e730f7374724d61746368436f6c756d6e730c62696e61727953747265616d0d756e69636f646553747265616d0b617363696953747265616d0a6368617253747265616d036d6170096c697374656e65727306706172616d736f904e4e4ecbec46909090cbf0545492cbe8904e4e4e4e4e567400106a6176612e7574696c2e566563746f726e0a8f8f8f8f8f8f8f8f8f8f7a76929a4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e7692904d7400136a6176612e7574696c2e486173687461626c657a7a4a027a"; + byte[] bs = hex2byte(s.getBytes()); + Assert.assertTrue(s.equalsIgnoreCase(byte2hex(bs))); + + ByteArrayInputStream input = new ByteArrayInputStream(bs, 0, bs.length); + Hessian2Input hin = new Hessian2Input(input); + hin.setSerializerFactory(factory); + + try { + hin.readObject(); + Assert.fail(); + } catch (Exception e) { + Assert.assertTrue(e instanceof IOException); + } + } + + @Test + public void testHessian1Array() throws IOException { + SerializerFactory factory = new SerializerFactory(); + String s = "567400075b6f626a6563746e025674001e5b636f6d2e73756e2e726f777365742e4a646263526f77536574496d706c6e014fad786f6d2e73756e2e726f777365742e4a646263526f77536574496d706cac07636f6d6d616e640355524c0a64617461536f757263650a726f77536574547970650b73686f7744656c657465640c717565727954696d656f7574076d6178526f77730c6d61784669656c6453697a650b636f6e63757272656e637908726561644f6e6c791065736361706550726f63657373696e670969736f6c6174696f6e08666574636844697209666574636853697a6504636f6e6e02707302727306726f77734d44057265734d440d694d61746368436f6c756d6e730f7374724d61746368436f6c756d6e730c62696e61727953747265616d0d756e69636f646553747265616d0b617363696953747265616d0a6368617253747265616d036d6170096c697374656e65727306706172616d736f904e4e4ecbec46909090cbf0545492cbe8904e4e4e4e4e567400106a6176612e7574696c2e566563746f726e0a8f8f8f8f8f8f8f8f8f8f7a76929a4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e7692904d7400136a6176612e7574696c2e486173687461626c657a7a4a027a"; + byte[] bs = hex2byte(s.getBytes()); + Assert.assertTrue(s.equalsIgnoreCase(byte2hex(bs))); + + ByteArrayInputStream input = new ByteArrayInputStream(bs, 0, bs.length); + HessianInput hin = new HessianInput(input); + hin.setSerializerFactory(factory); + + try { + hin.readObject(); + Assert.fail(); + } catch (Exception e) { + Assert.assertTrue(e instanceof IOException); + } + } + + private String byte2hex(byte[] b) { + StringBuilder hs = new StringBuilder(); + String stmp; + for (int n = 0; b != null && n < b.length; n++) { + stmp = Integer.toHexString(b[n] & 0XFF); + if (stmp.length() == 1) + hs.append('0'); + hs.append(stmp); + } + return hs.toString().toUpperCase(); + } + + /** + * 十六转byte + * + * @param b + * @return + */ + private byte[] hex2byte(byte[] b) { + if ((b.length % 2) != 0) + throw new IllegalArgumentException(); + byte[] b2 = new byte[b.length / 2]; + for (int n = 0; n < b.length; n += 2) { + String item = new String(b, n, 2); + b2[n / 2] = (byte) Integer.parseInt(item, 16); + } + return b2; + } +} diff --git a/src/test/java/com/alipay/stc/Hessian1BlackListTest.java b/src/test/java/com/alipay/stc/Hessian1BlackListTest.java new file mode 100644 index 0000000..5a1b56d --- /dev/null +++ b/src/test/java/com/alipay/stc/Hessian1BlackListTest.java @@ -0,0 +1,201 @@ +/* + * 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.alipay.stc; + +import com.alipay.hessian.ClassNameResolver; +import com.alipay.hessian.NameBlackListFilter; +import com.alipay.stc.bl.MockNameBlacklistFilter; +import com.alipay.stc.bl.TestBlackBean; +import com.caucho.hessian.io.HessianInput; +import com.caucho.hessian.io.HessianOutput; +import com.caucho.hessian.io.SerializerFactory; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *
自定义对象,数组,List,Map 命中黑名单的case
+ * + * @author GengZhang + */ +public class Hessian1BlackListTest { + + static SerializerFactory serializerFactory; + + @BeforeClass + public static void init() { + NameBlackListFilter filter = new MockNameBlacklistFilter(); + ClassNameResolver resolver = new ClassNameResolver(); + resolver.addFilter(filter); + serializerFactory = new SerializerFactory(); + serializerFactory.setClassNameResolver(resolver); + } + + @Test + public void testBeanSerialize() throws IOException { + TestBlackBean blackBean = new TestBlackBean().setString("sss"); + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + HessianOutput hout = new HessianOutput(output); + hout.setSerializerFactory(serializerFactory); + + try { + hout.writeObject(blackBean); + hout.flush(); + Assert.fail(); + } catch (Exception e) { + Assert.assertTrue(e instanceof IOException); + } + } + + @Test + public void testBeanDeserialize() throws IOException { + byte[] bs = new byte[] { 77, 116, 0, 31, 99, 111, 109, 46, 97, 108, 105, 112, 97, 121, 46, 115, 116, 99, + 46, 98, 108, 46, 84, 101, 115, 116, 66, 108, 97, 99, 107, 66, 101, 97, 110, 83, 0, 6, 115, 116, + 114, 105, 110, 103, 83, 0, 3, 115, 115, 115, 122 }; + + ByteArrayInputStream input = new ByteArrayInputStream(bs, 0, bs.length); + HessianInput hin = new HessianInput(input); + hin.setSerializerFactory(serializerFactory); + + try { + hin.readObject(); + Assert.fail(); + } catch (Exception e) { + Assert.assertTrue(e instanceof IOException); + } + } + + @Test + public void testListSerialize() throws IOException { + TestBlackBean blackBean = new TestBlackBean().setString("sss"); + List list = new ArrayList自定义对象,数组,List,Map 命中黑名单的case
+ * + * @author GengZhang + */ +public class Hessian2BlackListTest { + + static SerializerFactory serializerFactory; + + @BeforeClass + public static void init() { + NameBlackListFilter filter = new MockNameBlacklistFilter(); + ClassNameResolver resolver = new ClassNameResolver(); + resolver.addFilter(filter); + serializerFactory = new SerializerFactory(); + serializerFactory.setClassNameResolver(resolver); + } + + @Test + public void testBeanSerialize() throws IOException { + TestBlackBean blackBean = new TestBlackBean().setString("sss"); + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + Hessian2Output hout = new Hessian2Output(output); + hout.setSerializerFactory(serializerFactory); + + try { + hout.writeObject(blackBean); + hout.flush(); + Assert.fail(); + } catch (Exception e) { + Assert.assertTrue(e instanceof IOException); + } + } + + @Test + public void testBeanDeserialize() throws IOException { + byte[] bs = new byte[] { 79, -81, 99, 111, 109, 46, 97, 108, 105, 112, 97, 121, 46, 115, 116, 99, 46, 98 + , 108, 46, 84, 101, 115, 116, 66, 108, 97, 99, 107, 66, 101, 97, 110, + -111, 6, 115, 116, 114, 105, 110, 103, 111, -112, 3, 115, 115, 115 }; + + ByteArrayInputStream input = new ByteArrayInputStream(bs, 0, bs.length); + Hessian2Input hin = new Hessian2Input(input); + hin.setSerializerFactory(serializerFactory); + + try { + hin.readObject(); + Assert.fail(); + } catch (Exception e) { + Assert.assertTrue(e instanceof IOException); + } + } + + @Test + public void testListSerialize() throws IOException { + TestBlackBean blackBean = new TestBlackBean().setString("sss"); + List list = new ArrayList