Fastjson致命缺陷

JetCache序列化避坑指南:为什么FASTJSON2在2.7版本被隐藏了? 本文深入解析JetCache在2.7版本中隐藏FASTJSON2序列化器的技术原因,包括安全风险、兼容性问题及架构精简考量。提供了Kryo5替代方案、自定义FASTJSON2扩展及版本回退三种实战解决方案,帮助开发者根据业务需求选择合适的序列化策略,确保系统性能与安全。 阅读详情

前言

这个周末被几个技术博主的同一篇公众号文章 fastjson又被发现漏洞,这次危害可导致服务瘫痪! 刷屏,离之前的漏洞事件没多久,FastJson 又出现严重 Bug。目前项目中不少使用了 FastJson 做对象与JSON数据的转换,又需要更新版本重新部署,可以说是费时费力。与此同时,也带给我新的思考,面对大量功能强大的开源库,我们不能盲目地引入到项目之中,众多开源框架中任一个不稳定因素就足以让一个项目遭受灭顶之灾。趁着周末,在家学习下同样具备对象JSON相互转换功能的优秀开源框架 Gson,并且打算将今后项目使用 FastJson 的地方逐渐换成使用 Gson,记录下学习总结的内容,希望对小伙伴也有所帮助。

本文所涉及所有代码片段均在下面仓库中,感兴趣的小伙伴欢迎参考学习:

https://github.com/wrcj12138aaa/gson-actions

版本支持:

- JDK 8

- gson 2.8.5

- junit 5.5.1

- Lomok 1.18.8

Gson 简介

在正式介绍 Gson 之前,我们可以先从官方的wiki看下 Gson 的描述,了解它是什么?

Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object。

从描述可以看出,Gson 是用于将 Java 对象与 JSON格式字符串数据相互转换的 Java 库。它起初在Google 内部广泛使用在 Android 平台 和 Java 服务端上。2008 年开源之后,成为了谷歌又一个被广泛使用的开源框架,截止目前(2019.09.08) 在GitHub 上已有1W6 多星,相同作用的类库还有 Spring Framework 中集成的 Jackson,以及阿里开源的 FastJson等。

在使用方面,Gson 提供简易的API fromJson/toJson 来实现 Java 与 JSON 之间的转换,并且能生成紧凑,可读的 JSON 字符串输出,还支持复杂对象转换和丰富的自定义表示,足以满足在日常开发中我们绝大部分的 JSON 数据处理需求。

我们通常将对象与JSON字符串间的转换称之为序列化和反序列化(Serialization/Deserialization)。将对象转化成 JSON字符串的过程称为序列化,将JSON 字符串转化成对象的过程称为反序列化。img

Gson 基本使用

使用 Gson 框架进行序列化与反序列操作,都离不开 com.google.gson.Gson 对象,它也是 Gson 框架的关键对象,提供的公共 API 具备了多种序列化和反序列方式。

img

Gson 对象的创建主要有两种方式:

  • 使用 new 关键字直接创建:Gson gson = new Gson()
  • 由 GsonBuilder 对象构建:Gson gson = new GsonBuilder().create()

通常情况下,上面两种方式创建的 Gson 对象在进行序列化与反序列操作时行为都是一样的,但是第二种方式构建 Gson 对象时,允许进行额外的行为定制,比如格式化 JSON 字符串的输出内容,是否序列化 null 值等等。

Java 序列化

简单对象的序列化

我们可以通过下面的例子来看下通过上述两种方式序列化 Java 对象的不同效果:

public class ResultTest {
    @Test
    void test_serialization() {
        Gson gson = new Gson();
        Result result = new Result(200, "成功", null);
        String json = gson.toJson(result);
        System.out.println("json is "   json);

        Gson buildedGson = new GsonBuilder().setPrettyPrinting().serializeNulls().create();
        String buildedJson = buildedGson.toJson(result);
        System.out.println("buildedJson is "   buildedJson);
    }

    class Result {
        private int code;
        private String message;
        private Object data;

        public Result(int code, String message, Object data) {
            this.code = code;
            this.message = message;
            this.data = data;
        }
    }
}

运行该测试用例,在控制台可以看到如下日志输出:

img

从结果可以看出,默认的 Gson 对象行为序列化对象时会将 null 值的字段忽略,而执行 com.google.gson.GsonBuilder#serializeNulls 方法后将允许 Gson 对象序列化 null 字段;并且正常序列化后的 JSON 字符串是紧凑格式,节省字符串内存,使用 com.google.gson.GsonBuilder#setPrettyPrinting 方法之后最终输出的 JSON 字符串是更易读的格式。当然除了这两个方法,GsonBuilder 还提供了许多定制序列化和反序列化行为的API,我们将后面的内容进一步讲解。

JosnObject 生成 JSON

