Back to Blog
critical SEVERITY5 min read

How Information Disclosure via Malformed Cache-Control Directives Happens in Node.js and How to Fix It

A critical vulnerability (CVE-2026-13697) was discovered in the undici HTTP client library, allowing attackers to exploit malformed Cache-Control directives for information disclosure and denial of service. This fix upgrades undici from version 7.25.0 to 7.29.0 using npm overrides to ensure all nested dependencies receive the patched version.

O
By Orbis AppSec
Published August 29, 2026Reviewed August 29, 2026

Answer Summary

CVE-2026-13697 is an information disclosure and denial of service vulnerability in undici, a popular Node.js HTTP client. The flaw exists in how undici parses Cache-Control headers, allowing malformed directives to leak sensitive information or crash the application. The fix involves upgrading undici to version 7.29.0 or later and using npm overrides to ensure transitive dependencies also use the patched version.

Vulnerability at a Glance

cweCWE-400 (Uncontrolled Resource Consumption) / CWE-200 (Information Exposure)
fixUpgrade undici to 7.29.0 and enforce via npm overrides
riskAttackers can craft malicious HTTP responses to leak data or crash applications
languageJavaScript/Node.js
root causeImproper parsing of malformed Cache-Control directives in undici HTTP client
vulnerabilityInformation Disclosure / Denial of Service via HTTP Header Parsing

Introduction

In this repository's package-lock.json, Trivy flagged a high-severity vulnerability in the undici HTTP client library at version 7.25.0. The undici package is a fast, spec-compliant HTTP/1.1 client for Node.js that's widely used—including as the underlying fetch implementation in modern Node.js versions. The vulnerability, tracked as CVE-2026-13697, exists in how undici processes Cache-Control response headers, creating a pathway for both information disclosure and denial of service attacks.

What makes this particularly concerning is that undici often exists deep in dependency trees. Even if your direct dependencies don't explicitly list undici, it may be pulled in transitively through frameworks, testing libraries, or API clients. This is exactly the scenario we encountered here—the vulnerability was flagged in the dependency tree with the assessment "present in dependency tree, not confirmed reachable."

The Vulnerability Explained

CVE-2026-13697 targets the Cache-Control header parsing logic within undici. When an HTTP response contains malformed Cache-Control directives, the vulnerable versions of undici fail to properly validate and sanitize these values before processing them.

How Cache-Control Parsing Should Work

A typical Cache-Control header looks like this:

Cache-Control: max-age=3600, public, no-transform

The parser should extract these directives and their values safely, rejecting or sanitizing malformed input.

The Attack Vector

An attacker controlling an HTTP response (such as through a compromised API endpoint, man-in-the-middle attack, or malicious redirect) could craft a response with specially malformed Cache-Control directives:

Cache-Control: max-age=9999999999999999999999, private, [malicious-payload]

In vulnerable versions, this malformed input could:

  1. Information Disclosure: Cause the parser to expose internal state, memory contents, or cached data from other requests
  2. Denial of Service: Trigger excessive resource consumption, infinite loops, or crashes in the parsing logic

Real-World Impact

Consider a scenario where your Node.js application makes API calls to external services:

// Your application fetching data from an external API
const response = await fetch('https://api.external-service.com/data');
const data = await response.json();

If api.external-service.com is compromised or an attacker can intercept the response, they could inject malformed Cache-Control headers that exploit this vulnerability. The impact ranges from application crashes (affecting availability) to potential leakage of sensitive information from your application's memory or cache.

The Fix

The fix involves two key changes to ensure the vulnerable undici version is replaced throughout the entire dependency tree.

Before the Fix

The package-lock.json specified undici at the vulnerable version:

