netty: Fix client-initiated stream limit bypass in NettyServerHandler (v1.83.x backport) (#12942)
Backport of #12933 to v1.83.x.
---
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
diff --git a/netty/src/main/java/io/grpc/netty/NettyServerHandler.java b/netty/src/main/java/io/grpc/netty/NettyServerHandler.java
index 79715ca..58166f5 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 @@
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 1c8d2b5..84a1a48 100644
--- a/netty/src/test/java/io/grpc/netty/NettyServerHandlerTest.java
+++ b/netty/src/test/java/io/grpc/netty/NettyServerHandlerTest.java
@@ -455,6 +455,14 @@
}
@Test
+ public void connectionRemoteMaxActiveStreamsShouldBeEnforcedLocallyOnStartup() throws Exception {
+ maxConcurrentStreams = 314;
+ manualSetUp();
+
+ assertEquals(maxConcurrentStreams, connection().remote().maxActiveStreams());
+ }
+
+ @Test
public void shouldAdvertiseMaxHeaderListSize() throws Exception {
maxHeaderListSize = 123;
manualSetUp();