Spring MVC + FastJSON:反序列化攻击是怎么一步步发生的?

Spring MVC + FastJSON:反序列化攻击是怎么一步步发生的?

🧠 Spring MVC 是怎么悄咪咪地调用了 FastJSON 来反序列化的?

🌟 一句话总结:

你只写了一句 @RequestBody Object data,Spring 就自动帮你用 FastJSON 把请求体中的 JSON 字符串,转成了一个 Java 对象。

听起来很贴心对吧?但也正是这种“贴心”,有可能打开了安全漏洞的大门。


🔄 整体流程分析

1️⃣ 用户发起一个 HTTP POST 请求

 POST /api/parse
 Content-Type: application/json
 ​
 {
   "name": "Alice",
   "age": 18
 }

2️⃣ Spring 收到请求 → 找对应的 Controller 方法

Spring 找到了你写的这个方法:

 @PostMapping("/api/parse")
 public void parseJson(@RequestBody Object data) {
     log.info(data.toString());
 }

它看到参数上有 @RequestBody,就知道你想把请求体里的 JSON 转成一个 Java 对象。


3️⃣ Spring 去找“转换器”:HttpMessageConverter

这时候,Spring 会使用一系列叫做 HttpMessageConverter 的组件,把 JSON 转换成 Java 对象。

🧩 默认情况下 Spring 用的是 Jackson,但如果你配置了 FastJSON,比如:

  • 引入了 fastjson 的依赖;
  • 配置了 FastJsonHttpMessageConverter

那么 Spring 就会优先选用 FastJSON。


4️⃣ FastJSON 执行反序列化

FastJSON 会把 JSON 字符串“翻译”成 Java 对象,比如:

 {
   "@type": "com.evil.HackerClass",
   "cmd": "calc.exe"
 }

如果你写的是 Object data,FastJSON 就必须猜猜这是啥类型,那它就会启用 autoType 机制 —— 只要 JSON 里写了 @type,它就尝试去加载那个类。

如果这个类本身就能在构造时干点坏事(比如 RCE),就可能触发攻击链!


🚨 安全风险出现在哪?

@RequestBody 用在 Object 类型上,就是给了 FastJSON 自由反序列化的权限,攻击者就可能构造恶意对象骗它执行危险操作。


🔬 逐行分析一下:

 @PostMapping("/api/parse")
  • 创建一个 POST 接口,路径是 /api/parse
 public void parseJson(@RequestBody Object data)
  • 让 Spring 自动从请求体中解析 JSON;
  • 类型是 Object —— 这意味着 FastJSON 不知道你到底想反序列化成什么,就会试图自己“猜”。
 log.info(data.toString());
  • 打印出反序列化后的对象;
  • 如果对象是恶意构造的,调用 toString() 甚至可能就会触发攻击。

🛡 修复建议

✅ 1. 明确参数类型

不要用 Object,换成明确的类,比如:

 public void parseJson(@RequestBody UserDTO data)

✅ 2. 禁用 autoType

 ParserConfig.getGlobalInstance().setAutoTypeSupport(false);

或者设置白名单:

 ParserConfig.getGlobalInstance().addAccept("com.yoursafeapp.model.");

✅ 3. 使用最新版 FastJSON

老版本(1.2.68 以下)安全问题较多,尽量升级。


✅ 4.修复示例:

 @Data
 public class UserDTO {
     private String name;
     private Integer age;
 }
 ​
 @PostMapping("/api/parse")
 public void parseJson(@RequestBody UserDTO data) {
     log.info("接收到用户数据:name={}, age={}", data.getName(), data.getAge());
 }

这样就 明确告诉 FastJSON 应该反序列化成 UserDTO,不会再去“瞎猜”别的类,也自然不会轻易触发攻击链。


🎯 总结

你写了 Object data,Spring 帮你找来了 FastJSON,FastJSON 又热情地帮你反序列化了一个未知用户传入的Json字符串,结果这个用户把炸弹传进来了,那么就导致了一系列问题。

🔍整体流程:


 用户发送 HTTP POST 请求
           |
           v
  ┌───────────────────────────┐
  │ Spring 收到请求          │
  └───────────────────────────┘
           |
           v
  ┌───────────────────────────┐
  │ 匹配 Controller 方法      │
  │ @PostMapping("/api/parse")│
  └───────────────────────────┘
           |
           v
  ┌──────────────────────────────┐
  │ 发现参数使用 @RequestBody    │
  └──────────────────────────────┘
           |
           v
  ┌───────────────────────────────────────────┐
  │ 交给 HttpMessageConverter 转换器处理      │
  └───────────────────────────────────────────┘
           |
           v
  ┌─────────────────────────────────────────────┐
  │ 判断使用哪个 JSON 解析器(默认 Jackson)   │
  │ ✔ 如果配置了 FastJsonHttpMessageConverter │
  │ → 切换为 FastJSON                         │
  └─────────────────────────────────────────────┘
           |
           v
  ┌───────────────────────────────────────────────┐
  │ FastJSON 开始反序列化 JSON 字符串              │
  │ 如果类型为 Object,启用 autoType 猜类名        │
  │ JSON 中如含 "@type" 字段 → 反射加载该类         │
  └───────────────────────────────────────────────┘
           |
           v
  ┌──────────────────────────────────────┐
  │ 反序列化成功 → 调用 log.info(...)   │
  │ 如果是恶意类,可能已触发远程代码执行 │
  └──────────────────────────────────────┘

🧨 风险点:

  • @RequestBody Object data 让 FastJSON 自由反序列化;
  • 启用 autoType 且未设置白名单,风险极高;
  • 攻击者可以构造恶意 payload(带 @type)实现远程命令执行。

© 版权声明
THE END
喜欢就支持一下吧
点赞13赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容