Mar 5, 2026·6 min read·5 visits
Eclipse Jetty fails to release native memory for Gzip-compressed requests when the response is not compressed. Attackers can exhaust server memory by sending compressed requests without the 'Accept-Encoding: gzip' header.
A high-severity resource management vulnerability exists in Eclipse Jetty versions 12.0.0 through 12.0.31 and 12.1.0 through 12.1.5. The GzipHandler component fails to correctly release native memory resources associated with the zlib Inflater when processing compressed requests if the corresponding response is not compressed. This allows unauthenticated remote attackers to trigger a native memory leak, leading to Denial of Service (DoS) via application crash or OOM termination.
Eclipse Jetty is a widely used Java-based web server and servlet container. The vulnerability resides in the GzipHandler, a component responsible for dynamically compressing responses and decompressing requests. When handling HTTP requests with a Content-Encoding: gzip header, Jetty utilizes the java.util.zip.Inflater class to decompress the request body. Note that Inflater allocates native (off-heap) memory via the zlib library, which is not directly managed by the Java Garbage Collector.
In affected versions, a logic error in the request lifecycle management prevents the explicit release of these native resources under specific conditions. While the Java wrapper objects are eventually garbage collected, the underlying native memory blocks allocated by zlib remain explicitly allocated until the end() method is called. This discrepancy leads to a native memory leak.
This vulnerability is classified as CWE-400 (Uncontrolled Resource Consumption) and CWE-401 (Missing Release of Memory after Effective Lifetime). It poses a significant availability risk, as a relatively low volume of malicious traffic can exhaust the available native memory of the host system, causing the operating system to terminate the Java process.
The root cause of CVE-2026-1605 is an asymmetric resource lifecycle management flaw within GzipHandler.java. The handler manages two distinct operations: inflating (decompressing) the request and deflating (compressing) the response. These operations utilize Inflator and Deflater objects, respectively, which are pooled to reduce allocation overhead.
In the vulnerable implementation, the cleanup logic for the Inflator (used for the request) was inadvertently coupled to the response compression logic. When a request required inflation, a GzipRequest object was created, leasing an Inflator from the pool. The return of this resource to the pool was handled by the destroy() method.
However, the call to destroy() was only scheduled if the response also required compression. The code relied on a wrapper class GzipResponseAndCallback to handle the completion callback and trigger cleanup. If the response did not trigger compression—for instance, if the client omitted the Accept-Encoding: gzip header or if the response MIME type was excluded—this wrapper was never instantiated. Consequently, the completion callback passed to the next handler in the chain did not include the destroy() hook, and the Inflator was never returned to the pool or released.
The vulnerability exists in the handle method of GzipHandler.java. The fix involves decoupling the request cleanup from the response configuration. Below is a comparison of the logic before and after the patch.
Vulnerable Logic:
In the vulnerable code, the callback (which signifies request completion) is only wrapped if tryDeflate (response compression) is true.
// Vulnerable: Cleanup logic is conditional on response compression
if (tryDeflate) {
// GzipResponseAndCallback handles both response compression
// AND request cleanup (calling gzipRequest.destroy())
callback = new GzipResponseAndCallback(handler, request, response, callback);
}
// If tryDeflate is false, 'callback' remains unwrapped.
// The gzipRequest is created, but its destroy() method is never scheduled.Patched Logic (Commit a9e16433):
The fix introduces a dedicated cleanup wrapper using Callback.from. This ensures that gzipRequest::destroy is called regardless of whether the response is compressed.
if (inflatable && tryInflate || etagMatches) {
// ... GzipRequest instantiation ...
GzipRequest gzipRequest = new GzipRequest(request, _inflaterPool, ...);
request = gzipRequest;
// FIX: Unconditionally wrap the callback to ensure resource release.
// This ensures destroy() is called even if response compression is skipped.
callback = Callback.from(callback, gzipRequest::destroy);
}This change ensures that every Inflater leased from the pool is guaranteed to be returned when the request processing completes, eliminating the leak path.
Exploiting this vulnerability requires sending a specific sequence of HTTP headers that triggers request decompression while bypassing response compression. No authentication is required.
Attack Prerequisites:
GzipHandler enabled (enabled by default in many configurations).Exploit Steps:
Content-Encoding: gzip.Accept-Encoding: gzip header. This forces the server to skip the response compression logic, triggering the vulnerable code path where the cleanup callback is missed.Inflator instance (approximately 32KB-64KB of native memory depending on zlib settings, plus the overhead of the Java wrapper).Proof of Concept (Conceptual):
# Compress a dummy payload
echo "data" | gzip > payload.gz
# Send request causing leak
# Note: No Accept-Encoding header is sent
curl -X POST -H "Content-Encoding: gzip" --data-binary @payload.gz http://target-server/Continued execution of this loop will cause the process Resident Set Size (RSS) to grow until the operating system invokes the OOM killer.
The primary impact of CVE-2026-1605 is Denial of Service (DoS). Unlike heap-based memory leaks which result in a java.lang.OutOfMemoryError: Java heap space (often recoverable or catchable), this vulnerability exhausts native memory.
Consequences:
Severity Metrics:
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:HThe only complete fix is to upgrade the Eclipse Jetty components to a patched version. The fix was backported to the supported 12.0 and 12.1 branches.
Patched Versions:
Workarounds: If an immediate upgrade is not feasible, the following temporary mitigations apply:
GzipHandler from the server configuration chain.Content-Encoding: gzip headers from incoming requests, effectively disabling request inflation logic before it reaches Jetty. Note that this breaks functionality for legitimate clients sending compressed data.CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Eclipse Jetty Eclipse Foundation | 12.0.0 - 12.0.31 | 12.0.32 |
Eclipse Jetty Eclipse Foundation | 12.1.0 - 12.1.5 | 12.1.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400 / CWE-401 |
| CVSS Score | 7.5 (High) |
| Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| Attack Vector | Network (Remote) |
| Exploit Maturity | PoC Available |
| EPSS Score | 0.04% |
Uncontrolled Resource Consumption