除了上述将自定义类的对象转换成 JSON 的方式之外,还可以使用 Gson 框架提供的 JsonObject 构建普通对象,然后使用 toJson 方法生成 JSON 字符串,在原测试类中补充下方测试类,并运行查看效果如下

@Test
void test_jsonObject_serialization() {
  Gson gson = new Gson();
  JsonObject jsonObject = new JsonObject();
  jsonObject.addProperty("code", 400);
  jsonObject.addProperty("message", "参数错误");
  String toJson = gson.toJson(jsonObject);
  String exceptedJson = "{\"code\":400,\"message\":\"参数错误\"}";
  Assertions.assertEquals(exceptedJson, toJson); //true
}

JsonObject 使用 addProperty(property,value) 方法只能用来添加 String,Number,Boolean,Character这四类数据, 因为内部是调用 com.google.gson.JsonObject#add, 并将 value 封装成了 JsonPrimitive 对象,然后保存到了内部自定义的 LinkedTreeMap 集合变量 members 中;如果需要在 JsonObject 对象上添加其他对象时,就需要直接使用 add(String property, JsonElement value) 方法添加一个 JsonElement 对象。这里的 JsonElement 是一个抽象类,JsonObject 和 JsonPrimitive 都继承了JsonElement,所以我们最终通过新的 JsonObject 对象来作为原 JsonObject 上的属性对象:

Gson gson = new Gson();
JsonObject jsonObject = new JsonObject();
//...
JsonObject nestJsonObject = new JsonObject();
nestJsonObject.addProperty("username", "one");
nestJsonObject.addProperty("score", 99);
jsonObject.add("data", nestJsonObject);
String toJson2 = gson.toJson(jsonObject);
System.out.println(toJson2);
// {"code":400,"message":"参数错误","data":{"username":"one","sc
【Fastjson 漏洞风险预警】 国家信息安全漏洞库(CNNVD)、阿里巴巴及多家主流安全厂商近期先后发布风险预警:Fastjson 1.x 分支的 1.2.68 至 1.2.83 版本存在严重远程代码执行漏洞(CVE-2026-16723),CVSS 风险评分高达 9.0 分(41)。 阅读详情

相关推荐

Fastjson反序列化漏洞深度剖析:从AutoType机制到RCE实战复现

JSON反序列化是现代Web应用数据交换的核心技术,其原理是将JSON字符串转换为内存中的对象实例。然而,当反序列化过程允许用户控制目标类时,就可能引入严重的安全风险,例如远程代码执行(RCE)。Java生态中,Fastjson库的AutoType机制设计初衷是为了便捷地还原对象类型,但其早期版本的黑名单防护存在缺陷,攻击者可利用缓存污染等手段绕过限制,加载恶意类。结合JNDI注入技术,攻击者能进一步实现命令执行,对服务器安全构成直接威胁。本文以经典的CVE-2017-18349漏洞为例,通过搭建Vulhu

weixin_30570101的博客 422

Fastjson 1.2.24反序列化漏洞实战复现:从原理到RCE

Java反序列化漏洞是应用安全领域的核心议题之一,其原理在于程序将不可信的数据流还原为对象时,可能意外执行恶意代码。Fastjson作为广泛使用的JSON解析库,其早期版本的autotype特性在带来便利的同时,也引入了严重的安全风险。该机制允许通过@type字段指定反序列化的类,若未加严格限制,攻击者可利用JNDI注入等技术,引导应用加载并执行远程恶意类,最终实现远程命令执行(RCE)。这种漏洞在内部测试、安全评估及遗留系统中仍有较高遇见概率,深刻理解其利用链,对于构建安全的Java Web应用至关重要。

weixin_33805743的博客 381

fastjson xml转json_原创 | 在XML中测试Fastjson反序列化

点击上方蓝字 关注我吧引言在实际业务开发中,经常会对xml或者json类型的请求数据进行解析。例如微信扫码支付的功能,按照微信开发文档与支付平台进行数据交互就需要使用XML格式的数据。针对XML传输的数据,最容易想到的就是XXE攻击了。通过XXE的利用,可以达到以下的目的:敏感信息泄漏(使用file协议读取敏感文件、列目录)递归调用造成拒绝服务攻击SSRF在php开启expect拓展的前...

weixin_35799467的博客 1447

Fastjson反序列化漏洞攻防演进与纵深防御实战指南

序列化与反序列化是Java网络通信与数据持久化的核心技术,其本质在于实现对象与字节序列的相互转换。然而,这一过程若设计不当,可能引入严重的安全风险,攻击者通过构造恶意输入,可触发危险方法调用链,最终实现任意代码执行,对系统造成实质性危害。Fastjson作为广泛使用的JSON解析库,其AutoType特性在提供便利的同时,也成为了漏洞的根源,由此引发了一场持续数年的攻防拉锯战。攻击者不断挖掘新的利用链和绕过手法,例如经典的缓存机制绕过,而防御方则通过引入安全模式、严格白名单等手段进行应对。从技术价值看,理解

