Jun 15, 2026·7 min read·11 visits
Remote, unauthenticated attackers can crash Netty-based Redis servers by sending a 13-byte RESP array header containing a large declared array length, triggering an immediate OutOfMemoryError.
An uncontrolled resource pre-allocation flaw in the Netty Redis codec module allows remote unauthenticated attackers to cause a denial of service (OutOfMemoryError) by sending a crafted Redis Serialization Protocol (RESP) array header.
Netty is an asynchronous event-driven network application framework used for the rapid development of maintainable high-performance protocol servers and clients. The framework includes a specialized Redis codec implementation module, netty-codec-redis, which facilitates the parsing and generation of Redis Serialization Protocol (RESP) messages. This module is commonly utilized in custom Redis proxy servers, database gateways, and applications interfacing directly with Redis cluster nodes.
Within the netty-codec-redis module, the parsing architecture consists of two main pipeline components: the RedisDecoder and the RedisArrayAggregator. The RedisDecoder is responsible for low-level stream dissection, identifying RESP types, and emitting intermediate token representations. The RedisArrayAggregator is responsible for taking these flat tokens and consolidating them into full object hierarchies, such as nested arrays.
A weakness exists in how the RedisArrayAggregator manages memory when processing incoming array headers. The aggregator trustfully accepts the element count declared by the client and attempts to prepare the internal list structure prior to receiving any elements. Because the memory allocation is proportional to the unverified length value, the class exposes a high-severity denial-of-service interface to unauthenticated remote clients.
The root cause of the vulnerability lies in the coupling of network-supplied length parameters with internal array capacity reservations. In the RESP specification, an array is represented by a leading asterisk character followed by the number of elements as a decimal value, and terminated by carriage-return line-feed sequences. For instance, *3\r\n denotes an array expecting three child elements.
When the pipeline processes an incoming array, RedisDecoder#decodeLength reads the parsed character sequence and decodes the length. The decoder passes this value into an instance of ArrayHeaderRedisMessage. While the decoder enforces limits on individual bulk string sizes to prevent allocation exploitation, it does not impose limits on the value inside the array header. This design permits a packet claiming to contain the maximum possible signed 32-bit integer value (2,147,483,647) to pass unhindered.
The downstream RedisArrayAggregator intercepts the ArrayHeaderRedisMessage and instantiates a state management tracker named AggregateState. The constructor of AggregateState takes the declared length and sets up a standard Java ArrayList to hold the child elements. Specifically, it executes this.children = new ArrayList<>(length);. This call tells the Java Virtual Machine (JVM) to allocate a backing Object array matching the requested capacity, leading to an immediate memory reservation request without any confirmation that the matching elements will ever be sent over the socket.
In the vulnerable versions of netty-codec-redis (prior to 4.1.135.Final and 4.2.15.Final), the state-tracking class in the aggregator is implemented as follows:
// Vulnerable Code Path: io.netty.handler.codec.redis.RedisArrayAggregator
private static final class AggregateState {
private final int length;
private final List<RedisMessage> children;
AggregateState(int length) {
this.length = length;
// The constructor pre-allocates memory for the total declared length
this.children = new ArrayList<RedisMessage>(length);
}
}When a client sends the payload *2147483647\r\n, the length variable evaluates to 2147483647. Under standard JVM operations, the constructor of ArrayList initializes its internal reference table via new Object[initialCapacity]. On a 64-bit JVM, each reference requires 8 bytes (or 4 bytes with Compressed OOPs enabled). Calculating the allocation size for the backing array reveals the memory demand:
$$\text{Memory Request} = 2,147,483,647 \times 4 \text{ bytes} \approx 8.58 \text{ GB}$$
If Compressed OOPs is disabled, the system requests twice that amount, approximately 17.17 GB of contiguous heap memory. Since most JVM processes operate with heap configurations below this threshold, the memory manager cannot satisfy the allocation. The allocation failure forces the JVM to throw a java.lang.OutOfMemoryError immediately, causing thread termination or process termination.
The patched versions modify the class constructor to break the relationship between untrusted input and pre-allocation sizes. The patch limits the initial pre-allocation size to a maximum static threshold while allowing the list to grow dynamically if elements actually arrive:
// Patched Code Path: io.netty.handler.codec.redis.RedisArrayAggregator
private static final class AggregateState {
private final int length;
private final List<RedisMessage> children;
AggregateState(int length) {
this.length = length;
// The allocation is capped at 128 to prevent immediate OutOfMemoryError
this.children = new ArrayList<RedisMessage>(Math.min(length, 128));
}
}This modification ensures that a large array length header will only cause a tiny memory footprint upon connection. If the attacker fails to send the physical elements, the application simply awaits more network input without consuming system memory. If the attacker tries to send 2 billion elements to satisfy the allocation, the request will be caught by timeout filters, transport rate limits, or network bandwidth saturation before it can exhaust JVM resources.
Exploitation of CVE-2026-50011 requires zero privileges, no authentication, and can be initiated over any standard network path that allows connections to the Netty Redis service. The attacker needs only to establish a raw TCP connection and transmit a 13-byte malicious sequence.
Because the heap reservation happens instantly upon reading the header token, the attack is highly efficient and operates at wire speed. The attacker does not need to sustain a connection or perform multiple roundtrips. A single TCP packet containing the byte sequence 2a 32 31 34 37 34 38 33 36 34 37 0d 0a is sufficient to terminate the target pipeline.
If the Netty service uses shared thread loops or runs within a containerized environment where memory limits are strictly enforced by the host operating system, the OutOfMemoryError can lead to immediate shutdown of the containing container, taking down other colocated microservices.
The operational impact of CVE-2026-50011 is restricted to availability. However, because Netty-based servers are often critical middleware components, a failure at this level can disrupt dependent applications downstream.
Because an OutOfMemoryError represents an unrecoverable runtime state in most Java configurations, the default JVM behavior is to halt execution threads or exit entirely. If the application handles the exception on the event loop, the worker thread itself might crash, causing active connections on that thread to be abruptly severed.
Furthermore, before the JVM crashes, the sudden demand for billions of bytes of contiguous heap memory triggers garbage collection routines. The garbage collector will run exhaustively, trying to reclaim space to satisfy the allocation. This condition, known as GC thrashing, consumes 100 percent of available CPU resources, freezing the server and blocking all legitimate network transactions before the process eventually shuts down.
The definitive resolution for CVE-2026-50011 is upgrading the underlying dependencies to secure versions. For projects operating on the 4.1.x development branch, upgrade the netty-codec-redis dependency to version 4.1.135.Final or higher. For projects using the newer 4.2.x branch, upgrade to 4.2.15.Final or higher.
If upgrading is not an immediate option, developers can deploy a pipeline mitigation by implementing a custom inbound channel handler. This handler should be inserted directly before the RedisArrayAggregator within the channel pipeline. The validation handler should inspect incoming messages, catch instances of ArrayHeaderRedisMessage, check the declared length, and disconnect the client if the size exceeds a logical business limit (e.g., 65,536 elements).
// Example temporary mitigation handler
public final class LimitRedisArrayLengthHandler extends ChannelInboundHandlerAdapter {
private static final int MAX_ALLOWED_ELEMENTS = 65536;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof ArrayHeaderRedisMessage) {
ArrayHeaderRedisMessage header = (ArrayHeaderRedisMessage) msg;
if (header.length() > MAX_ALLOWED_ELEMENTS) {
// Block processing and close connection
ctx.close();
ReferenceCountUtil.release(msg);
return;
}
}
super.channelRead(ctx, msg);
}
}CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
netty-codec-redis Netty | < 4.1.135.Final | 4.1.135.Final |
netty-codec-redis Netty | >= 4.2.0.Final, < 4.2.15.Final | 4.2.15.Final |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-770 |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Base Score | 7.5 (High) |
| Exploit Maturity | Proof of Concept |
| Impact Category | Availability (Denial of Service) |
| CISA KEV Status | Not Listed |
The software allocates memory or other resources based on user-controlled input without bounding the maximum allocation size, allowing an attacker to cause resource exhaustion.
An authentication bypass in the SiYuan personal knowledge management system before version 3.7.0 exposes a dynamic icon rendering endpoint. This endpoint processes client-supplied Go template directives. By submitting a crafted request, an unauthenticated remote attacker can leverage registered database template functions to execute arbitrary read-only SQL queries and exfiltrate workspace contents.
CVE-2026-54069 is a critical authentication bypass vulnerability in the SiYuan Note personal knowledge management system. The flaw is located in the HTTP server's middleware handling API authorization, which unconditionally trusts requests carrying a 'chrome-extension://' scheme in the Origin HTTP header, granting administrative access without validating API tokens.
CVE-2026-54089 is a critical authentication bypass vulnerability in File Browser affecting instances configured with proxy-based authentication. An unauthenticated remote attacker with direct network access can impersonate arbitrary users or register new accounts by spoofing configured HTTP headers.
The malicious Cargo package 'exploration' was uploaded to the crates.io registry. During compilation or package import, the crate executes code designed to establish an outbound TCP/HTTP connection, download an external second-stage binary, and execute the binary locally on the host machine. This creates an unauthenticated remote code execution vector impacting developer environments and continuous integration pipelines.
CVE-2026-54088 is a critical command injection vulnerability in File Browser prior to version 2.63.6. When Hook Authentication is enabled, the application interpolates unsanitized credentials into a shell command, allowing unauthenticated remote code execution.
An authenticated remote code execution vulnerability exists in NotrinosERP (versions up to and including 1.0.0) within the Human Resource Management (HRM) module. Users with employee management permissions can upload arbitrary file types, including PHP scripts, which are written directly to a web-accessible directory. This allows for arbitrary code execution in the context of the web-server user.