多次触发FastJson漏洞的AutoType机制,你了解吗?

news2024/11/25 13:19:07

一个反序列化问题

在一次日志巡检过程中,发现线上业务出现报错。线上业务场景是:调用三方restful接口,根据接口返回json字符串内容,进行反序列化处理,业务中使用的json处理工具是FastJson(v1.2.71)。

报错是使用fastJson进行反序列化时出现的,问题json字符串如下:

{
    "name":"",
    "error":{
        "@type":"xxx.xxx.ErrorType",
        "message":"xxxxx"
    }
}

从数据结构上看,这个json字符串并没有什么特殊性,就是一个普通的字符串而已。从内容上看,比较特殊的地方在于多了一个特殊的字段“@type”,经过测试,反序列化报错,的确是因为这个特殊的字段造成的(把@type字段去掉,反序列化可以正常进行)。

那么@type是什么鬼,为什么有了字段就会产生问题呢?

@type和AutoType

使用过json序列化工具,处理包含接口、抽象类等无法直接实例化的字段类型时,你是否想过这些序列化工具是如何进行反序列化的吗?如果没有看明白这个问题的话,可以看一下下面的代码实例。

static class VehicleStore {
        private String name;
        private Vehicle vehicle;

       // 省略 setter/getter
    }

    interface Vehicle {
    }


    static class Car implements Vehicle {
        private BigDecimal price;
		// 省略 setter/getter
       
    }

上面代码定义了一个比较简单的数据类型,VehicleStore类中包含了一个类型是接口Vehicle 的字段 vehicle,接口Vehicle有一个实现类Car。

使用FastJson对VehicleStore进行序列化。

@Test
    public void deserializer() {
        VehicleStore store = new VehicleStore();
        store.setName("vehicleStore");
        Car car = new Car();
        car.setPrice(new BigDecimal(5000000));
        store.setVehicle(car);
        String jsonString = JSON.toJSONString(store);
    }

序列化后的json字符串内容如下:

 {"name":"vehicleStore","vehicle":{"price":5000000}}

在这个反序列化后的字符串内容中,vehicle字段的内容是 {“price”:5000000} ,无论从内容上、还是结构上看,根本看不出 {“price”:5000000} 和类型Car,有什么关系,那么用这个json字符串,进行反序列化,如何反序列化出 VehicleStore,并且把字段vehicle指定为Car呢?

其实是不能的,如果直接用FastJson进行反序列化,反序列化出来的VehicleStore中vehicle字段是空(没有任何字段内容)。
在这里插入图片描述

总结来说:当一个类中包含了一个接口(或抽象类),在使用fastjson进行序列化的时候,会将子类型抹去,只保留接口(抽象类)的类型,使得反序列化时无法拿到原始类型

为了解决这个问题,在fastjson中引入了AutoType机制,简单来说,既然无法正常反序列化是序列化时把原始类型擦除掉了导致的,那么在序列化时,把类型信息给添加上可以了。的确,FastJson也是这样做的,具体做法如下:

序列化:
在进行序列化时,使用

JSON.toJSONString(xxxObj, SerializerFeature.WriteClassName);

序列化出来的内容会带上"@type"字段,记录被序列化的类型,弥补类型擦除的问题。序列化后,内容如下:

{"@type":"com.test.FastJsonTest$VehicleStore","name":"vehicleStore","vehicle":{"@type":"com.test.FastJsonTest$Car","price":5000000}}

反序列化:
反序列化时使用@type字段完成对子类/实现类的实例化,然后,再将相应的字段内容通过setter方法注入到实例化后的对象中,完成反序列化。

完整实例代码:


@Test
    public void deserializer() {
        VehicleStore store = new VehicleStore();
        store.setName("vehicleStore");
        Car car = new Car();
        car.setPrice(new BigDecimal(5000000));
        store.setVehicle(car);

        String jsonString = JSON.toJSONString(store, SerializerFeature.WriteClassName); 
        VehicleStore newStore = JSON.parseObject(jsonString, VehicleStore.class);
        Car car = (Car) newStore.getVehicle();
    }


问题解决

到这里在文章开头,遇到的@type是怎么回事儿,也就清楚了。那么为什么带上@type后,反序列化会报错呢?这里我直接说一下答案:直接原因是@type指定的类型,在系统中不存在,在反序列化时,找不到该类型。

解决问题的方法也很简单,既然@type指定的类型不存在,那么可以在系统中把需要的类型定义出来,不过@type指定的类型,是三方接口系统中定义的,如果把该类型引入到调用方系统中,那么对于调用方的侵入性很大,而且定义这个类型,仅仅为了解决这个问题,有很大解释成本在里面。

第二种解决方案:在反序列化时,忽略@type字段,这需要在反序列化时,添加Feature.IgnoreAutoType,完整的配置方式如下:

VehicleStore newStore1 = JSON.parseObject(jsonStr, VehicleStore.class, Feature.IgnoreAutoType);

到这里,开头的问题已经得到了解决,但是了解了AutoType机制后,你是否想过,如果把@Type指定为一个比较“特殊”的类型,有可能会对系统的安全产生比较大的威胁。