weixin_33796205的博客 653

【异常】使用FastJSON进行JSON解析出错,报错内容syntax error, expect {, actual [, pos 0 at

如果你使用的是特定类型的解析器(比如期望解析对象但实际提供的是数组),也可能导致这个错误。如果 JSON 字符串格式正确,但错误依然存在,那么可能是你的代码期望了错误的数据类型。确保你提供的 JSON 字符串是格式正确的,并且与你期望解析的数据类型匹配。你的代码可能期望解析一个对象,但实际上提供的 JSON 字符串是一个数组。使用在线的 JSON 验证工具来检查你的 JSON 字符串是否格式正确。检查你的解析代码,确保你使用正确的方法来解析 JSON 数据。

奶爸的编程之路,也就一周冷个三天 5506

skill使用教程,从小白到大神进阶

(2)突然无法使用(NodeJS安装参考):如果正常使用中,突然发现claude命令无法启动claude-code了,可能是claude-code正在后台自动更新,等待几分钟后再尝试使用,如果还是不行,请先运行下列代码移除claude-code,注意,如果你的node安装目录不同,要替换成自己的安装目录:rm -rf /opt/homebrew/lib/node_modules/@anthropic-ai/claude-code。安装完成后,让我们启动 Claude Code,看看它长什么样。

weixin_45036829的博客 2006

SQLSTATE58030

在优化一条SQL的时候遇到了执行错误 gtlions =# select t1.telnumber,t2.ua,t2.url,t1.apply_name,t2.apply_name from tb1 t1 gtlions -# left outer join tb2 t2 on t1.sid = t2.ipsid gtlions-# where t1.sum_date=20141128 a

Gtlions Tracker 3658

基于FSL的DTI数据预处理流程

最近在学习处理DTI数据,总结了一份应用FSL做DTI数据预处理的流程与大家交流交流。如果有错误的地方欢迎大家指正!        我用的数据是Philips的数据,如果是GE或者西门子的数据可能会有所不同。   原始数据:包括3DT1数据和高分辨率DTI数据,均是dicom格式。 工具:MRICRON和FSL,所有的命令均在Linux的终端中运行。   1.格式转换:将后缀名为dcm

zaza_zaza的博客 2万+

招标文件智能解析系统开发文档

本系统是一个基于OCR与大语言模型的招标文件智能解析平台,专门用于处理和分析招标文件,自动提取关键信息并进行结构化展示。

警世龙的技术博客 1925

4相5线步进电机驱动原理

步进电机驱动

while(1) 3万+

杰理AC696N系列芯片外部中断使用教程

本教程详细介绍了杰理AC696N芯片的GPIO引脚中断唤醒功能实现方法。主要内容包括: 功能特点: 支持任意GPIO引脚配置为中断源 可灵活选择上升沿或下降沿触发 提供自定义中断回调函数接口 核心实现: 通过port_wkup_interrupt_init()函数配置GPIO属性 使用request_irq()注册中断服务程序 提供中断使能/关闭接口 注意事项: 此功能在低功耗模式下无效 需注意引脚冲突和中断优先级设置 建议在回调函数中实现简洁的逻辑 应用场景: 按键检测 外部信号监测 事件触发等 本方案提

qq_42014563的博客 944

手把手教你学simulink(85.6)--非线性控制:滑模控制场景实例:基于Simulink建模仿真的滑模控制(Sliding Mode Control, SMC)在无人机自主飞行控制系统中的应用

首先,在MATLAB命令窗口中定义系统的参数和状态空间模型。matlab深色版本% 系统参数m = 1.5;% 无人机质量 (kg)g = 9.81;% 重力加速度 (m/s^2)% 惯性矩阵 (kg*m^2)% 初始条件pos0 = [0;0;0];% 初始位置 (m)vel0 = [0;0;0];% 初始速度 (m/s)0;0];% 初始姿态角 (rad)0;0];% 初始角速度 (rad/s)

MHD0815的博客 649

YOLOv8改进 | 主干篇 | 利用MobileNetV2替换Backbone(轻量化网络结构)

本文给大家带来的改进机制是,其是专为移动和嵌入式视觉应用设计的轻量化网络结构。这些模型基于简化的架构,并利用深度可分离卷积构建轻量级深度神经网络,其引入了两个简单的全局超参数,用于在延迟和准确性之间进行有效的权衡。实验表明,MobileNets在资源和准确性的权衡方面表现出色,并在多种应用(如对象检测、细粒度分类、面部属性识别和大规模地理定位)中展现了其有效性,这个模型非常适合轻量化的读者来使用。适用检测目标:轻量化网络结构适合轻量化的读者⭐⭐⭐⭐。

Snu77的博客 5683

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

上一篇: Spring Boot 注入外部配置到应用内部的静态变量
下一篇: Java 使用 UnixSocket 调用 Docker API
SpringForAll
博客等级 码龄7年 15粉丝 79原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值