jackson-databind 升到 2.21.6 就安全了吗?jackson-core 是另一个坐标,它那条 high 全局库至今没收

先说结论

如果你的项目里有 com.fasterxml.jackson.core:jackson-core(几乎一定有,jackson-databind 会把它带进来),

而版本落在下面任一区间,你中了一条 high,而 Dependabot 不会告诉你:

坐标 受影响 升到
com.fasterxml.jackson.core:jackson-core >= 2.16.0, <= 2.18.9 2.18.10
同上 >= 2.19.0, <= 2.21.5 2.21.6
同上 >= 2.22.0, <= 2.22.1 2.22.2
tools.jackson.core:jackson-core(Jackson 3) >= 3.0.0, <= 3.1.5 3.1.6
同上 >= 3.2.0, <= 3.2.1 3.2.2

编号是 CVE-2026-68498(GHSA-649p-m576-vr99,high 7.5),FasterXML 2026-09-12 发在自己仓库的 Security 页上。

截至 2026-09-21 ,GitHub 全局漏洞库按这个编号查仍是 404 ------ Dependabot 和 OSV 读的就是那个库。

有一件事要先说清楚 :这不是「Jackson 又出了个 RCE」。它是内存耗尽型 DoS ,

而且只有从字符输入解析时才中。下面每一节都会把边界写死。

为什么升了 databind 还会中

jackson-databindjackson-core两个独立发版的坐标 ,只是通常一起升。

jackson-core 在 Maven 生态里的被依赖数甚至比 databind 还高 ------ 很多项目会直接声明 它,

也有不少项目用 dependencyManagement 单独钉住过它的版本。

于是有一种很常见的状态:jackson-databind 已经是 2.21.6,jackson-core 还停在 2.21.5。

你的 SCA 面板全绿,因为它按 jackson-databind 查,而这条洞不挂在那个坐标上。

这和「同一个 Netty 版本号、不同模块的『修完』版本不一样」是同一类问题:

你脑子里的单位是「Jackson」,而 advisory 的单位是「坐标」。

洞本身:一道校验跑得太晚

StreamReadConstraints 里有两个独立的上限:

复制代码
maxStringLength  默认 100,000,000   ------ 管字符串「值」
maxNameLength    默认      50,000   ------ 管对象属性「名」

差了约 2000 倍maxNameLength 的存在意义就是:哪怕你允许很大的字符串值,

也别让一个属性名吃掉那么多内存。

字节输入路径做对了。UTF8StreamJsonParser 扫属性名时,每次扩缓冲都会调

ParserBase._growNameDecodeBuffer(),里面就有一次 validateNameLength() ------

所以超长的名字在分配了几十 KB 之后就被拒掉了。

字符输入路径没有。ReaderBasedJsonParser._parseName2() 把名字累积进 TextBuffer,

TextBuffer.finishCurrentSegment() 调的是 validateStringLength() ------

字符串上限,不是名字上限 。真正的 validateNameLength() 要等整个名字扫到闭引号、

进了 CharsToNameCanonicalizer.findSymbol() 才跑。

那时候内存已经分配完了。

官方公告里贴了实测输出,两条路径的差别一眼可见:

复制代码
[bytes]  Name length (65536) exceeds the maximum allowed (50000, ...)
[reader] Name length (5000000) exceeds the maximum allowed (50000, ...)

字节路径在缓冲涨到 65,536 时就抛了;字符路径把整个 5,000,000 字符的名字读完了才抛 ------

异常信息里那个数字本身就是证据。不设人为上限的话,这条路径能一直缓冲到 maxStringLength,

也就是约 1 亿字符(约 200MB),而且 maxDocumentLength 默认是关的 (-1),没有别的东西兜底。

一个请求几百 MB,几个并发就够把堆打爆。不需要任何误配置。

你到底中不中:一句话判据

  • String / Reader / char[] 解析不可信 JSON →
  • byte[] / InputStream 解析,或用非阻塞(async)解析器 → 不中

坏消息是,第一种恰好是最常见的写法之一 ------ HTTP 请求体先读成 String

objectMapper.readValue(body, X.class),这行代码到处都是。

我自己的工具也漏了这一维

9 月 14 日我发过一个 jackson-check,扫 jar 判「你中哪几条、哪几条 Dependabot 看不见」。

它的判定表整张只有一个 artifactId:jackson-databind

所以它对 jackson-core 这 7 条公告是系统性失明的 ,而且不会报任何错 ------

它只是安静地跳过所有 jackson-core-*.jar「没扫到」和「你很安全」在报告里长得一模一样。

这一版(v0.3.0)把判定粒度从「advisory × groupId × 区间」改成

「advisory × groupId × artifactId × 区间」,判定、求交集、「未扫到这个坐标」

全部以完整坐标为键。顺带把 jackson-core 那 7 条公告都收了进来。

⚠️ 上一版给 jackson-databind 的答案(2.18.10 / 2.21.6 / 2.22.2 / 3.1.6 / 3.2.2)没有错 ,

