2026-10-06,Netty 同时放出 4.2.19.Final 与 4.1.139.Final。官博与 GitHub Release 都写成缺陷修复加安全发布;4.2 线列出 16 项安全修复,4.1 线列出 13 项。对依赖扫描习惯按 CVE 编号告警的团队,更关键的一句在正文中间:因 CVE 基础设施压力过大,这批报告发布时一个编号都没拿到,公告会不带 CVE 编号发出,扫描器可能漏报。
本稿只按官博、Release 与 Maven Central 可核验内容写作(核对时间 2026-10-07)。不编 CVE、不编严重级别;本批若尚未挂出对应 GHSA,就标明「尚未挂出」,不把更早周期的 advisory 硬套到本次版本上。
官方列出了什么
两份公告的安全列表格式一致:左侧是 CVE-2026-XXXXX
占位,右侧是问题类型加 io.netty:
模块坐标。把条目数点清楚:4.1.139.Final 共 13 条;4.2.19.Final 在相同 13
条之外多写了 HTTP/3 与两处 io_uring,合计 16 条。
共有部分按官方用词归纳如下(模块名保持原文坐标)。数字单位也按原文:这是「条目数」,不是「CVE 数」,因为编号尚未分配。
HTTP 与走私相关主要落在 netty-codec-http:improper CRLF
neutralization(request/response smuggling)、另有一条 request/response
smuggling、origin validation error,以及 unbounded resource
consumption。也就是说,公告把 CRLF 注入与请求响应走私、源校验错误和 HTTP
侧资源耗尽都点到了同一模块上,但分成了多条独立条目,不要自行合并成「一个洞」或「一个
CVE」。做影响面评估时,可以按模块收敛排查范围,但计数仍应与官方列表对齐:4.1
为 13,4.2 为 16。
协议与路由方面:netty-codec-http2 是 unbounded resource
consumption;netty-handler 列出 SNI routing bypass 与
improper access control;netty-handler-ssl-ocsp 是
time-of-check/time-of-use error(TOCTOU)。DNS、XML、以及 codec
基座上的资源耗尽分别写在
netty-codec-dns、netty-codec-xml、netty-codec-base。另外还有
netty-codec-haproxy 的 parser desync,以及
netty-codec-socks 的 input misinterpretation。
4.2.19 多出来的三项只在 4.2 公告与 4.2 Release
里出现:netty-codec-http3 的 unbounded resource
consumption;netty-transport-classes-io_uring 的
use-after-free;netty-transport-native-io_uring 的 memory
leak。走 HTTP/3 或启用了 io_uring transport 的部署,不能只看 4.1 线的 13
项清单;纯 4.1 用户则不必把这三项当成自己线路上的必选项,但 EOL
时间表仍适用。
原文没有在这两篇发布说明里给出真实 CVE 编号,也没有写
CVSS。阅读时按「模块 + 官方类型描述」对齐即可,不要把占位符
CVE-2026-XXXXX 当成已分配编号。
为什么说「暂无 CVE」是读者增量
官方原句如下(两篇公告措辞一致):
Note that due to overwhelming strain on the CVE infrastructure, we have not gotten a single CVE number assigned to these reports in time for our release. The advisories will be published without.
漏洞已经写进发版说明,只是公共 CVE
编号流程没赶上报发布节奏。发版说明里已经把问题类型和模块写清楚了,只是公共
CVE ID 还空着。实际后果通常是:发版当天(甚至之后一段时间)NVD / 各类
CVE 库里搜不到对应条目;只认 CVE 字段的
SCA、镜像扫描、软件成分清单对账,仍可能显示通过;内部变更单若写成「无
CVE 不给升」,会被流程本身挡住。更稳妥的门禁是版本比较:4.1 线升到
4.1.139.Final,4.2 线升到 4.2.19.Final。本稿用 Maven Central
交叉核对过,io.netty 相关构件已能解析到这两个版本。
安全公告有时晚于版本说明,这是发稿前要默认接受的节奏。本稿核对时(2026-10-07),打开 netty/netty Security Advisories 并检索与 4.2.19 / 4.1.139 相关的公开材料,尚未看到与上述 16/13 项一一对应、并标明 patched versions 为 4.2.19.Final / 4.1.139.Final 的新 GHSA。仓库里能看到的较早 GHSA 属于此前发布周期,修复版本也更早,不能当作本批的编号表,本文也不转抄那些 id,以免读者误以为「本批已经有编号」。后续若挂出 GHSA,应以 advisory 原文中的 GHSA id、影响模块与修复版本为准;在那之前,不要断言「永远没有编号」,也不要凭猜测填 CVE。
对排障同事可以多说一句:若扫描报告仍显示旧版 Netty 的历史 CVE 已修复、却对本次条目沉默,优先核对依赖树里的版本号,而不是等 CVE 库补齐后再动手。
FileUpload.setContentType
与 4.1 EOL
两份公告都单独点出行为变化:以前
FileUpload.setContentType
不校验入参;现在若给定字符串不像合理的 MIME content type,会抛出
IllegalArgumentException(官博拼成
IllegaalArgumentException,Java 标准异常类名是
IllegalArgumentException)。这不是安全列表里的占位 CVE
条目,但是升级后可见的 API 行为变化。multipart 上传、自定义
Content-Type、测试里故意塞奇怪 MIME
的路径,都值得跑一遍;原先「写进去就算了」的代码,升级后可能直接失败。
同一段还写明:Netty 4.1 将于 2027-07-01 End-of-Life。日期来自官博原文(July 1st, 2027)。仍在 4.1 的项目,短期至少应到 4.1.139.Final;中期要规划迁 4.2,否则 EOL 之后连同类安全修复通道都会收窄。
排查命令与升级目标
先确认 classpath 上实际解析到的 io.netty 版本。
Maven:
mvn dependency:tree -Dincludes=io.nettyGradle(把构件名换成你最关心的那一个,例如
netty-handler):
./gradlew dependencyInsight --dependency io.netty:netty-codec-http --configuration runtimeClasspath判定规则简单:当前是 4.1.x 且低于 4.1.139.Final,升到 4.1.139.Final;当前是 4.2.x 且低于 4.2.19.Final,升到 4.2.19.Final。不要跨大版本「顺手」从 4.1 跳到 4.2,除非你已经评估过 4.2 的 API 与 transport 差异;安全修复在两条线上是分别发布的。
间接依赖很常见:WebFlux / Reactor Netty、部分 gRPC 与网关栈都会带入
io.netty。只改业务模块里显式声明的版本不够时,要用依赖树把
netty-codec-http、netty-handler、netty-codec-http2
等关键模块的解析结果看全。若树里同时出现 4.1 与
4.2,先查是谁引入了另一条线,再决定对齐策略,避免「升了一半」。
Spring
Boot:netty.version 属性与本稿核对到的默认值
Spring Boot 参考文档「Version Properties」写明,覆盖 Netty
管理版本的属性名是
netty.version。属性名可以确认;默认落到哪一个
Netty,则取决于你用的 Boot BOM,不能写死成某一个想象中的 Boot 版本。
本稿从 Maven Central 已发布的 spring-boot-dependencies
POM 读取(2026-10-07):
| Spring Boot | BOM 中 netty.version |
|---|---|
| 3.5.16 | 4.1.135.Final |
| 4.0.8 | 4.2.17.Final |
| 4.1.1 | 4.2.17.Final |
对照本次修复版本可以看到:3.5.16 仍停在 4.1.135.Final,低于
4.1.139.Final;4.0.8 / 4.1.1 停在 4.2.17.Final,低于 4.2.19.Final。Boot
发版节奏与 Netty 安全发版并不总是同一天对齐,出现「Boot 稳定版默认 Netty
仍低于本次安全版」是常态,不必等 Boot 小版本再动手。若你的 Boot
版本不在上表,请打开对应 BOM 看
<netty.version>,或直接用
dependency:tree / dependencyInsight
看解析结果,以你项目所用 Boot BOM 为准。
继承 spring-boot-starter-parent 时,Maven
可临时覆盖:
<properties>
<netty.version>4.1.139.Final</netty.version>
</properties>4.2 线写成 4.2.19.Final。Gradle 在使用 Spring
dependency-management 插件的前提下,设置
ext['netty.version'] 或
extra["netty.version"]。覆盖后务必再跑依赖树,确认
netty-codec-http、netty-handler、netty-codec-http2
等模块版本一致,避免只抬了一个 artifact。
等 Boot 后续小版本把默认 netty.version
抬上来之后,可以去掉覆盖。在此之前,版本属性是官方文档支持的做法。回归重点除了安全相关协议路径外,还有上文的
FileUpload.setContentType;若生产启用了 io_uring 或
HTTP/3,优先对照 4.2.19 的三项额外修复做验证。
一起交流
分享你的思考,让讨论更进一步。