Aug 4, 2026·7 min read·1 visit
A vulnerability in Undici allows remote attackers to inject arbitrary cookie attributes (such as SameSite, HttpOnly, and Secure) via unsanitized domain inputs and custom unparsed options arrays, undermining core web-security mitigations like CSRF protections.
CVE-2026-16729 (GHSA-v3r7-h72x-cjcm) is a medium-severity cookie attribute injection vulnerability in Undici's web-compliant cookie utility module. Due to insufficient validation of domain parameters and raw attributes in the unparsed options array, arbitrary attributes like SameSite, HttpOnly, and Secure can be injected. This allows attackers to bypass CSRF protections, strip security flags, or override intended cookie behaviors when applications pass user-controlled values to these properties.
Undici is the standard, high-performance HTTP/1.1 client for Node.js, forming the backbone of the global fetch API implementation inside modern Node.js environments. Within Undici, cookie serialization and compliance are handled by dedicated utilities inside lib/web/cookies/util.js. This file exports functions such as setCookie and stringify to help developers easily craft and apply Set-Cookie headers.
The attack surface exists when host applications take untrusted user inputs and map them directly to parameters used in cookie generation, such as tenant-specified domain scopes or dynamic preference arrays. In these architectural patterns, if the underlying HTTP client library lacks robust parameter validation, structural delimiters can be smuggled directly into the header payload.
This specific vulnerability is classified as CWE-74 (Improper Neutralization of Special Elements in Output Used by a Downstream Component). Successful exploitation allows attackers to manipulate cookie attributes, potentially stripping integrity flags or forcing configurations that reduce client-side protections. The impact is restricted to cookies processed by downstream user agents (browsers) that receive the malformed headers generated by the library.
The root cause of the vulnerability lies in two separate code paths in lib/web/cookies/util.js that failed to sanitize inputs before generating the final Set-Cookie header. The first flaw resides within the validateCookieDomain helper function. This function was implemented using a blacklist check that only rejected domains starting with a hyphen or ending with a period or hyphen.
This blacklist-based verification failed to check for standard delimiters, most notably the semicolon (;). Because semicolons serve as structural parameter boundaries in HTTP cookie headers, an attacker supplying a domain string like example.com; SameSite=None; Secure could easily inject arbitrary parameters. Undici would directly append this string to the outgoing header, and downstream browsers would parse the injected parameters as separate, valid cookie attributes.
The second flaw exists in the custom attribute serialization loop of the stringify function. This loop iterates over the unparsed options array, which is intended to allow developers to define raw custom cookie configurations. The pre-patch loop split each element on the first equal sign (=) and immediately appended them to the output list without executing any security-critical validations on either the keys or values. If user input reached this array, arbitrary characters could be injected into the output sequence.
To fix this vulnerability, the development team replaced the fragile blacklist validations with robust, RFC-compliant whitelists. The patches were backported across three major version branches. The critical changes target both domain verification and unparsed options verification.
In the patched version of validateCookieDomain, Undici implements a precise character-by-character scanner that enforces RFC 1034, RFC 1123, and RFC 1035 standards. The code now checks that domain segments (labels) only contain alphanumeric characters or hyphens, that labels do not exceed 63 characters, and that the total domain length does not exceed 255 characters. Semicolons and other non-compliant characters now trigger immediate validation errors.
// Patched validateCookieDomain implementation in lib/web/cookies/util.js
function validateCookieDomain (domain) {
if (domain === ' ') {
return
}
if (domain.length > 255) {
throw new Error('Invalid cookie domain')
}
let labelLength = 0
for (let i = 0; i < domain.length; ++i) {
const code = domain.charCodeAt(i)
if (code === 0x2E) { // "."
if (labelLength === 0 || domain.charCodeAt(i - 1) === 0x2D) {
throw new Error('Invalid cookie domain')
}
labelLength = 0
continue
}
if (labelLength === 0 && !isLetterOrDigit(code)) {
throw new Error('Invalid cookie domain')
}
if (!isLetterOrDigit(code) && code !== 0x2D) { // "-"
throw new Error('Invalid cookie domain')
}
if (++labelLength > 63) {
throw new Error('Invalid cookie domain')
}
}
if (labelLength === 0 || domain.charCodeAt(domain.length - 1) === 0x2D) {
throw new Error('Invalid cookie domain')
}
}Additionally, the stringify function was patched to validate elements from the unparsed array. Instead of appending elements directly, the patched code validates both the keys and values using existing utility methods:
// Patched serialization block in stringify()
const [key, ...value] = part.split('=')
const trimmedKey = key.trim()
const joinedValue = value.join('=')
// These helpers ensure neither keys nor values contain injection delimiters
validateCookieName(trimmedKey)
validateCookieValue(joinedValue)
out.push(`${trimmedKey}=${joinedValue}`)To exploit CVE-2026-16729, an attacker must locate an application interface that exposes the domain configuration of cookies or the unparsed attribute array to user-controlled parameters. This is common in multi-tenant architectures, where cookie scopes are dynamically determined from incoming host headers, or in proxy servers that handle cookie propagation.
In a typical attack scenario targeting the domain parameter, an attacker submits a modified HTTP request where the query string contains structural cookie delimiters. For instance, sending ?tenant_domain=victim.com;%20SameSite=None;%20Secure forces the application to produce a malformed header.
Because standard browsers prioritize initial configuration parameters or fail to resolve duplicate attribute conflicts safely, appending an injected SameSite=None parameter can override the application's default SameSite=Lax setting. This successfully strips the client-side cross-site request forgery (CSRF) protections. Similarly, an injection into the unparsed array using X-Attr=Val; HttpOnly can alter the visibility of session tokens to client-side scripts, disrupting session integrity controls.
The overall impact of CVE-2026-16729 is rated as Medium with a CVSS v3.1 score of 4.8. The attack complexity is classified as high because exploitation requires specific application-level configurations that expose Undici's cookie parameters to raw user inputs.
If exploited, the confidentiality and integrity of web sessions can be compromised. For example, stripping the HttpOnly or Secure attributes enables cross-site scripting (XSS) payloads to extract sensitive session keys or facilitates the interception of cookies over unencrypted channels. Conversely, injecting SameSite=None exposes critical session cookies to CSRF attacks.
The vulnerability is currently not known to be used in active ransomware campaigns, nor has it been added to the CISA Known Exploited Vulnerabilities (KEV) catalog. No active exploitation has been observed, and public proof-of-concept codes are limited to manual verification scripts.
The definitive remediation for this vulnerability is upgrading Undici to a secure, patched release depending on the active major release branch. Applications running on the 6.x line must upgrade to 6.28.0 or higher. Applications running on 7.x must upgrade to 7.29.0 or higher, and applications on 8.x must upgrade to 8.9.0 or higher.
If library upgrades cannot be immediately scheduled, temporary mitigation must be enforced at the application layer. Developers must apply a strict regular expression to sanitize domain inputs before passing them to the setCookie utility. This validation filter must reject any inputs containing semicolons, spaces, or control characters.
// Temporary input-level sanitization filter
const RFC_1123_DOMAIN_REGEX = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
function sanitizeDomain(domainInput) {
const trimmed = domainInput.trim();
if (trimmed === '') return ' ';
if (!RFC_1123_DOMAIN_REGEX.test(trimmed) || trimmed.length > 255) {
throw new Error('Security Violation: Invalid domain configuration input');
}
return trimmed;
}Security teams must verify nested dependency trees using dependency-lock audit tools to ensure older versions of Undici are not introduced transitively via dependent packages.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
undici Node.js / OpenJS Foundation | < 6.28.0 | 6.28.0 |
undici Node.js / OpenJS Foundation | >= 7.0.0 < 7.29.0 | 7.29.0 |
undici Node.js / OpenJS Foundation | >= 8.0.0 < 8.9.0 | 8.9.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-74 |
| Attack Vector | Network |
| CVSS v3.1 Score | 4.8 |
| Exploit Status | poc |
| CISA KEV Status | No |
| Ransomware Association | No |
The software constructs an output using input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the structure of the output when processed by a downstream component.
A medium-severity vulnerability in Undici's retry interceptor causes body-length mismatches with the Content-Length header during HTTP 206 response resumption. Forwarding these inconsistent headers downstream leads to HTTP response desynchronization, connection hangs, or potential protocol smuggling.
An interpretation conflict (CWE-436) in the cache interceptor of the undici HTTP client for Node.js causes whitespace-padded Cache-Control directives to be parsed incorrectly, leading to shared cache pollution and the unauthorized disclosure of sensitive, private, or authenticated user information (CWE-524).
CVE-2026-15157 details an improper neutralization of CRLF sequences ('CRLF Injection') within undici, a widely used Node.js HTTP/1.1 client. The vulnerability is triggered when processing request bodies that exhibit a duck-typed blob-like interface. When an application accepts untrusted data and assigns it to the .type property of such an object without setting an explicit Content-Type on the request, undici appends the value directly to the outgoing headers array without validating it against control characters. This allows remote attackers to inject carriage return and line feed sequences, culminating in arbitrary header injection, HTTP response splitting, or HTTP request smuggling.
A trust-boundary bypass and Server-Side Request Forgery (SSRF) vulnerability exists in the ip-address library versions 10.1.1 through 10.2.0 due to structural input misclassification. The library fails to resolve and normalize transition IP notations, such as IPv4-mapped IPv6 (::ffff:0:0/96) and NAT64 (64:ff9b::/96) addresses, to their embedded IPv4 representations prior to evaluation. Consequently, standard security validation checks (e.g., isLoopback, isLinkLocal, isULA) return false for these addresses. This allows remote attackers to bypass application-level IP address filters, gaining unauthorized access to internal resources, cloud metadata interfaces, and local services on dual-stack hosts or environments utilizing NAT64 gateways.
A critical authentication bypass vulnerability (CVE-2026-18574) in Check Point Security Management and Multi-Domain Security Management (MDS) Servers allows unauthenticated remote attackers to execute arbitrary system commands with administrative privileges. The flaw stems from an alternate path authentication bypass (CWE-288) in the management interface daemons.
An input validation vulnerability in the npm package `ip-address` allows unauthenticated remote attackers to bypass Server-Side Request Forgery (SSRF) protections by appending a `/0` CIDR suffix to IP address strings. This causes the library's classification helper functions to incorrectly identify internal addresses as public, external addresses, while normalization helpers resolve the address back to its internal form during network connection establishment.