首页 > 其他分享 >fastjson低版本反序列化bug/设计缺陷记录

fastjson低版本反序列化bug/设计缺陷记录

时间:2024-07-02 14:53:00浏览次数:14  
标签:fastjson set name 低版本 propertyName FieldInfo 序列化 id

1. 问题场景

 _id正常的赋值

相同的代码我们继续跑

 _id的值被反序列化到id上了???

相同的代码,跑出不一样的反序列化结果,amazing

2.问题探究

2.1 List<FieldInfo>

反序列化时会先创建一个List<FieldInfo>

每一个FieldInfo

List<FieldInfo>的填充方式:遍历Methods[],取出所有的set方法,从set方法里解析字段名并连同对应的set方法构造成一个FieldInfo

 2.2 List<FieldInfo>覆盖问题

构造好FieldInfo后添加到列表的方式

可以看到如果后加进来的FieldInfo满足:①name跟列表里某个存在的FieldInfo.name一致 ②.class类型一致;那么后面加进来的FieldInfo会覆盖掉之前的FieldInfo

回到生成FieldInfo这一步,深入研究name字段赋值逻辑

 

2.3 propertyName (FieldInfo.name)取值方式

 可以看出来,在java代码中

字段_id,其set方法名为set_id(),那么此处得到的propertyName为id;

字段id,其set方法名为setId(),那么此处得到的propertyName也为id;

2.4 初步结论

由于2.2中提到的覆盖和2.3中不同字段取成了相同的propertyName(FieldInfo.name),所以其实最后的List<FieldInfo>中只有一条数据

name = id,method = setId() 或者 name = id,method = set_id()

至于到底是哪一条

 取决于clazz.getMethods()出的Method[]里的set_id()和setId()的顺序,这个顺序在类信息加载进堆内的时候定死了,但是如果 重新启动的话,就会重新排序,所以反序列化时赋值到_id还是id上是在掷骰子。。。

 

 可以看到如果类信息装载一次,的话由于Method[]固定,反序列化受到赋值的字段也是固定的。

3. 问题解决

在set方法上使用JSONField(name=“”)手动指定propertyName,避免List<FieldInfo>存在的覆盖问题

 

4. 更多的bug

fastjson的反序列化其实总体可以分为三步

①解析要赋值的字段名 propertyName

②得到调用的的赋值方法

③从json串里获取待赋的值

我们刚才其实找到了①和②存在一些设计缺陷

但其实③的取值好像也有些奇怪的问题

 可以看到我们仅仅是把json串从{"_id":"aaa","id":null}变为{"id":null,"_id":"aaa"} ,变更了json串里的字段顺序,确得到了更离谱的结果。

标签:fastjson,set,name,低版本,propertyName,FieldInfo,序列化,id
From: https://www.cnblogs.com/JNU-Iot-Longxin/p/18279770

相关文章

  • warmup(php反序列化+SQL注入)
    warmup(php反序列化+SQL注入)题目界面单看题目界面的话推测可能是SQL注入。题解题目涉及三个附近,主要从index.php和conn.php入手。index.php中有两个功能,一个是检查请求中的Cookie,一个是检查用户提交的用户名和密码。检查Cookie首先要求Cookie中的变量是一个数组,......
  • fastjson整理思路
    此处把常用的一些方法,简单做个记录。 做自动化时,我们发送一个请求,返回的是一个字符串。首先我们要把这个字符串转换为json对象  parseObject():将JSON字符串解析为Java对象。 Stringjson="{\"person\":{\"name\":\"Ivy\",\"age\":60}}";JSONO......
  • python json反序列化为对象
    在Python中,将JSON数据反序列化为对象通常意味着将JSON格式的字符串转换为一个Python的数据结构(如列表、字典)或者一个自定义的类实例。虽然Python的标准库json模块不提供直接将JSON数据映射到类的实例的功能,但我们可以通过一些技巧来实现这个需求。以下是一个详细的示例,展示了如何......
  • 面试官:告诉我为什么static和transient关键字修饰的变量不能被序列化?
    一、写在开头在上一篇学习序列化的文章中我们提出了这样的一个问题:“如果在我的对象中,有些变量并不想被序列化应该怎么办呢?”当时给的回答是:不想被序列化的变量我们可以使用transient或static关键字修饰;transient关键字的作用是阻止实例中那些用此关键字修饰的的变量序列化;当......
  • Go自定义数据的序列化流程
    ......
  • FastJson使用详解
    FastJson文章目录第一章FastJson使用详解这一篇就够了第二章FastJsonHttpMessageConverter类的作用与使用详解第三章Jackson使用详解文章目录FastJson文章目录前言一、FastJson是什么?二、使用步骤1.引入库2.序列化和反序列化Java对象3解析JSON字符串4使用注解......
  • fastjson
    fastjson一、fastjson简介fastjson是java的一个库,可以将java对象转化为json格式的字符串,也可以将json格式的字符串转化为java对象提供了toJSONString()和parseObject()方法来将Java对象与JSON相互转换。调用toJSONString方法即可将对象转换成JSON字符串,parseObject......
  • 树的序列化笔记
    \(dfs\)序以\(DFS\)(先根遍历)⾸次访问顺序将节点重新排列。特征:每个顶点在序列中出现恰好⼀次(废话)⽗节点排在⼦节点前⾯(废话)每棵⼦树都占据序列的⼀个区间欧拉序记录\(DFS\)递归/回溯时依次经过的所有点。特征:每个点出现次数=度数(根多1次)相邻点深度差1\(LCA(x,y)=\)......
  • 序列化和反序列化pickle和json 模块
    importpicklehello='helloworld'data=pickle.dumps(hello)#pickle.dumps把任意对象序列化成一个bytes(字节数)print(data)data1=pickle.loads(data)#pickle.loads将字节数反序列化print(data1)importjsondata={'hello':123,'nihao':'word&......
  • [LCTF 2018]bestphp's revenge php原生类的利用以及php_session反序列化相关
    今天继续来一道反序列化的题目。点击查看代码<?phphighlight_file(__FILE__);$b='implode';call_user_func($_GET['f'],$_POST);session_start();if(isset($_GET['name'])){$_SESSION['name']=$_GET['name'];}var_dump......