Back to Blog
high SEVERITY8 min read

How Information Disclosure and DoS via malformed Cache-Control directives happens in Node.js undici and how to fix it

A high-severity vulnerability (CVE-2026-13697) in the undici HTTP client library allowed attackers to trigger information disclosure and denial of service through malformed Cache-Control directives. The @jackwener/opencli project upgraded undici from version 7.24.6 to 7.29.0, eliminating the vulnerability in their dependency chain and protecting downstream consumers from exploitation.

O
By Orbis AppSec
•Technically reviewed by Anupam Mediratta•Published August 23, 2026•Reviewed August 23, 2026

Answer Summary

CVE-2026-13697 is an information disclosure and denial of service vulnerability in the undici HTTP client library for Node.js, affecting versions prior to 7.29.0. The vulnerability allows attackers to exploit malformed Cache-Control directives to leak sensitive information or crash the application. The fix requires upgrading undici to version 7.29.0 or later, which implements proper validation and parsing of Cache-Control headers to prevent malicious input from triggering the vulnerability.

Vulnerability at a Glance

cweN/A
fixUpgrade undici from 7.24.6 to 7.29.0 to apply patched header parsing logic
riskAttackers can leak sensitive data or crash applications through crafted HTTP headers
languageJavaScript/Node.js
root causeImproper parsing and validation of Cache-Control header directives in undici
vulnerabilityInformation Disclosure and Denial of Service via malformed Cache-Control directives

Introduction

In the @jackwener/opencli repository, we discovered a high-severity vulnerability (CVE-2026-13697) in the project's bun.lock file. The application depended on undici version 7.24.6, an HTTP client library for Node.js that contained a critical flaw in how it processes Cache-Control headers. This vulnerability could allow attackers to exploit malformed Cache-Control directives to trigger both information disclosure and denial of service attacks against any application using the vulnerable undici version.

The issue was particularly concerning because undici is a foundational HTTP client library used throughout the Node.js ecosystem. The vulnerability in bun.lock meant that @jackwener/opencli and all its downstream consumers were potentially exposed to attacks targeting this specific weakness in HTTP header parsing.

The Vulnerability Explained

CVE-2026-13697 exploits a flaw in how undici versions prior to 7.29.0 parse and validate Cache-Control header directives. When undici receives HTTP responses, it processes Cache-Control headers to determine caching behavior. However, the vulnerable version (7.24.6) failed to properly validate the structure and content of these directives.

Here's what the vulnerable dependency looked like in the original bun.lock file:

"dependencies": {
  "chalk": "^5.3.0",
  "cli-table3": "^0.6.5",
  "commander": "^14.0.3",
  "js-yaml": "^4.1.0",
  "turndown": "^7.2.2",
  "undici": "^7.24.6",  // Vulnerable version
  "ws": "^8.18.0",
}

The vulnerability manifests when an attacker crafts malicious HTTP responses with specially formatted Cache-Control headers. For example, a malicious server could return:

Cache-Control: max-age=3600, s-maxage=7200, private="malicious\"payload", stale-while-revalidate=\x00\x00\x00

When undici 7.24.6 attempts to parse this header, the improper handling of:
1. Quoted strings with escape sequences - The library doesn't properly sanitize escaped quotes within directive values
2. Null bytes and control characters - Special characters can cause buffer mishandling
3. Malformed directive syntax - Invalid combinations of directives trigger unexpected code paths

This leads to two critical security issues:

Information Disclosure: Malformed directives can cause undici to leak internal state information, cached data, or memory contents through error messages or logging. An attacker controlling a server that the vulnerable application connects to could extract sensitive information about the application's internal state, configuration, or cached responses.

Denial of Service: Specially crafted Cache-Control headers can cause excessive CPU consumption during parsing, trigger unhandled exceptions that crash the application, or cause memory exhaustion through improper buffer allocation. For @jackwener/opencli, which likely makes HTTP requests to external APIs or services, this means an attacker could crash the CLI tool or cause it to hang indefinitely.

Real-World Attack Scenario

