Netty 4.2.16.Final 已发布,这不是功能堆料型版本,而是面向漏洞和安全问题的修复版本。对跑 HTTP、STOMP 或自定义协议网关的团队来说,这类版本的优先级通常高于普通 patch:网络框架处在入口层,问题一旦被远程触发,影响面会从单个请求扩大到线程、内存和连接池。
这次发布修了什么
Netty 本身是异步事件驱动的网络应用框架,常见位置包括协议服务器、RPC 客户端、消息网关、代理层和高吞吐 HTTP 服务。4.2.16.Final 的重点是修复漏洞和安全问题,摘要中明确提到:
io.netty:netty-codec-stomp存在内存耗尽问题,对应公告编号在摘要中显示为CVE-2026-XXXXX。io.netty:netty-codec-http存在 zip bomb 问题,对应CVE-2026-55833。- 另一个
io.netty:netty-...相关 CVE 在摘要中被截断,不能据此推断具体模块和影响范围。
这里有两个工程判断。第一,STOMP 和 HTTP codec 都属于协议解析层,输入来自网络边界,攻击者不一定需要业务权限。第二,zip bomb 和内存耗尽类漏洞的共同点是“请求体看起来不大,展开或解析成本很高”,传统的 QPS 限流未必能挡住。
受影响面怎么查
不要只看应用的直接依赖。很多项目通过 Spring、gRPC 适配层、网关 SDK、消息中间件客户端间接引入 Netty。可以先从依赖树确认当前版本和模块。
Maven 项目可以这样查:
mvn -q dependency:tree -Dincludes=io.netty
Gradle 项目可以这样查:
./gradlew dependencies --configuration runtimeClasspath | grep -i netty
如果输出里出现 netty-codec-http 或 netty-codec-stomp,并且版本低于 4.2.16.Final,就应该进入升级清单。即使业务代码没有直接写 Netty handler,也不要放过嵌入式 HTTP server、客户端连接池、消息网关这类路径。
直接升级依赖:先让补丁进来
Maven 中可以通过 BOM 统一 Netty 版本,避免 netty-buffer、netty-codec-http、netty-transport 等模块版本漂移。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-bom</artifactId>
<version>4.2.16.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http</artifactId>
</dependency>
</dependencies>
Gradle 可以这样实践:
dependencies {
implementation platform('io.netty:netty-bom:4.2.16.Final')
implementation 'io.netty:netty-codec-http'
}
升级后再确认最终解析版本:
mvn -q dependency:tree -Dincludes=io.netty
# 或
./gradlew dependencyInsight --dependency netty-codec-http --configuration runtimeClasspath
关键不是“声明了新版本”,而是运行时 classpath 真的只有一组一致的 Netty 4.2.16.Final 模块。
可以顺手加上的入口防线
补丁是第一层,但网络入口仍然应该有资源上限。下面是一个最小 Netty HTTP server 示例,演示如何在 pipeline 中设置请求聚合上限。它不能替代 4.2.16.Final 的安全修复,但可以降低大请求、异常请求把内存打满的概率。
把下面文件保存为 SafeHttpServer.java,并确保项目已依赖 netty-codec-http 和 netty-transport。
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;
public class SafeHttpServer {
public static void main(String[] args) throws Exception {
EventLoopGroup boss = new NioEventLoopGroup(1);
EventLoopGroup worker = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap()
.group(boss, worker)
.channel(NioServerSocketChannel.class)
.childOption(ChannelOption.AUTO_READ, true)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new HttpServerCodec());
ch.pipeline().addLast(new HttpObjectAggregator(1024 * 1024));
ch.pipeline().addLast(new SimpleChannelInboundHandler<FullHttpRequest>() {
@Override
protected void channelRead0(io.netty.channel.ChannelHandlerContext ctx, FullHttpRequest req) {
var body = Unpooled.copiedBuffer("ok\n", CharsetUtil.UTF_8);
var res = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, body);
res.headers().set("content-length", body.readableBytes());
ctx.writeAndFlush(res);
}
});
}
});
ChannelFuture future = bootstrap.bind(8080).sync();
future.channel().closeFuture().sync();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
如果你的服务需要处理压缩请求体,还要在网关层和应用层同时考虑解压后大小、请求超时、连接数和内存水位。zip bomb 类问题的麻烦在于压缩前体积不能代表真实成本。
升级时别漏掉这些检查
这次版本适合按安全升级流程处理,而不是等下一个功能发布窗口。建议 checklist 如下:
- 确认所有服务的
io.netty模块最终版本统一到4.2.16.Final。 - 对使用 HTTP codec、STOMP codec 的服务优先发布。
- 跑一遍协议入口的回归测试,包括大请求、压缩请求、慢请求和异常帧。
- 检查镜像或 fat jar 中是否残留旧版 Netty class。
- 如果依赖来自上游框架,优先升级上游框架;短期无法升级时,再评估 dependency management 强制覆盖的兼容性风险。
安全补丁的取舍通常很现实:升级可能暴露传递依赖冲突,不升级则把网络入口暴露在已公开的问题面前。对 Netty 这种底层框架,合理路线是先在测试环境统一版本,再用小流量服务验证,最后推进到所有暴露公网或处理不可信输入的服务。