Skip to content

Commit

Permalink
Fix serialization security vulnerabilities. (#8)
Browse files Browse the repository at this point in the history
* Fix CI build error on JDK 1.6 which cause by TLS upgrade of the server.  
* Upgrade version to v3.3.1
* Fix serialization security vulnerabilities.
  • Loading branch information
leizhiyuan authored and ujjboy committed Jul 13, 2018
1 parent b50eb5e commit a45db28
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 53 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ before_install:
&& wget https://archive.apache.org/dist/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.zip
&& unzip -qq apache-maven-3.2.5-bin.zip
&& export M2_HOME=$PWD/apache-maven-3.2.5
&& export PATH=$M2_HOME/bin:$PATH
&& export PATH=$M2_HOME/bin:$PATH
&& cp ./tools/ci/.travis.settings.xml $HOME/.m2/settings.xml
&& mvn -version

install:
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>com.alipay.sofa</groupId>
<artifactId>hessian</artifactId>
<version>3.3.0</version>
<version>3.3.1</version>
<packaging>jar</packaging>

<name>${project.groupId}:${project.artifactId}</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,45 +30,58 @@ public class InternalNameBlackListFilter extends NameBlackListFilter {

private static final List<String> INTERNAL_BLACK_LIST = Arrays
.asList(
"bsh",
"com.mchange",
"com.sun.",
"java.lang.Thread",
"java.net.Socket",
"java.rmi",
"javax.xml",
"org.apache.bcel",
"org.apache.commons.beanutils",
"org.apache.commons.collections.Transformer",
"org.apache.commons.collections.functors",
"org.apache.commons.collections4.comparators",
"org.apache.commons.fileupload",
"org.apache.myfaces.context.servlet",
"org.apache.tomcat",
"org.apache.wicket.util",
"org.codehaus.groovy.runtime",
"org.hibernate",
"org.jboss",
"org.mozilla.javascript",
"org.python.core",
"org.springframework",
"javax.imageio.",
"jdk.nashorn.internal.objects.NativeString",
"org.apache.commons.collections4.functors.InvokerTransformer",
"org.apache.commons.collections4.functors.ChainedTransformer",
"org.apache.commons.collections4.functors.ConstantTransformer",
"org.apache.commons.collections4.functors.InstantiateTransformer",
"org.apache.myfaces.el.CompositeELResolver",
"org.apache.myfaces.el.unified.FacesELContext",
"org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression",
"java.util.PriorityQueue",
"java.lang.reflect.Proxy",
"javax.management.MBeanServerInvocationHandler",
"javax.management.openmbean.CompositeDataInvocationHandler",
"java.beans.EventHandler",
"java.util.Comparator",
"org.reflections.Reflections",
"net.sf.json.JSONObject");
"clojure.core$constantly",
"clojure.main$eval_opt",
"com.alibaba.citrus.springext.support.parser.AbstractNamedProxyBeanDefinitionParser$ProxyTargetFactory",
"com.alibaba.citrus.springext.support.parser.AbstractNamedProxyBeanDefinitionParser$ProxyTargetFactoryImpl",
"com.alibaba.citrus.springext.util.SpringExtUtil.AbstractProxy",
"com.alipay.custrelation.service.model.redress.Pair",
"com.caucho.hessian.test.TestCons",
"com.mchange.v2.c3p0.JndiRefForwardingDataSource",
"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource",
"com.rometools.rome.feed.impl.EqualsBean",
"com.rometools.rome.feed.impl.ToStringBean",
"com.sun.jndi.rmi.registry.BindingEnumeration",
"com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl",
"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
"com.sun.rowset.JdbcRowSetImpl",
"com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data",
"java.rmi.server.UnicastRemoteObject",
"java.security.SignedObject",
"java.util.ServiceLoader$LazyIterator",
"javax.imageio.ImageIO$ContainsFilter",
"javax.imageio.spi.ServiceRegistry",
"javax.management.BadAttributeValueExpException",
"javax.naming.InitialContext",
"javax.naming.spi.ObjectFactory",
"javax.script.ScriptEngineManager",
"javax.sound.sampled.AudioFormat$Encoding",
"org.apache.carbondata.core.scan.expression.ExpressionResult",
"org.apache.commons.dbcp.datasources.SharedPoolDataSource",
"org.apache.ibatis.executor.loader.AbstractSerialStateHolder",
"org.apache.ibatis.executor.loader.CglibSerialStateHolder",
"org.apache.ibatis.executor.loader.JavassistSerialStateHolder",
"org.apache.ibatis.executor.loader.cglib.CglibProxyFactory",
"org.apache.ibatis.executor.loader.javassist.JavassistSerialStateHolder",
"org.apache.tomcat.dbcp.dbcp.datasources.SharedPoolDataSource",
"org.apache.wicket.util.upload.DiskFileItem",
"org.apache.xalan.xsltc.trax.TemplatesImpl",
"org.apache.xbean.naming.context.ContextUtil$ReadOnlyBinding",
"org.apache.xpath.XPathContext",
"org.eclipse.jetty.util.log.LoggerLog",
"org.geotools.filter.ConstantExpression",
"org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator$PartiallyComparableAdvisorHolder",
"org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor",
"org.springframework.beans.factory.BeanFactory",
"org.springframework.beans.factory.config.PropertyPathFactoryBean",
"org.springframework.beans.factory.support.DefaultListableBeanFactory",
"org.springframework.jndi.support.SimpleJndiBeanFactory",
"org.springframework.orm.jpa.AbstractEntityManagerFactoryBean",
"org.springframework.transaction.jta.JtaTransactionManager",
"org.yaml.snakeyaml.tokens.DirectiveToken",
"sun.rmi.server.UnicastRef",
"javax.management.ImmutableDescriptor",
"org.springframework.jndi.JndiObjectTargetSource");

/**
* 构造函数
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/caucho/hessian/io/Hessian2Input.java
Original file line number Diff line number Diff line change
Expand Up @@ -2200,6 +2200,12 @@ 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) {
Expand All @@ -2208,6 +2214,9 @@ public Object readObject(Class cl)

case 'M': {
String type = readType();
if (resolver != null) {
type = resolver.resolve(type);
}

// hessian/3bb3
if ("".equals(type)) {
Expand Down Expand Up @@ -2643,6 +2652,11 @@ 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);
}
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/com/caucho/hessian/io/HessianInput.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@

package com.caucho.hessian.io;

import com.alipay.hessian.ClassNameResolver;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -137,6 +139,19 @@ public SerializerFactory getSerializerFactory()
return _serializerFactory;
}

/**
* Gets the serializer factory, creating a default if necessary.
*/
public final SerializerFactory findSerializerFactory()
{
SerializerFactory factory = _serializerFactory;

if (factory == null)
_serializerFactory = factory = new SerializerFactory();

return factory;
}

/**
* Initialize the hessian stream with the underlying input stream.
*/
Expand Down Expand Up @@ -1037,6 +1052,12 @@ 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;
Expand Down Expand Up @@ -1170,6 +1191,12 @@ 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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public void test() throws Exception {

boolean error = false;
try {
resolver.resolve("java.lang.Thread");
resolver.resolve("java.security.SignedObject");
} catch (Exception e) {
error = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void testAll() {
String className = null;
boolean pass = true;
try {
filter.resolve("org.apache.commons.beanutils.xxx");
filter.resolve("java.util.ServiceLoader$LazyIterator.xxx");
} catch (Exception e) {
pass = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ public Object generateGenericObject_2b() {
}

public Object generateObject_3() {
TestCons cons = new TestCons();
SimpleTestCons cons = new SimpleTestCons();

cons.setFirst("a");
cons.setRest(cons);
Expand All @@ -694,7 +694,7 @@ public Object generateObject_3() {
}

public Object generateGenericObject_3() {
GenericObject gobj = new GenericObject(TestCons.class.getName());
GenericObject gobj = new GenericObject(SimpleTestCons.class.getName());
gobj.putField("_first", "a");
gobj.putField("_rest", gobj);
return gobj;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@
/**
* Cons-cell for testing
*/
public class TestCons implements java.io.Serializable {
public class SimpleTestCons implements java.io.Serializable {
private Object _first;
private Object _rest;

public TestCons() {
public SimpleTestCons() {
}

public TestCons(Object first) {
public SimpleTestCons(Object first) {
_first = first;
}

public TestCons(Object first, Object rest) {
public SimpleTestCons(Object first, Object rest) {
_first = first;
_rest = rest;
}
Expand Down Expand Up @@ -72,15 +72,15 @@ public String toString(HashMap map) {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName()).append("[");

if (_first instanceof TestCons)
sb.append(((TestCons) _first).toString(map));
if (_first instanceof SimpleTestCons)
sb.append(((SimpleTestCons) _first).toString(map));
else
sb.append(_first);

sb.append(",");

if (_rest instanceof TestCons)
sb.append(((TestCons) _rest).toString(map));
if (_rest instanceof SimpleTestCons)
sb.append(((SimpleTestCons) _rest).toString(map));
else
sb.append(_rest);

Expand Down
Loading

0 comments on commit a45db28

Please sign in to comment.