Listen to this Post
How CVE-2026-16728 Works
Undici is a high-performance HTTP/1.1 client for Node.js. A vulnerability exists in its `interceptors.retry()` functionality, which is designed to automatically retry failed requests. The core of the issue lies in how the interceptor handles responses from a range request when the upstream server sends a partial response with mismatched framing metadata.
The attack scenario unfolds as follows:
- An application using Undici with the retry interceptor enabled makes a `Range` request to an upstream server.
- A malicious or faulty upstream server responds with a `206 Partial Content` status. The response includes headers such as `Content-Range: bytes 0-99/300` and
Content-Length: 300. - Critically, the upstream server then sends only 99 bytes of the body before abruptly closing the socket connection.
- Upon detecting the premature closure, Undici’s retry interceptor initiates a retry of the request, this time with a `Range: bytes=99-99` header to fetch the missing byte.
- The upstream server responds to this second request with the single remaining byte.
- The retry interceptor then assembles a complete response body for the application. However, it does not update the `Content-Length` header, which remains set to the original value of `300` from the first response.
The application now has a response object where the `Content-Length` header (300) does not match the actual body length (100 bytes). This state is dangerous for applications like proxies or gateways that forward upstream responses downstream. By forwarding the mismatched headers and body, they can cause downstream clients or intermediaries to become desynchronized, leading to connection hangs, corrupted responses, or other unpredictable behavior.
The vulnerability is not trivial to exploit; it requires three conditions to be met: the retry interceptor must be enabled, an upstream server must provide a partial response with inconsistent framing, and the downstream forwarder must not remove or recalculate the `Content-Length` header. It is fixed in Undici versions 6.28.0, 7.29.0, and 8.9.0.
DailyCVE Form
Platform: Node.js
Version: <6.28.0, 7.0.0-7.28.0, 8.0.0-8.8.0
Vulnerability: Response Desynchronization
Severity: Medium (CVSS: 4.8)
Date: 2026-07-29
Prediction: 2026-07-29
What Undercode Say: Analytics
The following `curl` commands simulate the malicious upstream behavior that triggers the vulnerability. An upstream server could respond to a range request with a mismatched `Content-Length` header and an incomplete body.
Simulate a malicious upstream response to a Range request The server responds with a 206 status, a Content-Length of 300, but only sends 99 bytes before closing the connection. curl -v -H "Range: bytes=0-99" http://malicious-upstream.example.com/file
Developers can use the `NODE_DEBUG` environment variable to enable verbose logging from Undici, which can help in identifying such framing mismatches during debugging.
NODE_DEBUG=undici node your-app.js
A simple code example of a vulnerable proxy using the retry interceptor:
import { request, interceptors } from 'undici';
const { retry } = interceptors;
const proxy = async (req, res) => {
const upstreamRes = await request('http://upstream.example.com', {
interceptors: { response: retry() }
});
// Forwarding headers and body without sanitizing Content-Length
res.writeHead(upstreamRes.statusCode, upstreamRes.headers);
upstreamRes.body.pipe(res);
};
Exploit
An attacker can exploit this vulnerability by controlling or poisoning an upstream server. The exploitation steps are:
1. Identify a Target: Find a proxy or gateway application that uses Undici’s `interceptors.retry()` and forwards responses without modifying headers.
2. Trigger a Partial Response: The attacker’s upstream server responds to a `Range` request from the target with a `206 Partial Content` response.
3. Send Mismatched Headers: The response includes a `Content-Length` header that is larger than the actual body that will be sent.
4. Close Connection Prematurely: The server sends only a portion of the body (e.g., 99 bytes of a 300-byte claim) and then closes the socket.
5. Force a Retry: The target’s retry interceptor will automatically retry the request to fetch the remaining data.
6. Deliver Assembled Response: The retry interceptor assembles the complete body from the partial responses but retains the original, stale `Content-Length` header from the first response.
7. Forward Malformed Response: The target application forwards this response (with a mismatched `Content-Length` and body) to the downstream client.
8. Cause Desynchronization: The downstream client or any intermediary that relies on the `Content-Length` header will become desynchronized. This can lead to connection hangs, where the client waits for data that will never arrive, or response corruption, where the client misinterprets the boundaries of the HTTP message.
Protection
- Upgrade Undici: The most effective protection is to upgrade to a patched version: v6.28.0, v7.29.0, or v8.9.0 or later.
- Disable Retry Interceptor: For applications that cannot be immediately upgraded, disable the `interceptors.retry()` for any untrusted or potentially malicious upstream servers.
- Sanitize Headers: As a workaround, before forwarding a response, remove or recalculate the `Content-Length` header based on the actual length of the response body that was assembled or transformed by Undici.
- Implement Response Validation: Add logic in your application to validate that the length of the received response body matches the `Content-Length` header. If a mismatch is detected, the response should be discarded or handled as an error.
Impact
- Response Desynchronization: Clients or intermediaries may lose sync with the HTTP message boundaries, leading to protocol errors.
- Connection Hangs: A client expecting more data based on a large `Content-Length` may hang indefinitely waiting for the connection to close or for more data to arrive.
- Response Corruption: Subsequent responses in a keep-alive connection could be misinterpreted, as the framing is broken. This can lead to one response’s data being appended to another, or entirely new requests being parsed incorrectly.
- Proxy/Gateway Vulnerability: The primary risk is to applications that act as proxies or gateways, as they are the ones that forward the malformed responses to end-users or other services.
- Medium Severity: The vulnerability has a CVSS score of 4.8 (Medium), indicating it is a significant risk that should be addressed, though it requires specific conditions to be exploited.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

