From 9b1a9abe7ac36729d182a92ad3c34ae14c3094db Mon Sep 17 00:00:00 2001 From: Kannan J Date: Tue, 28 Jul 2026 13:02:58 +0000 Subject: [PATCH] netty: Fix client-initiated stream limit bypass in NettyServerHandler (#12933) Configure connection.remote().maxActiveStreams(maxStreams) directly upon `DefaultHttp2Connection` initialization. Because `NettyServerHandler` instantiates `DefaultHttp2Connection` directly rather than using Netty's `AbstractHttp2ConnectionHandlerBuilder`, it missed Netty's built-in CVE-2026-47244 patch. This left a pre-handshake window where the server's local connection allowed up to Integer.MAX_VALUE active client-initiated streams until a SETTINGS_ACK was received. Enforcing the limit proactively at startup closes this vulnerability window and prevents client-initiated stream floods / resource exhaustion. Fixes #12930 --- netty/src/main/java/io/grpc/netty/NettyServerHandler.java | 1 + .../test/java/io/grpc/netty/NettyServerHandlerTest.java | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/netty/src/main/java/io/grpc/netty/NettyServerHandler.java b/netty/src/main/java/io/grpc/netty/NettyServerHandler.java index 79715ca2996..58166f50f7e 100644 --- a/netty/src/main/java/io/grpc/netty/NettyServerHandler.java +++ b/netty/src/main/java/io/grpc/netty/NettyServerHandler.java @@ -252,6 +252,7 @@ static NettyServerHandler newHandler( maxMessageSize); final Http2Connection connection = new DefaultHttp2Connection(true); + connection.remote().maxActiveStreams(maxStreams); UniformStreamByteDistributor dist = new UniformStreamByteDistributor(connection); dist.minAllocationChunk(MIN_ALLOCATED_CHUNK); // Increased for benchmarks performance. DefaultHttp2RemoteFlowController controller = diff --git a/netty/src/test/java/io/grpc/netty/NettyServerHandlerTest.java b/netty/src/test/java/io/grpc/netty/NettyServerHandlerTest.java index 1c8d2b5479d..84a1a48b37f 100644 --- a/netty/src/test/java/io/grpc/netty/NettyServerHandlerTest.java +++ b/netty/src/test/java/io/grpc/netty/NettyServerHandlerTest.java @@ -454,6 +454,14 @@ public void shouldAdvertiseMaxConcurrentStreams() throws Exception { assertEquals(maxConcurrentStreams, captor.getValue().maxConcurrentStreams().longValue()); } + @Test + public void connectionRemoteMaxActiveStreamsShouldBeEnforcedLocallyOnStartup() throws Exception { + maxConcurrentStreams = 314; + manualSetUp(); + + assertEquals(maxConcurrentStreams, connection().remote().maxActiveStreams()); + } + @Test public void shouldAdvertiseMaxHeaderListSize() throws Exception { maxHeaderListSize = 123;