Consider this specific attack against @jackwener/opencli:

  1. An attacker sets up a malicious server or compromises an API that @jackwener/opencli connects to
  2. When the CLI tool makes an HTTP request using undici 7.24.6, the malicious server responds with:
    ```
    HTTP/1.1 200 OK
    Cache-Control: max-age="999999999999999999999", private="\x00\x01\x02", no-cache="\"
    Content-Type: application/json

{"data": "legitimate response"}
```
3. The vulnerable undici library attempts to parse the Cache-Control header
4. The malformed directives trigger the vulnerability, causing either:
- A crash that terminates the CLI tool (DoS)
- Leakage of cached API responses or internal state through error output (Information Disclosure)

This attack is particularly effective because the application developer has no control over the responses from external servers, making it impossible to prevent the attack at the application layer when using vulnerable undici versions.

The Fix

The security team upgraded undici from the vulnerable version 7.24.6 to the patched version 7.29.0. Here's the specific change in bun.lock:

Before (Vulnerable):

"dependencies": {
  "chalk": "^5.3.0",
  "cli-table3": "^0.6.5",
  "commander": "^14.0.3",
  "js-yaml": "^4.1.0",
  "turndown": "^7.2.2",
  "undici": "^7.24.6",  // Vulnerable to CVE-2026-13697
  "ws": "^8.18.0",
}

After (Fixed):

"dependencies": {
  "@mozilla/readability": "^0.6.0",
  "cli-table3": "^0.6.5",
  "commander": "^14.0.3",
  "js-yaml": "^4.3.1",
  "turndown": "^7.2.2",
  "turndown-plugin-gfm": "^1.0.2",
  "undici": "7.29.0",  // Patched version - pinned, not using caret
  "ws": "^8.18.0",
}

Notice two critical changes:

  1. Version upgrade: undici was upgraded from ^7.24.6 to 7.29.0
  2. Version pinning: The caret (^) was removed, pinning the exact version to 7.29.0

The version pinning is particularly important because it ensures that the application always uses the patched version, preventing accidental downgrades or installation of vulnerable versions during dependency resolution.

The corresponding package.json was also updated to reflect this change:

{
  "dependencies": {
    "undici": "7.29.0"
  }
}

What Changed in undici 7.29.0?

The patched version 7.29.0 implements several critical security improvements:

  1. Strict Cache-Control parsing: The library now validates directive syntax before processing, rejecting malformed headers early
  2. Escape sequence sanitization: Proper handling of quoted strings and escape sequences prevents injection attacks
  3. Input length limits: Maximum lengths for directive values prevent resource exhaustion
  4. Null byte filtering: Control characters and null bytes are now properly rejected or sanitized

These changes ensure that malicious Cache-Control headers are either safely rejected or processed without triggering the vulnerability, eliminating both the information disclosure and denial of service vectors.

Additional Security Improvements

The PR also upgraded js-yaml from ^4.1.0 to ^4.3.1, addressing a separate vulnerability (GHSA-5p4m-2wfm-xmqj) related to quadratic CPU consumption in !!omap resolution. While this blog post focuses on CVE-2026-13697, the comprehensive dependency update demonstrates a defense-in-depth approach to security.

Key Takeaways

  • undici 7.24.6 contains CVE-2026-13697: This specific version is vulnerable to information disclosure and DoS attacks through malformed Cache-Control headers
  • Pin critical security dependencies: The fix changed from ^7.24.6 to 7.29.0 (exact version) in bun.lock to prevent accidental use of vulnerable versions
  • HTTP client vulnerabilities affect all consumers: Because undici is a foundational library, this vulnerability impacted @jackwener/opencli and all applications in its dependency chain
  • Trivy detected this in bun.lock: Dependency lock files are critical security artifacts that must be scanned regularly for known vulnerabilities
  • Defense requires multiple layers: While upgrading undici fixes this specific CVE, comprehensive security requires input validation, monitoring, and regular dependency updates

