XStream于2021.08.22升级了1.4.18版本,本次改动很大,看看官网说了啥
大概的意思是说,9年前,XStream整了一个安全框架,用来反序列化时为允许的类型实现黑名单或白名单,在版本1.4.17之前,XStream保留了一个默认黑名单,以拒绝所有类型的Java运行时(用于各种安全攻击),从而保证现有用户的最佳运行时兼容性。然而,这种方法失败了(它每个版本补漏洞就是把已知的攻击加到黑名单中)。经过几个月的研究,仅Java运行时就包含了数十种可用于攻击的类型,甚至不需要查看类路径上的第三方库(他们补不过来了)。因此,XStream的新版本现在默认使用一个白名单(重点),这是自9年以来一直推荐的。所以只要你遵循在初始化时,把场景(就是你反序列化用到的类)在初始化时加入到白名单中,就不会出现任何问题,否则新版本在反序列化时肯定会失败。
XStream团队原来是靠打补丁解决问题,现在改成加白名单,所以当你的代码出现com.thoughtworks.xstream.security.ForbiddenClassException错误的时候,那你先看看你得xstream是不是升到了1.4.18版本,先降级到1.4.17 或者 去改你的反序列化方法
public Object toBean(Class<?> clazz, String xml){
Object xmlObject;
XStream xStream = new XStream();
//重点在这,1.4.18 增加了白名单机制,你的内容里涉及了多少个类,你就往里加吧
Class<?>[] classes = new Class[] { Calss1.class, Calss2.class, ... };
xStream.allowTypes(classes);
//应用传过来类的注解
xStream.processAnnotations(clazz);
//自动检测注解
xStream.autodetectAnnotations(true);
//手动设置ClassLoader
xStream.setClassLoader(clazz.getClassLoader());
xmlObject=xStream.fromXML(xml);
return xmlObject;
}
如果,嫌 xStream.allowTypes(classes); 太费事,可以使用allowTypesByWildcard()方法,按照包路径进行过滤,如下:
private static final String[] ALLOW_TYPES = new String[]{"org.test.**"};
xStream.allowTypesByWildcard(ALLOW_TYPES);
denyTypes() 可以限制指定类,1.4.18以前全靠这个修复安全漏洞
private static final Set<String> DefaultDenyTypes = new HashSet<String>() {
{
this.add("org.apache.commons.collections4.functors.InstantiateTransformer");
this.add("org.apache.commons.collections4.functors.ConstantTransformer");
this.add("org.apache.commons.collections4.functors.ChainedTransformer");
this.add("org.apache.commons.collections4.functors.InvokerTransformer");
this.add("org.apache.commons.collections4.comparators.TransformingComparator");
this.add("org.apache.commons.configuration.ConfigurationMap");
this.add("org.apache.commons.logging.impl.NoOpLog");
this.add("org.apache.commons.configuration.Configuration");
this.add("org.apache.commons.configuration.JNDIConfiguration");
this.add("java.util.ServiceLoader$LazyIterator");
this.add("com.sun.jndi.rmi.registry.BindingEnumeration");
this.add("org.apache.commons.beanutils.BeanComparator");
this.add("jdk.nashorn.internal.objects.NativeString");
this.add("com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data");
this.add("sun.misc.Service$LazyIterator");
this.add("com.sun.jndi.rmi.registry.ReferenceWrapper");
this.add("com.sun.jndi.toolkit.dir.LazySearchEnumerationImpl");
this.add("org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator$PartiallyComparableAdvisorHolder");
this.add("org.springframework.beans.factory.BeanFactory");
this.add("org.springframework.jndi.support.SimpleJndiBeanFactory");
this.add("org.springframework.beans.factory.support.RootBeanDefinition");
this.add("org.springframework.beans.factory.support.DefaultListableBeanFactory");
this.add("org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor");
this.add("org.springframework.aop.aspectj.annotation.BeanFactoryAspectInstanceFactory");
this.add("org.springframework.aop.aspectj.AspectJPointcutAdvisor");
this.add("org.springframework.aop.aspectj.AspectJAroundAdvice");
this.add("org.springframework.aop.aspectj.AspectInstanceFactory");
this.add("org.springframework.aop.aspectj.AbstractAspectJAdvice");
this.add("javax.script.ScriptEngineFactory");
this.add("com.sun.rowset.JdbcRowSetImpl");
this.add("com.rometools.rome.feed.impl.ToStringBean");
this.add("com.rometools.rome.feed.impl.EqualsBean");
this.add("java.beans.EventHandler");
this.add("javax.imageio.ImageIO$ContainsFilter");
this.add("java.util.Collections$EmptyIterator");
this.add("javax.imageio.spi.FilterIterator");
this.add("java.lang.ProcessBuilder");
this.add("java.lang.Runtime");
this.add("org.codehaus.groovy.runtime.MethodClosure");
this.add("groovy.util.Expando");
this.add("com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource");
this.add("org.apache.commons.collections.map.LazyMap");
this.add("org.apache.commons.collections.functors.ChainedTransformer");
this.add("org.apache.commons.collections.functors.InvokerTransformer");
this.add("org.apache.commons.collections.functors.ConstantTransformer");
this.add("org.apache.commons.collections.keyvalue.TiedMapEntry");
}
};
String[] dentTypes = new String[DefaultDenyTypes.size()];
DefaultDenyTypes.toArray(dentTypes);
xStream.denyTypes(dentTypes);