Fastjson反序列化浅析(一)
字数 1529 2025-08-18 11:37:15
Fastjson反序列化漏洞分析(一)
一、Fastjson基本概念
Fastjson是一个Java语言的JSON解析库,主要功能是将JSON字符串解析为Java对象。其基本使用方式如下:
String s = "{\"param1\":\"aaa\",\"param2\":\"bbb\"}";
// 解析JSON
JSONObject jsonObject = JSON.parseObject(s);
// 原生打印
System.out.println(jsonObject);
// 获取指定的键值
System.out.println(jsonObject.getString("param1"));
Fastjson支持将JSON字符串解析为JavaBean对象:
String s = "{\"age\":\"18\",\"name\":\"yexing\"}";
Person person = JSON.parseObject(s, Person.class);
System.out.println(person.getName());
二、Fastjson的关键特性
Fastjson有一个特殊特性:可以通过@type字段指定要反序列化的类:
String s = "{\"@type\":\"org.example.Person\", \"age\":\"18\", \"name\":\"yexing\"}";
JSONObject jsonObject = JSON.parseObject(s);
System.out.println(jsonObject);
这个特性允许客户端控制反序列化的类,从而可能导致安全问题。
三、Fastjson反序列化流程分析
1. 整体流程
JSON.parseObject()主要做两件事:
parse()- 序列化操作,将字符串解析为对象(调用setter)JSON.toJSON()- 将对象转为字符串(调用getter)
2. 解析流程细节
-
初始解析:
- 调用
DefaultJSONParser()创建默认JSON解析器 - 根据JSON字符串的字符进行解析(通过switch控制)
- 调用
-
处理@type字段:
- 当解析到
@type字段时,表示需要进行Java反序列化 - 调用
loadClass()加载指定类:- 先尝试从mappings缓存中加载
- 未找到则使用APPClassLoader加载
- 当解析到
-
获取反序列化器:
- 首先从缓存中查找反序列化器
- 不在内置类型中则通过
getDeserializer()获取 - 检查类名是否在黑名单中(1.2.24以前的黑名单主要基于性能考虑)
- 最终通过
createJavaBeanDeserializer()创建JavaBean反序列化器
-
JavaBean信息构建:
- 调用
JavaBeanInfo.build():- 第一个循环:遍历获取setter方法
- 第二个循环:遍历public字段
- 第三个循环:遍历getter方法
- 返回包含所有信息的JavaBeanInfo对象
- 调用
-
实例创建与属性设置:
- 通过反射调用构造函数创建实例
- 调用
parseField()和setValue()设置属性值(调用setter)
-
toJSON处理:
- 调用
toJSON()将对象转为字符串 - 通过
getFieldValuesMap()获取字段值 - 调用
getter.getPropertyValue()获取属性值(调用getter)
- 调用
四、关键安全点分析
-
@type字段控制:
- 允许客户端指定任意类进行反序列化
- 这是Fastjson反序列化漏洞的根本原因
-
方法调用:
- 自动调用setter和getter方法
- 可能触发危险操作
-
黑名单机制:
- 1.2.24版本前的黑名单不完善
- 主要基于性能考虑而非安全考虑
-
动态类加载:
- 通过
asmEnable开关控制动态类创建 - 可能被利用来加载恶意类
- 通过
五、漏洞利用条件
- 存在只有getter没有setter且返回特定类型(Map/Collection等)的方法
- 当满足这个条件时:
getOnly标志会被设为trueasmEnable会被设为false- 使用可调试的反序列化器
六、防御建议
- 升级到最新版本Fastjson
- 严格限制反序列化的类(使用白名单)
- 禁用
@type特性(通过ParserConfig.getGlobalInstance().setAutoTypeSupport(false);) - 避免在getter/setter中执行危险操作
七、总结
Fastjson的反序列化漏洞主要源于其灵活的@type特性和自动调用getter/setter的设计。理解其内部解析流程对于分析和防御相关漏洞至关重要。开发者应当谨慎使用Fastjson的反序列化功能,特别是在处理不可信的JSON输入时。