Aug 4, 2026·6 min read·59 visits
An interpretation conflict in undici's cache parser fails to strip whitespace from Cache-Control directives, leading to unauthorized sharing of private cached data.
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-14643 identifies an interpretation conflict (CWE-436) within the Cache Interceptor component of undici, the default HTTP client for Node.js. This defect specifically impacts deployments where the Cache Interceptor is configured to operate in shared-cache mode (shared: true). When parsing HTTP response headers, the engine fails to adequately normalize whitespace in specific Cache-Control directives.\n\nThe primary risk associated with this vulnerability is the unintentional caching and subsequent reuse of HTTP responses containing sensitive, authenticated information (CWE-524). An attacker can leverage this parsing discrepancy to intercept private data destined for other authenticated users. The vulnerability occurs without direct user interaction and can be executed remotely over the network, though it requires specific caching configurations to be active.\n\nThis vulnerability represents a regression or an incomplete fix from a previous security advisory, CVE-2026-9678. The earlier fix omitted validation logic for optional whitespace (OWS) located around the equality sign or inside quoted arguments of qualified no-cache and private cache directives.
The root cause of CVE-2026-14643 lies in lib/util/cache.js inside the parseCacheControlHeader function of the undici library. This function is responsible for interpreting directives such as private="authorization" or no-cache="authorization". According to RFC 9111, if an upstream server marks specific headers as private or no-cache, a shared cache must not store or serve those portions of the response to other clients.\n\nWhen the upstream server responds with optional whitespace around the equals sign or inside the quoted parameters, the parser's logic breaks. For example, if the upstream server returns Cache-Control: private=" authorization", the parser processes the value verbatim. Because it fails to sanitize or trim leading and trailing whitespaces, it stores the field restriction as " authorization" instead of "authorization".\n\nDuring subsequent request matching, the cache engine performs a strict equality lookup between the client's request headers and the stored restricted headers array. Because " authorization" containing whitespace does not match "authorization", the comparison evaluates to false. The cache interceptor then erroneously concludes that no private or restricted headers are present in the cached entry, allowing the cached response to be served to unauthenticated users.
To understand the exact failure mechanism, we examine the difference in lib/util/cache.js before and after the applied patch. In the vulnerable version, the array of extracted headers was populated directly from the parsed token values without trimming whitespace characters.\n\nBelow is the comparison of the parser logic, highlighting how the patch normalizes the headers using JavaScript's .trim() method:\n\njavascript\n// Vulnerable logic\nif (key in output) {\n output[key] = output[key].concat(headers)\n} else {\n output[key] = headers\n}\n\n// Patched logic\nfor (let j = 0; j < headers.length; j++) {\n headers[j] = headers[j].trim()\n}\nif (key in output) {\n output[key] = output[key].concat(headers)\n} else {\n output[key] = headers\n}\n\n\nAdditionally, the patch addresses single-value scenarios, such as no-cache="some-header". Instead of pushing the raw string directly into the output array, it now binds the trimmed value to a new constant fieldName before storage:\n\njavascript\n// Patched single-value handling\nconst fieldName = value.trim()\nif (key in output) {\n output[key] = output[key].concat(fieldName)\n} else {\n output[key] = [fieldName]\n}\n\n\nThis corrective action eliminates any whitespace-padded headers from the final restricted list. It ensures that standard matching routines (such as Array.prototype.includes) perform accurately against sanitized request keys during cache evaluation.
To successfully exploit this vulnerability, an attacker must target an application utilizing an affected version of undici with the Cache Interceptor running in shared-cache mode. The upstream server must also return a Cache-Control header that includes whitespace-padded qualified directives. An example of such a header is Cache-Control: public, max-age=120, private=" authorization".\n\nBelow is a sequence diagram illustrating the flow of the exploitation technique:\n\nmermaid\ngraph LR\n Victim["Victim (Authenticated)"] -->|1. GET /profile with Auth Header| Proxy["Undici Shared Cache Client"]\n Proxy -->|2. Forward Request| Origin["Upstream Server (Origin)"]\n Origin -->|3. Response with private=' authorization'| Proxy\n Proxy -->|4. Parse failure: Stores cache as public| Cache[("Shared Cache Storage")]\n Attacker["Attacker (Unauthenticated)"] -->|5. GET /profile| Proxy\n Proxy -->|6. Checks Cache: Match Fails due to ' authorization' whitespace mismatch| Cache\n Proxy <--|7. Serves Cached Authenticated Response| Attacker\n\n\nFirst, an authenticated user (the victim) initiates a request to the application containing their authentication credentials. The upstream server returns the restricted content accompanied by the malformed Cache-Control header. Due to the parsing flaw, undici saves the response in the shared cache, ignoring the directive that restricts caching of the Authorization header's content.\n\nSecond, the attacker sends an unauthenticated request for the same endpoint. The proxy retrieves the cached response belonging to the victim. Because the security check fails to identify the cached response as private, the server returns the sensitive, authenticated data directly to the unauthenticated attacker.
The CVSS v3.1 score for CVE-2026-14643 is assessed at 5.9 (Medium Severity). The vulnerability has a high confidentiality impact because it allows unauthorized third parties to retrieve session tokens, personal details, or sensitive transaction records. It does not directly compromise system integrity or service availability, leading to a score of none for those metrics.\n\nThe attack complexity is rated as high. This classification reflects the multiple operational prerequisites needed to trigger the flaw, including the active shared cache configuration, exact request path overlap, and specific whitespace patterns generated by the upstream service. However, because no prior privileges or user interaction are required, the entry point for exploitation remains accessible to any network-based actor.\n\nEPSS data indicates a low overall probability of exploit automation in the wild, sitting at approximately 0.23%. This rating is consistent with the lack of active exploitation reports in CISA's Known Exploited Vulnerabilities (KEV) catalog. Nonetheless, in environments where Node.js microservices act as reverse proxies or API gateways using undici, the risk of silent data leakage remains a significant concern.
The primary remediation path is upgrading the undici dependency within the application. For deployments relying on the 7.x release train, the package must be updated to version 7.29.0 or higher. For deployments using the 8.x branch, the dependency must be updated to version 8.9.0 or higher.\n\nIf an immediate dependency upgrade is impossible due to breaking changes or legacy constraints, several temporary workarounds can mitigate the risk. Network administrators can configure reverse proxies or application delivery controllers (such as Nginx, Cloudflare, or AWS CloudFront) to strip or sanitize whitespace inside Cache-Control headers before they reach the Node.js application. This prevents the parser from encountering malformed inputs.\n\nAdditionally, developers can temporarily disable the Cache Interceptor or reconfigure it to run in private caching mode. This modification prevents the storage of shared cache records entirely, neutralizing the vector of cross-user information disclosure at the cost of increased upstream traffic.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
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-436 / CWE-524 |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 5.9 (Medium) |
| EPSS Score | 0.00229 |
| Impact | Confidentiality (High) |
| Exploit Status | Proof-of-Concept (PoC) |
| KEV Status | Not Listed |
The product does not properly neutralize whitespace differences when comparing structured elements, leading to interpretation discrepancies.
An origin trust boundary failure in the Ruby mechanize library (prior to v2.14.1) allows unauthenticated remote web servers to harvest sensitive global request headers, such as Authorization Bearer tokens and cookies, by utilizing HTML-level meta-refresh redirection tags. Standard HTTP-level redirect boundaries were not applied to document-level redirects, creating a vector for cross-origin credential leakage during automated crawls.
CVE-2026-107718 is a medium-severity Open Redirect vulnerability in the core HTTP server package of the AdonisJS Node.js framework. Prior to versions 8.2.3 and 9.3.0, the framework built route paths by directly interpolating dynamic parameters and wildcard segments without URI encoding. If an application routes attacker-controlled input directly to a dynamic first path segment and uses the generated route URL as a redirect destination, a leading slash can produce a scheme-relative external URL. Modern web browsers process scheme-relative URLs by redirecting the client to the specified external domain, exposing users to credential harvesting, social engineering, and session hijacking. This vulnerability affects all applications running unpatched configurations where input validation is not explicitly implemented before generating paths.
CVE-2026-107725 is a critical security bypass in Hazelcast where missing authorization checks in the MapPermission class permit unprivileged clients to issue queries containing aggregators or projections. This architectural oversight allows attackers to run arbitrary code on the cluster servers under the privileges of the active Hazelcast process.
A stored Cross-Site Scripting (XSS) vulnerability was identified in Indico, an open-source event management system developed at CERN, prior to version 3.3.13. The vulnerability stems from weak URL validation in custom link fields and lack of HTML sanitization during Marshmallow serialization of event notes. This allows authenticated attackers with event modification privileges to inject malicious payloads that execute in the browser of users viewing the event pages or collaborating on notes.
A technical analysis of CVE-2026-107397, a stored Cross-Site Scripting (XSS) vulnerability in Indico's collaborative notes editor and custom link generation fields. Prior to version 3.3.13, Marshmallow serialization schemas omitted HTML sanitization during conflict resolution, and form validators failed to enforce strict URI schemes, enabling authenticated low-privilege attackers to execute arbitrary JavaScript.
An authorization bypass vulnerability exists in the legacy session export API of Indico, an open-source event management system developed at CERN. Due to a missing object-level access check, authenticated users can bypass configuration-level restrictions to extract private session metadata (including session titles, descriptions, and list of conveners) from events that they are otherwise authorized to view.