AutoType 安全与修复建议
Fastjson 是一个高性能的 JSON 处理库,但它的 AutoType 功能(自动类型识别)曾引发严重的安全问题。本文将解释 AutoType 的原理、风险,并提供修复建议。
什么是 AutoType?
AutoType 是 Fastjson 的一个特性:在反序列化时,无需显式指定要转换的 Java 类型,而是根据 JSON 中的 @type 字段自动识别并创建实例。
// JSON 字符串中包含 @type 字段
String json = "{\"@type\":\"com.example.User\",\"name\":\"Alice\",\"id\":1}";
// 可以直接反序列化为 User 对象
Object obj = JSON.parse(json); // 默认启用 AutoType 时,会识别 @type
AutoType 的安全风险
AutoType 最大的问题是 可能导致远程代码执行(RCE)。攻击者可以通过构造特殊的 JSON 字符串,让 Fastjson 反序列化时调用危险方法,例如:
{
"@type": "java.net.InetAddress",
"val": "malicious-server.com"
}
更严重的例子是结合某些 Java 库(如 fastjson 的 AutoType 白名单绕过)执行任意命令。历史上多个 Fastjson 版本因此被爆出高危漏洞(如 CVE-2022-25845)。
核心问题:Attackers 可以通过 @type 指定任意类的构造函数或 setter,如果该类在类路径中且包含不安全逻辑,则能实现攻击。
安全修复建议
禁用 AutoType(最推荐)
在 JSON.parse / parseObject 时显式指定目标类型,避免使用 @type。
// 安全方式:指定目标类型
String json = "{\"name\":\"Alice\",\"id\":1}";
User user = JSON.parseObject(json, User.class); // 不依赖 @type
如果必须使用 JSON.parse(String),可以通过配置全局禁用 AutoType:
ParserConfig.getGlobalInstance().setAutoTypeSupport(false); // 禁用自动类型
白名单模式(如必须 AutoType)
如果业务需要 AutoType,只允许特定的安全类。
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
ParserConfig.getGlobalInstance().addAccept("com.example.myapp."); // 只接受该包下的类
或者使用安全黑名单方式(不推荐,因为攻击者总能寻找新类):
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
// 建议使用白名单,而不是黑名单
升级到最新版本
快速修复漏洞的最佳方法是升级到 Fastjson 的最新安全版本(目前建议 >= 1.2.83)。例如:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version> <!-- 检查最新版本 -->
</dependency>
最新版本通常已修复已知的 AutoType 漏洞。
使用替代库
如果业务对安全要求极高,可以迁移到更安全的 JSON 库,如 Jackson(需正确配置)或 Gson(默认不开启自动类型识别)。
实际修复示例
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
public class SafeFastjsonDemo {
public static void main(String[] args) {
// 方案一:禁用 AutoType
ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
// 方案二:使用白名单(假设业务需要)
// ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
// ParserConfig.getGlobalInstance().addAccept("com.example");
// 安全的反序列化:指定类型
String userJson = "{\"name\":\"Tom\",\"age\":25}";
User user = JSON.parseObject(userJson, User.class);
System.out.println(user.getName());
// 永远不要使用未校验的 JSON.parse(String) 且不指定类型
// 例如:Object obj = JSON.parse(userJson); // 危险!
}
}
总结
作为开发者,你的首要任务是禁用或严格限制 AutoType 的使用。结合升级库版本和代码审查,可以极大降低安全风险,反序列化时永远不要信任外部输入。

