Mikko7头像
关注

Jetty 官方叫我升到 9.4.60 修 CVE-2026-2332,可 Maven Central 上根本没有这个版本,怎么办?

一条你修不掉的告警

依赖扫描报出来:org.eclipse.jetty:jetty-http,CVE-2026-2332,high。你照例去查官方安全公告,它给了升级建议。你按那个版本号去 Maven Central 下 —— 404

这不是你手滑打错版本号。这篇要讲的就是:对 Jetty 的 9.4 / 10 / 11 三条老线,官方公告叫你升的那个修复版本,在公开仓库里根本不存在,而这件事扫描工具不会告诉你。

先把 2026 年这五条摆出来,它们散在四个模块上:

CVE模块严重度一句话
CVE-2026-2332jetty-httphigh / CVSS v3 7.4⭐ 主打:chunked 编码里 quoted-string 内的 \r\n 被当成分块头结束 → 请求走私(CWE-444)
CVE-2026-5795jetty-jaspihigh / v3 7.4JASPI 的 ThreadLocal 未清理 → 越权
CVE-2026-6790jetty-servermedium / v3 5.3HTTP/2·3 的 Host 与 :authority 混淆
CVE-2026-10050jetty-securityhigh / v4 8.7Digest 认证的 ISO-8859-1 处理
CVE-2025-11143jetty-httplow / v3 3.7URI 解析差异

注意评级:6790 是 medium、11143 是 low。别被「五条 CVE」这个数字唬住统称高危。 而且五条里真正受影响面站得住的只有主打的 2332 —— 后面会说为什么。

主打这条为什么是真的:走私落在默认解析路径上

CVE-2026-2332 是 “Funky Chunks” 请求走私的一个新变种:Jetty 的 HTTP/1.1 解析器在遇到 chunk 扩展的 quoted-string 里的 \r\n 时,把它当成了分块头的结束,而不是报错。

我担心的是它会不会像有些漏洞那样,要开某个特定功能才触发 —— 那样受影响面就很小。于是用修复 commit 和真 jar 做了构件级核对:

  • gh api ...compare/jetty-12.0.32...jetty-12.0.33:改动集中在 jetty-http/.../HttpParser.java(+346/−156),外加新增测试 ChunkSizeExtensionTest。12.1.6→12.1.7 是同款。
  • HttpParser 是 Jetty 的 HTTP/1.1 解析主状态机,不是任何可选 handler。HttpParser.class 在 9.4.58 / 11.0.26 / 12.0.32 的 jar 里全都在。
  • javap -p HttpParser:_chunkLength / isChunking() / MAX_CHUNK_LENGTH 这些成员由 parseNext() 无条件驱动,没有任何开关。advisory 自带的 PoC 也只是一个普通的 POST / HTTP/1.1Transfer-Encoding: chunked

结论:这条走私落在 HTTP/1.1 解析主路径上,不需要开任何特定功能,受影响面就是 ServerConnector 本身。

但危害有前提,这里必须说清楚: 请求走私要害的前提是你的 Jetty 前面还有一个前端代理 / 负载均衡,而两者对同一个请求的解读不一致。裸跑一个 Jetty、前面什么都没有,讲不出攻击故事。这也是官方给它 7.4 而不是满分的原因。本文证明的是「这段代码在你的构件里、走的是默认路径」,不是「你一定会被打穿」。

核心:9.4 / 10 / 11 老线的公开修复版不存在

这是本文最硬的一条。

官方安全页 https://jetty.org/security.html 对 CVE-2026-2332 那一行写的是:

修复版:12.0.33, 12.1.79.4.60, 10.0.28, 11.0.29 see details for availability

那句 “see details for availability” 是一个超链接,指向商业支持。也就是说:12 线给了公开版本号,而 9.4 / 10 / 11 老线的版本号被放进了「看详情谈可用性」里。

我把这些版本号逐个拿到 Maven Central 上 HEAD 探测:

版本Maven Central
jetty-http 12.0.33(12.0 线修复版)200 —— 在
jetty-http 12.1.7(12.1 线修复版)200 —— 在
jetty-http 9.4.60404
jetty-http 10.0.28404
jetty-http 11.0.29404
jetty-http 9.4.58.v20250814(老线最后一个公开版)200 —— 在

最后一行很关键:老线的最后一个版本仍然在 Central 上,404 的只是那个「修复版」本身 —— 不是整个坐标下架了,是那个补丁版本没往公开仓库发。

而且修复版可得性其实有三种情况,不是非黑即白:

  • 有公开修复版:12.0 / 12.1 线,升就是了;
  • 官方点名了但 Central 404:9.4/10/11 的 2332、5795、10050 —— 就是 “see details for availability”;
  • 官方连版本号都没给:9.4/10/11 的 6790 和 11143,advisory 的 first_patched_version 直接是空。