"node_modules/undici": {
  "version": "7.25.0",
  "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz",
  "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==",

After the Fix

The version was upgraded to 7.29.0:

"node_modules/undici": {
  "version": "7.29.0",
  "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz",
  "integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==",

The Critical Addition: npm Overrides

Simply updating the direct dependency isn't sufficient. The fix adds an npm override in package.json:

"overrides": {
  "tar": "7.5.21",
  "brace-expansion": "5.0.9",
  "undici": "7.29.0"
}

This override is crucial because it forces all instances of undici in the dependency tree—including those pulled in by transitive dependencies—to use version 7.29.0. Without this override, a nested dependency could still resolve to the vulnerable 7.25.0 version.

Additional Change: @capacitor/core

The fix also removed the peer: true designation from @capacitor/core:

-      "peer": true,
       "dependencies": {
         "tslib": "^2.1.0"
       }

This change ensures the package is properly included in the dependency resolution, preventing potential version conflicts that could undermine the security fix.

Prevention & Best Practices

1. Use npm Overrides for Security Patches

When patching transitive dependencies, always use npm overrides (npm 8.3+) or yarn resolutions:

{
  "overrides": {
    "vulnerable-package": "^patched-version"
  }
}

2. Implement Automated Dependency Scanning

Integrate tools like Trivy, Snyk, or npm audit into your CI/CD pipeline:

# Example GitHub Actions step
- name: Run Trivy vulnerability scanner
  uses: aquasecurity/trivy-action@master
  with:
    scan-type: 'fs'
    scan-ref: '.'

3. Validate External HTTP Responses

Even with patched libraries, implement defensive coding practices:

// Add response validation
const response = await fetch(url);
const cacheControl = response.headers.get('cache-control');

// Validate header format before processing
if (cacheControl && !isValidCacheControl(cacheControl)) {
  console.warn('Suspicious Cache-Control header detected');
  // Handle appropriately
}

4. Keep Dependencies Updated

Establish a regular cadence for dependency updates. Consider using tools like Dependabot or Renovate for automated PR creation.

5. Monitor Security Advisories

Subscribe to security advisories for critical dependencies:
- Node.js Security Working Group
- npm Security Advisories
- GitHub Security Advisories

Key Takeaways

  • Transitive dependencies require explicit overrides: The vulnerable undici version could exist in nested dependencies even after updating direct dependencies—npm overrides ensure comprehensive patching
  • HTTP client libraries are high-value targets: undici's role in processing untrusted server responses makes header parsing vulnerabilities particularly dangerous
  • "Not confirmed reachable" still requires action: Even when a vulnerability isn't confirmed reachable in your specific code paths, the risk of future code changes or indirect exploitation warrants patching
  • Cache-Control headers are untrusted input: Any data from HTTP responses, including headers, should be treated as potentially malicious
  • Version pinning in overrides provides defense-in-depth: The explicit "undici": "7.29.0" override prevents dependency resolution from accidentally downgrading to vulnerable versions

How Orbis AppSec Detected This

  • Source: HTTP response headers from external servers, specifically Cache-Control directives processed by the undici HTTP client
  • Sink: undici's internal Cache-Control parsing logic in versions prior to 7.29.0
  • Missing control: Proper validation and sanitization of malformed Cache-Control directive values before processing
  • CWE: CWE-400 (Uncontrolled Resource Consumption) and CWE-200 (Exposure of Sensitive Information)
  • Fix: Upgraded undici to version 7.29.0 via npm overrides to ensure all dependency tree instances use the patched version

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2026-13697 in undici demonstrates how vulnerabilities in HTTP client libraries can have far-reaching security implications. The malformed Cache-Control directive parsing flaw could enable both information disclosure and denial of service attacks against any Node.js application using affected versions.

The fix—upgrading to undici 7.29.0 with npm overrides—is straightforward but highlights an important lesson: transitive dependencies require explicit management. Simply updating your direct dependencies isn't always sufficient; you need mechanisms like npm overrides to ensure security patches propagate throughout your entire dependency tree.

As developers, we must treat all external input—including HTTP headers—as potentially malicious and ensure our dependencies are regularly updated and scanned for vulnerabilities.

References

Frequently Asked Questions

What is CVE-2026-13697?

CVE-2026-13697 is a vulnerability in the undici HTTP client where malformed Cache-Control headers can cause information disclosure or denial of service through improper header parsing logic.

How do you prevent HTTP header parsing vulnerabilities in Node.js?

Keep HTTP client libraries updated, validate and sanitize incoming headers, implement request timeouts, and use npm overrides to enforce patched versions across all dependencies.

What CWE is this vulnerability?

This vulnerability maps to CWE-400 (Uncontrolled Resource Consumption) for the DoS aspect and CWE-200 (Information Exposure) for the information disclosure component.

Is upgrading the direct dependency enough to prevent this vulnerability?

No, transitive dependencies may still use vulnerable versions. Using npm overrides ensures all instances of undici in your dependency tree use the patched version.

Can static analysis detect HTTP header parsing vulnerabilities?

Yes, tools like Trivy can detect known CVEs in dependencies by scanning package-lock.json files and matching against vulnerability databases.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #9

Related Articles

high

How Denial-of-Service via Unbounded Array Expansion happens in JavaScript and how to fix it

CVE-2026-69152 is a high-severity Denial-of-Service vulnerability in the `brace-expansion` npm package, where crafted input strings cause the library to generate unbounded intermediate arrays that exhaust memory and CPU—bypassing the earlier CVE-2026-14257 mitigation. The fix upgrades `brace-expansion` across all affected version branches (1.x, 2.x, 3.x, 5.x) and pins the safe version in `package.json` to prevent regression.

critical

How Unsandboxed Plugin Execution Happens in Node.js and How to Fix It

A critical vulnerability (CVE-2026-54466) was discovered in the `websocket-driver` dependency (version 0.7.4), which handles WebSocket protocol framing and I/O. The fix upgrades the package to version 0.7.5 via an npm override in `package.json` and an updated lockfile, closing a WebSocket frame-parsing flaw that could allow attackers to inject or manipulate WebSocket traffic. This dependency-level fix is essential because the vulnerable library sits in the application's dependency tree and proce

high

How Missing Minimum Release Age Configuration in pnpm Workspaces Happens and How to Fix It

A Node.js library's pnpm workspace configuration lacked the `minimumReleaseAge` setting, leaving it vulnerable to malicious or unstable newly-published packages. By adding a 7-day waiting period (10,080 minutes) along with additional hardening measures like `blockExoticSubdeps` and `trustPolicy`, the project now has robust defense against supply chain attacks targeting its dependencies.

critical

How CORS Misconfiguration happens in Node.js with Hono and how to fix it

CVE-2026-54290 is a HIGH severity CORS misconfiguration in the Hono web framework where the CORS middleware incorrectly reflects any `Origin` header back to the client — including credentials — when the `origin` option defaults to a wildcard. Upgrading `hono` from `4.12.16` to `4.12.34` in `package-lock.json` and pinning the version via `overrides` in `package.json` closes the vulnerability. Left unpatched, this flaw could allow malicious cross-origin sites to make credentialed requests and read

high

How Denial of Service via Infinite Loop happens in Node.js and how to fix it

A critical Denial of Service vulnerability (CVE-2026-67213) in the nanoid package allowed attackers to trigger infinite loops during random ID generation. This fix upgrades nanoid from version 3.3.11 to 3.3.18 using npm overrides, eliminating the infinite loop condition in the customAlphabet function that could crash Node.js applications.

critical

How WebSocket Protocol Handler Vulnerabilities happen in Node.js Dependencies and how to fix it

A critical vulnerability (CVE-2026-54466) was discovered in websocket-driver version 0.7.4, a WebSocket protocol handler used in the dependency tree. The vulnerability allowed attackers to exploit flaws in WebSocket frame parsing, potentially leading to denial of service or protocol-level attacks. The fix upgraded websocket-driver to version 0.7.5, which patches the protocol handling vulnerabilities and hardens input validation for untrusted WebSocket frames.