Listen to this Post
The vulnerability resides in the `Lz4FrameDecoder` before decompression begins. The decoder reads a compressed block’s header and uses the user-supplied `decompressedLength` field directly as the size for a new `ByteBuf` allocation.
This value can be up to 32 MB per block, and to reach the vulnerable code path, an attacker only needs to send a valid LZ4 frame header plus the `compressedLength` payload—22 bytes total if compressedLength == 1.
The decoding process works as follows:
- The LZ4 frame header is parsed from the incoming stream.
- On the compressed path, after
readableBytes >= compressedLength, the decoder invokesctx.alloc().buffer(decompressedLength, decompressedLength). - This pre‑allocates a `ByteBuf` of the size indicated by the attacker‑controlled `decompressedLength` field before any decompression or validation occurs.
Because the header fields are trusted without any limit checks, a minimal 22‑byte request can force the server to allocate a 32 MB buffer. By sending many such small frames, an attacker can exhaust the server’s memory, leading to a denial‑of‑service condition.
The provided proof of concept (PoC) demonstrates that a `ServerBootstrap` with an `Lz4FrameDecoder` crashes with an `IndexOutOfBoundsException` after receiving 22 crafted bytes.
Platform: Netty
Version: <=4.2.12.Final
Vulnerability : Memory Exhaustion DoS
Severity: High
date: 2026-05-07
Prediction: Patch 2026-05-05
Analytics under heading What Undercode Say:
Check your current Netty version in a Maven project mvn dependency:tree | grep netty-codec For Gradle ./gradlew dependencies | grep netty-codec Identify vulnerable versions (≤4.2.12.Final or ≤4.1.132.Final) echo "If netty-codec version is 4.2.12.Final or lower, you are affected." Test the PoC (requires a Netty server with Lz4FrameDecoder) Replace the server port and host as needed curl --data-binary @poc.bin http://target:port/ Monitor memory usage for sudden spikes (Linux) watch -n1 'ps aux --sort=-%mem | head -10' Immediately upgrade to a fixed version (4.2.13.Final or 4.1.133.Final) For Maven: <dependency> <groupId>io.netty</groupId> <artifactId>netty-codec</artifactId> <version>4.2.13.Final</version> </dependency> For Gradle: implementation 'io.netty:netty-codec:4.2.13.Final'
Exploit:
The attacker crafts an LZ4 frame header with a valid magic number, a compressed block type flag, and sets `compressedLength=1` while setting `decompressedLength` to a high value (e.g., 1<<25 = 32MB). The remaining payload is trivial (e.g., a single null byte). Upon receiving these 22 bytes, the server allocates a 32 MB buffer, leading to memory exhaustion.
Protection from this CVE
Upgrade to Netty 4.2.13.Final or 4.1.133.Final, which enforce a `maxDecompressedLength` limit in Lz4FrameDecoder. If upgrading is not immediately possible, implement a custom `ChannelInboundHandler` before the decoder to filter or reject LZ4 frames with suspicious `decompressedLength` values. Also, apply per‑channel and aggregate memory limits through `io.netty.maxDirectMemory` or similar JVM flags.
Impact
A remote, unauthenticated attacker can send a continuous stream of small LZ4 frames (as few as 22 bytes each) to force the target server to repeatedly allocate large memory buffers (up to 32 MB per request). This uncontrolled resource consumption quickly leads to memory exhaustion, causing the application to become unresponsive or crash, resulting in a denial of service.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

