🧠 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
)实现远程命令执行。
暂无评论内容