比如,把@type指定一个jdk中自带的类型 com.sun.rowset.JdbcRowSetImpl ,同时把字段dataSourceName设置为一个rmi数据源,那么对rmi数据源进行解析时,就完成了对rmi的调用,实现了对系统的远程命令执行。

具体操作过程如下(此漏洞,已修复,无法复现了,哈哈哈)

public void setDataSourceName(String var1) throws SQLException {
        if (this.getDataSourceName() != null) {
            if (!this.getDataSourceName().equals(var1)) {
                super.setDataSourceName(var1);// 注入攻击rmi源
                this.conn = null;
                this.ps = null;
                this.rs = null;
            }
        } else {
            super.setDataSourceName(var1);
        }
    } 


private Connection connect() throws SQLException {
        if (this.conn != null) {
            return this.conn;
        } else if (this.getDataSourceName() != null) {
            try {
                InitialContext var1 = new InitialContext();
                DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());// 调用rmi方法
                return this.getUsername() != null && !this.getUsername().equals("") ? var2.getConnection(this.getUsername(), this.getPassword()) : var2.getConnection();
            } catch (NamingException var3) {
                throw new SQLException(this.resBundle.handleGetObject("jdbcrowsetimpl.connect").toString());
            }
        } else {
            return this.getUrl() != null ? DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword()) : null;
        }
    }

其实FastJson的很多安全漏洞都和AutoType有关,当黑客发现了一个漏洞后,作者会立即进行相应的修复,在安全的攻防过程中,fastJson对AutoType进行了多个版本的更新:

1.2.59发布,增强AutoType打开时的安全性 fastjson
1.2.60发布,增加了AutoType黑名单,修复拒绝服务安全问题 fastjson
1.2.61发布,增加AutoType安全黑名单 fastjson
1.2.62发布,增加AutoType黑名单、增强日期反序列化和JSONPath fastjson
1.2.66发布,Bug修复安全加固,并且做安全加固,补充了AutoType黑名单 fastjson
1.2.67发布,Bug修复安全加固,补充了AutoType黑名单 fastjson
1.2.68发布,支持GEOJSON,补充了AutoType黑名单。(引入一个safeMode的配置,配置safeMode后,无论白名单和黑名单,都不支持autoType。) fastjson
1.2.69发布,修复新发现高危AutoType开关绕过安全漏洞,补充了AutoType黑名单 fastjson
1.2.70发布,提升兼容性,补充了AutoType黑名单

对此过程有感兴趣的老铁可以阅读一下下面这个文章:https://juejin.cn/post/6846687594130964488

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1332794.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux系统编程二十三】:(信号2)--信号的保存

【Linux系统编程二十三】:信号的保存 一.信号的保存1.阻塞信号2.sigset_t类型(位图)3.block表4.handler表5.pending表 二.实验验证三.信号的其他概念 一.信号的保存 信号发送本质上是操作系统发送信号,而进程PCB内部有一个位图用来表示是否接收到信号。…

T-Dongle-S3开发笔记——创建工程

创建Hello world工程 打开命令面板 方法1:查看->命令面板 方法2:按F1 选择ESP-IDF:展示示例项目 创建helloworld 选择串口 选择芯片 至此可以编译下载运行了 运行后打印的信息显示flash只有2M。但是板子上电flash是W25Q32 4MB的吗 16M-bit

高级RGA(二):父文档检索器

在我之前写的<<使用langchain与你自己的数据对话>>系列博客中&#xff0c;我们介绍了利用大型语言模型LLM来检索文档时的过程和步骤&#xff0c;如下图所示&#xff1a; 我们在检索文档之前&#xff0c;通常需要对文档进行切割&#xff0c;然后将其存入向量数据库如…

用友时空KSOA UploadImage任意文件上传漏洞

漏洞描述 用友时空 KSOA 是根据流通企业前沿的IT需求推出的统的IT基础架构&#xff0c;它可以让流通企业各个时期建立的 IT 系统之间彼此轻松对话。由于用友时空设备开放了文件上传功能&#xff0c;但未鉴权且上传的文件类型、大小、格式、路径等方面进行严格的限制和过滤&…

企业知识库在跨地域团队协作中的价值

随着全球化进程的不断加速&#xff0c;越来越多的企业开始面临跨地域协作的挑战。在这种背景下&#xff0c;企业知识库作为一种重要的知识管理工具&#xff0c;对于提高团队协作效率、促进知识共享与创新具有不可替代的价值。接下来就说一下知识库在跨地域团队协作中的重要性及…

JVM简单学习

jvm与字节码 jvm只需关注字节码文件 jvm由哪些部分构成 1.类加载子系统&#xff0c;将磁盘中的字节码文件加载到方法区的内存空间中 类加载器分两种&#xff1a;引导类加载器是jvm底层中用C和C语言写的 各个默认的类加载器的不同区别在于 各自默认负责要加载的类的目录不一…

web前端游戏项目-辨色大比拼【附源码】