错的是维度 ------ 它只回答了一个坐标的问题。

工具

bash 复制代码
java -jar jackson-check.jar ./target ./src

零依赖单 jar,不联网,判定表内置。扫普通 jar、Spring Boot fat jar(BOOT-INF/lib/)、

传统 WAR(WEB-INF/lib/),坐标从 META-INF/maven/**/pom.properties 读,读不到才退回 MANIFEST 和文件名。

下面是 09-21 的真实输出 ------ databind 已经升到 2.21.6,core 还停在 2.21.5:

复制代码
【一】扫到的 jackson 构件(databind / core)
  com.fasterxml.jackson.core:jackson-core        2.21.5        (版本来源:pom.properties)
  com.fasterxml.jackson.core:jackson-databind    2.21.6        (版本来源:pom.properties)

【三】判定结果
  你的版本落在受影响区间内的:1 条
  其中 Dependabot 会报的:0 条(GitHub 全局漏洞库已收录)
  🔴 其中 Dependabot 看不见的:1 条(GitHub 全局漏洞库还没收录,按 GHSA 号查 404)

    CVE-2026-68498         high 7.5 Delayed maxNameLength enforcement for char-backed input ...
        坐标   com.fasterxml.jackson.core:jackson-core · 你的版本 2.21.5 · 受影响 2.19.0 <= 版本 <= 2.21.5
        条件   仅当从 String / Reader / char[] 解析不可信 JSON;从 byte[] / InputStream 解析不受影响
        未找到 CharInputParse
        说明   未在你的源码里找到触发条件(CharInputParse) ------ 🔴 这不等于安全

【四】该升到哪个版本(逐条求交集,不是照抄某一条 advisory)
  com.fasterxml.jackson.core:jackson-core
      现在 2.21.5  →  升到 2.21.6
      盖住 1 条;把目标顶到这么高的是 CVE-2026-68498

退出码:0 版本没中 · 2 版本中但源码里没找到触发条件 · 3 触发条件也成立 · 4 有文件读不动

最后那个 4 值得单说。ZipInputStream 遇到不是 zip 的文件不抛异常,只给零条目 ------

扫描会正常走完、输出「没找到」、退出码 0。「我读不动它」于是变成了「你是安全的」。

所以这里单独占一个退出码。

🔴 工具做不到的那一半

它判得了 jar 版本,判不了你的调用方式。

readValue(body, X.class) 里的 bodyString 还是 byte[],文本扫描看不出来 ------

那是个变量。工具只认得出显式写法(比如 new StringReader(...)),

所以报告里那句「未在你的源码里找到触发条件」后面永远跟着一句 「🔴 这不等于安全」

真要确认,只有两条路:看一眼你那几处反序列化入口的实参类型;或者直接升版本。

升版本更便宜。

这篇能证明什么、不能证明什么

:CVE-2026-68498 在 FasterXML 仓库公开可查;截至 09-21 全局库按编号查仍 404;

五个修复版在 Maven Central 上都拿得到;字节码实测 validateNameLength 的调用

只在修复版的 ReaderBasedJsonParser 里有、中招版里没有 (2.18.9→2.18.10、

2.21.5→2.21.6、3.1.5→3.1.6 三条线都复现了)。

不能 :不能证明你一定会被打 ------ 得看你是不是从字符输入解析不可信 JSON;

不是说 Dependabot 对 jackson-core 全瞎 ------ 那 7 条里其余 6 条都已收录、正常告警,只有这一条没有 ;

也不是说 GitHub 永远不会收录它,AsyncHttpClient 那批就是晚了 39 天才收的。

工具、判定表生成脚本、发文前复核脚本都在仓库里(Apache-2.0):

https://github.com/xiaoqiMikko/jackson-check ------ 可直接下载的 jar 在 Release v0.3.0

相关推荐
知守观1 小时前
Spring AOP + 自定义注解实现三角色权限控制:从设计到落地的完整方案
后端
LONGZETECH1 小时前
一线职教实测:风光 580 汽车故障诊断仿真系统,破解实车实训四大核心痛点
人工智能·学习·安全·架构·汽车
Ticnix1 小时前
我调了三个月 overlap=50,它其实一次都没生效
后端·python·agent
Java_AI工程师1 小时前
90%的人写Function Calling,只写了"把参数传给工具执行"这一步,剩下的参数校验、错误重试、超时控制、结果格式化,全是空白。
java·人工智能·程序员
斯维赤1 小时前
LangChain4j 入门教学(Java 后端狂喜版
java·后端
数据库小学妹1 小时前
MySQL库存扣减实战:原子UPDATE、分桶方案与锁范围分析
数据库·后端·mysql
旺仔不是程序员1 小时前
LIMIT 1:PostgreSQL 只取一行的高效查询姿势
数据库·后端·sql
知守观1 小时前
Java POI 动态二级表头导出实战:并集计算 + 合并单元格 + 冻结列的完整实现
后端
Java_2017_csdn1 小时前
Java 8 Stream API 中的 map 和 flatMap 详解
java