Aug 7, 2026·5 min read·61 visits
Netty's Redis array aggregator fails to release pooled direct buffers upon specific limit-validation errors, allowing remote attackers to pin system memory and induce a Denial of Service.
A vulnerability in Netty's Redis codec allows remote unauthenticated attackers to cause a memory-pinning Denial of Service (DoS) due to the failure to release partial aggregate state when specific error conditions occur in RedisArrayAggregator. When processing Redis Serialization Protocol (RESP) messages, the aggregator fails to clear internal queues and release retained direct byte buffers on exception paths triggered by exceeded maxElements or invalid length properties. If the pipeline does not explicitly tear down the connection upon detecting a decoder error, subsequent elements continue utilizing the stale context, allowing memory blocks to remain indefinitely pinned.
Netty's Redis codec offers high-performance parsing and aggregation for the Redis Serialization Protocol (RESP). The RedisArrayAggregator component converts incoming sequential RESP elements (such as bulk strings or integers) into structured, composite array structures represented by ArrayRedisMessage objects.
To manage hierarchy and nested structures, the aggregator tracks incoming components using an internal stack of aggregate states. To prevent excessive memory allocation by untrusted peers, the handler enforces configured security limits, specifically bounding both the maximum element count (maxElements) and the maximum nesting depth (maxNestedArrayDepth).
A critical vulnerability exists where the handler validation logic deviates across different threshold checks. When specific constraints are violated, the aggregator raises decoder exceptions without releasing the already gathered partial states or decrementing the reference count of associated pooled buffers. This behavior leaves allocated resources active on the handler context, introducing a remote resource-pinning vector.
The root cause is located in the RedisArrayAggregator.decodeRedisArrayHeader method during the assessment of incoming array length fields. The handler uses an internal stack named depths containing AggregateState instances that retain reference counts of previously accumulated child payloads.
Under normal execution, if the incoming array structure exceeds the maximum allowed nesting limit (depths.size() >= maxNestedArrayDepth), the code executes releaseAndClearDepths(), which releases all retained direct buffers, and then raises a CodecException.
However, if the incoming header specifies an array length that exceeds the maxElements boundary, or if a negative length (bad length) check is triggered, the system directly instantiates and throws a CodecException without invoking releaseAndClearDepths(). This oversight allows references to accumulated buffers to remain pinned in JVM memory, as the internal stack is never systematically cleared on these exception paths.
The original implementation checked limits in sequence but failed to clear the accumulation stack on every path that raised an error.
// Vulnerable logic in RedisArrayAggregator.java
private RedisMessage decodeRedisArrayHeader(ArrayHeaderRedisMessage header) {
if (header.isNull()) {
return ArrayRedisMessage.NULL_INSTANCE;
} else if (header.length() > 0L) {
if (header.length() > maxElements) {
// State is not cleared before throwing this exception
throw new CodecException("this codec doesn't support longer length than " + maxElements);
}
if (depths.size() >= maxNestedArrayDepth) {
releaseAndClearDepths(); // Only cleared here
throw new CodecException("max nested array depth exceeded: " + maxNestedArrayDepth);
}
depths.push(new AggregateState((int) header.length()));
return null;
} else {
// State is not cleared before throwing this exception
throw new CodecException("bad length: " + header.length());
}
}The remediation introduces a centralized helper method, clearAndCreateException, to ensure that state cleanup is applied consistently across all validation pathways:
// Remediation logic in RedisArrayAggregator.java
private CodecException clearAndCreateException(String msg) {
releaseAndClearDepths(); // Explicitly releases all pooled memory and clears the depths stack
return new CodecException(msg);
}
private RedisMessage decodeRedisArrayHeader(ArrayHeaderRedisMessage header) {
if (header.isNull()) {
return ArrayRedisMessage.NULL_INSTANCE;
} else if (header.length() > 0L) {
if (header.length() > maxElements) {
throw clearAndCreateException("this codec doesn't support longer length than " + maxElements);
}
if (depths.size() >= maxNestedArrayDepth) {
throw clearAndCreateException("max nested array depth exceeded: " + maxNestedArrayDepth);
}
depths.push(new AggregateState((int) header.length()));
return null;
} else {
throw clearAndCreateException("bad length: " + header.length());
}
}An unauthenticated attacker can exploit this state retention vulnerability through a multi-step sequence over an established TCP connection.
First, the attacker initiates a valid array sequence to trigger memory allocation on the server side, sending a small header and a large bulk string. The aggregator allocates a pooled direct buffer and pushes the state to the stack.
Second, the attacker sends a subsequent array header with a length value intentionally exceeding the configured maxElements limit. This triggers a validation failure on the server.
Third, because the state cleanup is bypassed, the server leaves the allocated direct buffer pinned in memory. The attacker keeps the socket connection open and repeats this sequence, forcing the server to exhaust its pooled direct memory space.
The consequence of this vulnerability is a denial of service (DoS) caused by persistent JVM memory exhaustion. Because high-performance Netty servers utilize a pooled memory model (such as PooledByteBufAllocator), unreleased direct buffers do not return to the system and cannot be reclaimed by standard garbage collection.
The retention of these buffers is tied directly to the lifetime of the channel handler context. If the application continues processing traffic on the same TCP channel or catches decoder exceptions without tearing down the connection, memory remains pinned.
By repeatedly inducing this error state across multiple sessions, an attacker can consume all available direct or heap memory allocations. This forces the system to throw an OutOfMemoryError on subsequent requests, causing the Netty worker threads to terminate or crash the application.
The primary defense is updating the Netty dependency to a secure version. The patch has been backported and released in versions 4.1.136.Final and 4.2.16.Final.
If immediate library upgrades are not feasible, implement a strict connection-teardown routine in the pipeline. Ensure that your Netty pipeline handler explicitly catches CodecException and closes the associated channel to free up handler resources.
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
if (cause instanceof CodecException) {
// Force connection termination to release any pinned aggregate states
ctx.close();
} else {
ctx.fireExceptionCaught(cause);
}
}Additionally, monitor application performance telemetry. Look for continuous linear growth in direct memory pools alongside unhandled exception logs referencing Redis decoder limit failures.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
Netty Netty | < 4.1.136.Final | 4.1.136.Final |
Netty Netty | >= 4.2.0-Final, < 4.2.16.Final | 4.2.16.Final |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-401, CWE-703 |
| Attack Vector | Network (AV:N) |
| CVSS Base Score | 6.5 |
| Impact Type | Denial of Service (Memory Exhaustion) |
| Exploit Status | No public PoC available |
| CISA KEV Status | Not Listed |
The application does not release memory after its effective lifetime, or fails to properly handle exceptional conditions, leading to resource exhaustion.
An uncontrolled resource consumption vulnerability exists in the Docling document conversion library. Maliciously structured HTML, JATS, ODS, or BoxNote inputs containing table cells with excessively large 'rowspan' or 'colspan' attribute values trigger algorithmic complexity conditions. This allows unauthenticated remote attackers to initiate resource exhaustion states, crashing or hanging the target document processing pipeline while bypassing configured timeouts.
A Local File Inclusion (LFI) and Arbitrary File Disclosure vulnerability exists in Docling and Docling Slim versions >= 2.16.0 up to 2.131.0. When parsing serialized DoclingDocument structures using the JSON input format, the backend fails to restrict image URI schemes, allowing remote attackers to retrieve local files and verify path existence on the host system during embedded document export.
Docling, a tool for parsing and processing diverse document formats, is vulnerable to arbitrary file read, arbitrary file write, and potential remote code execution (RCE) in versions 2.94.0 through 2.131.0. The vulnerability occurs when applications configure Docling to use the Tectonic engine for rendering TikZ diagrams into images. Because the compilation did not restrict hazardous TeX primitives or sandbox the environment, an attacker can supply crafted documents containing malicious TikZ definitions to access or modify local files and execute arbitrary commands under the privileges of the processing application.
An SSRF guard bypass vulnerability in the Docling document conversion engine allows unauthenticated attackers to bypass internal IP access controls. The vulnerability exists due to a DNS rebinding Time-of-Check Time-of-Use (TOCTOU) condition, URL authority parsing inconsistencies, and unvalidated network requests triggered during headless browser page rendering.
A technical analysis of CVE-2026-105742 (GHSA-p3fw-7699-7926), a sensitive information disclosure vulnerability in the Docling document processing library. Vulnerable versions of Docling indiscriminately forward custom HTTP headers, such as authentication tokens, to arbitrary third-party origins and during cross-origin redirects while fetching remote image assets from untrusted HTML and EPUB documents.
CVE-2026-106121 is a Denial of Service (DoS) vulnerability in the RabbitMQ Java Client library (amqp-client) affecting versions prior to 5.37.0. The vulnerability resides in the legacy, custom JSON-RPC parsing class com.rabbitmq.tools.json.JSONReader. When parsing malformed or truncated payloads ending within a quoted string or single-line comment, the parser's scanner enters an infinite loop. This occurs because the loop lacks an exit condition for the end-of-input sentinel character returned by the iterator, leading to either CPU exhaustion or a JVM crash from an OutOfMemoryError.