web前端游戏项目-辨色大比拼【附源码】 《辨色大比拼》是一个旨在测试和提升玩家颜色识别能力的在线游戏。在游戏中&#xff0c;玩家将通过辨识颜色来解谜并推进游戏进程。辨色大比拼也是一个寓教于乐的游戏&#xff0c;它不仅提供了一个有趣的辨色挑战&#xff0c;还能帮助玩…

通过 Higress Wasm 插件 3 倍性能实现 Spring-cloud-gateway 功能

作者&#xff1a;韦鑫&#xff0c;Higress Committer&#xff0c;来自南京航空航天大学分布式系统实验室 导读&#xff1a;本文将和大家一同回顾 Spring Cloud Gateway 是如何满足 HTTP 请求/响应转换需求场景的&#xff0c;并为大家介绍在这种场景下使用 Higress 云原生网关的…

【Linux】Linux常见指令解析上

目录 1. 前言2. ls指令3. pwd指令4. cd指令3.1 cd常见快捷指令 4. touch指令5. mkdir指令6. rmdir指令 && rm指令 &#xff08;重要&#xff09;6.1 rmdir指令6.2 rm指令 7. man指令 1. 前言 这篇文章我们将详细介绍一下Linux下常见的基本指令。 2. ls指令 语法: ls [选…

掌握函数式组件:迈向现代化前端开发的关键步骤(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

精通推荐算法1:为什么需要推荐系统(系列文章,建议收藏)

作者简介&#xff1a; 腾讯算法研究员。硕士毕业于中国科学院大学。在阿里和腾讯工作多年&#xff0c;拥有丰富的搜索和推荐算法经验。CSDN博客专家&#xff0c;原创文章100篇。发表专利15个&#xff0c;其中已授权6个。 1 概述 随着互联网的大力发展&#xff0c;用户规模和…

操作无法完成(错误 0x000006ba),Windows 11 PDF打印机无法使用解决办法

操作无法完成(错误 0x000006ba)&#xff0c;Windows 11 PDF打印机无法使用解决办法 解决方式一 先重启一次电脑&#xff0c;看看是否可以解决问题。 解决方式二 重新启动 Printer Spooler 服务

降本后如何有效增效

在当今竞争激烈的商业环境中&#xff0c;“勒紧裤腰带”式的求生存谋发展&#xff0c;已成为更多成长型企业常态化的战略方向之一了。然而&#xff0c;如何在有限的资源成本下释放更多的效能&#xff1f;降本策略是否会影响组织活力造成得不偿失的结果&#xff1f;如果降本之后…

Maya python清除命名空间

问题描述&#xff1a; Maya命名空间可能存在嵌套。 如上&#xff0c;直接删除 :female_actor02会出现异常。 因此需要先删除子命名空间&#xff0c;再删除父命名空间。 解决方法&#xff1a; def remove_namespace_node(namespace_name, ns_parent":"):""…

解决虚拟机卡顿、卡死、待机后不动的情况(真实有效

本人环境&#xff1a; VM workstation 17.5 ubuntu 22.04 虚拟机配置&#xff1a;4核 4g issue&#xff1a; 出现开机卡死不动运行一段时间&#xff0c;可能半小时不到&#xff0c;就页面卡死不动经常需要关机重启才解决&#xff0c;可能没有解决 1.配置虚拟化引擎 这一步我称…

旅游品牌网站搭建的作用是什么

我国旅游业规模非常高&#xff0c;各地大小旅游景区也是非常多&#xff0c;尤其节假日更是可以达到峰值&#xff0c;无论周边游还是外地游对所要去的景区&#xff0c;消费者总是需要来回了解很多&#xff0c;浏览器查或旅行社咨询等。 对旅游企业而言&#xff0c;传统线下方式…

css 实现满屏升空的气球动画

最终实现效果 demo放在最后了。。。。 问题一 怎么实现满屏气球&#xff1f;简单理解就是多个气球的合并&#xff0c;难道要写多个盒子吗&#xff1f;确实是这样子&#xff0c;但可以有更好的办法&#xff0c;其实就是通过原生操作多个盒子生成&#xff0c;所以只需要实现一个…

【JavaWeb学习笔记】13 - JSP浏览器渲染技术

项目代码 https://github.com/yinhai1114/JavaWeb_LearningCode/tree/main/jsp 目录 项目代码 JSP 一、JSP引入 1.JSP现状 2.为什么需要JSP 二、JSP基本原理及使用 1.基本介绍 2.快速入门 ​编辑 3.JSP运行原理 4.page指令 三、JSP三种常用的脚本 1.声明脚本基本语…

做到这两条,破解35岁中年危机

最近我在看吴军老师的《富足》这本书&#xff0c;其中有一篇文章讲的是如何破解35岁中年危机&#xff0c;我觉得讲清楚了这个问题的本质&#xff0c;我在这里分享给你&#xff0c;以下内容大部分摘抄自《破解35岁中年危机》一章。 35岁中年危机的原因 35岁中年危机的说法好像…

nodejs微信小程序+python+PHP计算机网络在线考试系统-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…