⚠️ 到此为止都是可复现的事实。至于官方为什么这么做,我不替它说 —— 12 线仍在正常更新,这不是「Jetty 不发版了」;而「把补丁藏起来卖钱」是动机推断,一手源没这么写。事实就是:照公告去升老线,你会升到一个公开渠道拿不到的版本号。

被困在老线上的,主要是这几个 Spring Boot 版本

Jetty 在国内是少数派(大多数 Spring Boot 用的是 Tomcat)。但如果你当年选了 spring-boot-starter-jetty,你带进来的默认 Jetty 版本是这样的(从每个 spring-boot-dependencies-<版本>.pom<jetty.version> 实读):

Spring Boot默认 Jetty落在哪条线有没有公开修复版
2.7.189.4.53.v202310099.4 老线❌ 老线,see details
3.0.1311.0.1811 老线❌ 老线,see details
3.1.1211.0.2111 老线❌ 老线,see details
3.2.x – 3.4.x12.0.9 – 12.0.1512.0 线✅ 升到 12.0.33+ 即可(公开有)

也就是说:还在 Boot 2.7 / 3.0 / 3.1 且用 Jetty 的项目,默认落在无公开修复版的老线上;要拿到公开修复版,得跨大版本升到 Boot 3.2+(12 线)—— 那是迁移,不是打补丁。3.2 以上的项目在 12 线内升个小版本就行。

(如果你在 pom 里自己覆盖过 jetty.version,以你覆盖的为准 —— 这也正是工具直接扫构件、不看 Boot 版本号的原因。)

判据为什么不能靠「jar 里有没有某个类」

姊妹项目 tomcat-line-check 的判据是「jar 里有没有某个修复类」,因为 Tomcat 那次修复新增了一个类

Jetty 这次不行。上面说过,2332 的修复改的是 HttpParser 的方法体,isChunking() 这些成员在修复前后都在,没有新增类可查。所以判据只能是:

你的完整坐标 + 版本线,命中哪几条 CVE;以及官方点名的修复版,在 Maven Central 上到底存不存在。

还有个坑:5795(jaspi)和 10050(security)在 12.x 里模块名会裂开成 jetty-ee10-jaspi / jetty-ee9-security 这种,9.4/10/11 才是光 jetty-jaspi / jetty-security。判定必须按完整坐标,短名一刀切会漏。

一个把这些做完的小工具

jetty-line-check:扫目录 / jar / war / Spring Boot fat jar(读的是实际打进去的构件,不是 pom),读出每个 Jetty 模块的完整坐标和版本,对照判定表给出「命中哪几条 CVE、每条的修复版是公开有 / Central 404 / 官方没给」。

https://github.com/xiaoqiMikko/jetty-line-check

单 jar、零运行时依赖、完全离线、Java 17+。

java -jar jetty-line-check-0.1.0.jar /path/to/jetty     # 解压部署的 Jetty(扫 lib/*.jar)
java -jar jetty-line-check-0.1.0.jar app.war            # war
java -jar jetty-line-check-0.1.0.jar app.jar            # Spring Boot fat jar
java -jar jetty-line-check-0.1.0.jar --table            # 只看五条 CVE × 模块 × 版本线的判定表
java -jar jetty-line-check-0.1.0.jar --utf8 ...         # Windows 控制台中文乱码时加

判定表不是手抄的:tools/gen_table.py 从五条 advisory 加 Maven Central 真 jar 探测生成,七组断言(阳性对照 / 核心主张 / 老线终版 / 哨兵 / 主打结构 / 裂模块 / 评级)不过就拒绝出表。发文前的 tools/recheck_before_publish.py 会把上面这些主张重跑一遍。

退出码:0 = 每个文件都真读进去了 · 2 = 用法错误 · 4 = 有文件读不动。4 故意不是 0 —— 一个损坏 / 下载不全的 jar,不能在 CI 里安静地变成「没发现问题」。

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

  • 不是「扫描工具报不出来」。 五条都是 reviewed 的 advisory,报是报得出来的。本文讲的是报出来之后,叫你升的那个老线版本号在公开仓库里不存在。
  • 不是「Jetty 不发版了」。 12.0 / 12.1 线仍在更新,公开修复版都在 Central 上。
  • 不是「任何 Jetty 应用都会被打穿」。 主打那条是请求走私,危害要前置代理与解析分歧,见上文。
  • 不替官方说动机。 “see details for availability” 是官方页面的原话,到此为止。
  • :9.4 / 10 / 11 这三条 EOL 老线,官方点名的多条 CVE 修复版在 Maven Central 上是 404;主打的 CVE-2026-2332 走私落在默认解析路径上,受影响面是 server 本身;工具帮你按实际构件判到「中哪几条、能不能公开升」这一步。

如果你发现哪里错了,欢迎直接开 issue —— 这类文章的价值全在准确性上。


转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/P191117/article/details/165121289

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--