问题记录:XStream ForbiddenClassException 异常

问题记录

XStream

ForbiddenClassException

今天,笔者在工作中遇到了一个解析XML的异常:

com.thoughtworks.xstream.security.ForbiddenClassException: xxx.xxx.xxx.xxx
	at com.thoughtworks.xstream.security.NoTypePermission.allows(NoTypePermission.java:26)
	at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:74)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47)
	at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:135)
	at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
	at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1421)
	at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1399)
	at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1284)
	at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1275)

有同事在解决组件漏洞的问题,可能是相关同事修改了XStream的版本。

排查GIT提交记录,Xstream版本由1.4.17升级到了1.4.19。异常信息中,看到了熟悉的security,鉴权问题。

本地版本回退至1.4.17,XML解析正常,但是笔者注意到了一个之前忽略的警告:

Security framework of XStream not explicitly initialized, using predefined black list on your own risk.

大概意思就是没有初始化XStream的安全组件,默认使用了一个。

查看XStream的版本维护文档:

http://x-stream.github.io/changes.html

在这里插入图片描述

在1.4.18的更新记录里,有这么两段话,大概意思就是,新版本的XStream默认使用了一个白名单的东西,用户必须初始化这个白名单,否则反序列化操作会失败。

于是笔者尝试将本地1.4.17版本更新至1.4.18,不出所料,仍然是ForbiddenClassException,于是准备修改方案。

参考工具:XStream官方文档,路径:

http://x-stream.github.io/javadoc/index.html

在XStream类中,查询到关于添加鉴权的方法:

在这里插入图片描述

排查到,allowTypes方法,支持根据类型、类名等参数添加权限。

修改后的代码(demo):

		/**
     * xml -> javaBean
     * @param xml
     * @param node
     * @return
     */
    public static Object simpleXmlToObject(String xml, Object... node) {
        Object obj = null;
        try {
            XStream xStream = new XStream(new DomDriver());
            for (int i = 0; i < node.length; i++) {
                Object objTemp = node[i];
                xStream.alias(objTemp.getClass().getSimpleName(), objTemp.getClass());
              	// 新增这一行,根据类型添加安全权限
                xStream.allowTypes(new Class[]{objTemp.getClass()});
            }
            obj = xStream.fromXML(xml);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return obj;
    }

测试代码:

@Data
public class User {

    private String userId;

    private String userName;


    public static void main (String[] args) {

        String str = "<User>\n" +
                    "    <userId>1</userId>\n" +
                    "    <userName>张三</userName>\n" +
                    "</User>";

        final User user = (User)XStreamUtils.simpleXmlToObject(str, new User());

        System.out.println(user.getUserId());

        System.out.println(user.getUserName());

    }
}

sout输出:

1
张三

笔者会持续更新工作中遇到的问题以及解决方案。

好记性不如烂笔头。

愿与诸君共勉。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值