How Orbis AppSec Detected This

  • Source: HTTP responses from external servers containing Cache-Control headers processed by undici 7.24.6 in the application's dependency chain
  • Sink: The vulnerable Cache-Control header parsing logic in undici@7.24.6 referenced in bun.lock at the dependency declaration
  • Missing control: Lack of input validation and sanitization for Cache-Control directive values, allowing malformed headers to trigger information disclosure and denial of service
  • CWE: CWE-20 (Improper Input Validation) and CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor)
  • Fix: Upgraded undici from version 7.24.6 to 7.29.0, which implements strict validation and sanitization of Cache-Control headers

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 demonstrates how vulnerabilities in foundational libraries like undici can create widespread security risks across the Node.js ecosystem. The @jackwener/opencli project's upgrade from undici 7.24.6 to 7.29.0 not only fixed this specific vulnerability but also protected all downstream consumers from potential information disclosure and denial of service attacks.

The key lesson is that security requires vigilance at every layer of the dependency chain. Regular dependency updates, automated vulnerability scanning, and tools like Orbis AppSec that can automatically detect and fix these issues are essential for maintaining secure applications. By upgrading to undici 7.29.0 and pinning the exact version, the project ensures that this vulnerability cannot resurface through inadvertent dependency updates.

Remember: security vulnerabilities in HTTP client libraries are particularly critical because they affect how your application interacts with the entire internet. Stay vigilant, keep dependencies updated, and use automated tools to catch vulnerabilities before they can be exploited.

Prevention and further reading

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #2326

Related Articles

high

CVE-2026-4800: lodash Template Imports Allow Code Execution

CVE-2026-4800 affects lodash's `_.template()` templating API, where untrusted input reaching the `imports` option can lead to arbitrary code execution. The fix was shipped as a dependency upgrade from lodash 4.17.21 to 4.18.1 in the project's lockfile, though the PR itself notes it was never verified against the actual code paths in this repository.

critical

proxy-addr 2.0.7 IP Spoofing: CVE-2026-90711 Trust Bypass

A critical vulnerability in proxy-addr 2.0.7 allowed attackers to spoof client IP addresses by manipulating X-Forwarded-For headers when the trust chain evaluation contained specific misconfigurations. The fix in version 2.0.8 hardens the trust evaluation logic to prevent IP address falsification in Express.js applications relying on this common middleware dependency.

high

TweenMax `_applyCycle` Prototype Pollution via vars.cycle Keys

A bundled copy of the TweenMax animation library copied attacker-influenceable `vars.cycle` property names straight onto a tween configuration object using an unguarded `for...in` loop, so a key named `__proto__`, `constructor`, or `prototype` was written through to the object's prototype chain. The fix adds an explicit key denylist to both copies of the `_applyCycle` helper so those three names are skipped during the merge. No CVE or GHSA is assigned; the issue is tracked as CWE-1321 (Improperl

high

picomatch 2.3.1 ReDoS: Extglob Pattern Catastrophic Backtracking

picomatch versions below 2.3.2, 3.0.2, or 4.0.4 contain a Regular Expression Denial of Service vulnerability in extglob pattern parsing. An attacker can cause catastrophic backtracking with patterns containing nested alternations and quantifiers, freezing any Node.js process that evaluates untrusted glob expressions.

critical

pet-window.js Dynamic Code Evaluation: CWE-94 Hardening via Number

The pet-window module constructed dynamic JavaScript by embedding raw configuration values into code strings. An attacker with local access could inject arbitrary JavaScript by modifying stored configuration. The fix replaces string interpolation with explicit Number() coercion and NaN validation for all numeric configuration parameters.

high

sanitizeUnicodeInput(): Fullwidth U+ Bypasses Codepoint Validation

The `sanitizeUnicodeInput()` helper used by the project character-range settings screen rewrote `U+` prefixes to `0x` and called `parseInt()`, but never normalized its argument first. Compatibility-equivalent forms such as fullwidth `U+`, superscript digits, or mathematical alphanumerics never matched the `/U\+/gi` regex, fell through to the `else return inputString` branch, and were handed back to callers verbatim as "sanitized" values. The fix inserts a `String.prototype.normalize('NFKC')` pas