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
Published August 23, 2026Reviewed 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.

Prevention & Best Practices

To prevent vulnerabilities like CVE-2026-13697 in your Node.js applications:

1. Regular Dependency Updates

Implement automated dependency scanning and update workflows:

# Use npm audit to check for vulnerabilities
npm audit

# Use tools like Dependabot or Renovate Bot for automated PRs
# Configure in .github/dependabot.yml:
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"

2. Dependency Pinning for Critical Libraries

For security-critical dependencies like HTTP clients, consider exact version pinning:

{
  "dependencies": {
    "undici": "7.29.0",  // Exact version, not "^7.29.0"
  }
}

This prevents unexpected updates while still allowing you to control when upgrades occur.

3. Use Security Scanning Tools

Integrate vulnerability scanning into your CI/CD pipeline:

# Trivy for container and dependency scanning
trivy fs --severity HIGH,CRITICAL .

# Snyk for comprehensive vulnerability detection
snyk test

4. Implement Defense in Depth

Even with patched dependencies, implement additional security controls:

  • Input validation: Validate all external data, including HTTP responses
  • Rate limiting: Limit requests to external services to mitigate DoS risks
  • Error handling: Implement proper error handling to prevent information leakage
  • Monitoring: Log and monitor for suspicious patterns in HTTP responses

5. Follow OWASP Guidelines

Refer to OWASP resources for HTTP security:

  • OWASP Top 10: Understand common web application vulnerabilities
  • OWASP Cheat Sheet Series: Implement security controls based on best practices
  • CWE-20 (Improper Input Validation): Ensure all inputs, including HTTP headers, are validated

6. Dependency Review Process

Establish a process for reviewing dependency updates:

  1. Automated scanning: Use tools to identify vulnerable dependencies
  2. Impact assessment: Evaluate the severity and exploitability of vulnerabilities
  3. Testing: Test updates in staging before production deployment
  4. Documentation: Document security updates and their rationale

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.

References

Frequently Asked Questions

What is CVE-2026-13697 in undici?

CVE-2026-13697 is a vulnerability in the undici HTTP client library that allows attackers to exploit malformed Cache-Control headers to cause information disclosure or denial of service. The flaw exists in how undici parses and processes Cache-Control directives, allowing specially crafted headers to trigger unintended behavior.

How do you prevent Cache-Control header vulnerabilities in Node.js?

Always use the latest stable version of HTTP client libraries like undici, implement proper input validation for all HTTP headers, use dependency scanning tools like Trivy to detect known vulnerabilities, and consider implementing rate limiting and request validation at the application layer to prevent malicious header injection.

What CWE is information disclosure via malformed headers?

While CVE-2026-13697 doesn't map to a single CWE, it relates to CWE-20 (Improper Input Validation) and CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor). The vulnerability stems from inadequate validation of HTTP header directives, leading to both information leakage and availability issues.

Is upgrading undici enough to prevent this vulnerability?

Yes, upgrading to undici 7.29.0 or later fully resolves CVE-2026-13697. However, comprehensive security requires regularly updating all dependencies, implementing defense-in-depth strategies including input validation, monitoring for suspicious header patterns, and using automated vulnerability scanning to catch future issues early.

Can static analysis detect malformed header vulnerabilities?

Yes, static analysis tools like Trivy can detect known vulnerabilities such as CVE-2026-13697 by scanning dependency lock files (bun.lock, package-lock.json) and comparing versions against vulnerability databases. However, detecting novel header parsing vulnerabilities requires dynamic analysis and fuzzing techniques in addition to static scanning.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #2326

Related Articles

high

How Server-Side Request Forgery (SSRF) happens in Python Flask and how to fix it

A high-severity Server-Side Request Forgery (SSRF) vulnerability was discovered in `webui/backend/main.py` at line 6597 of the Posterizarr project. User-controlled `request.media_type` was interpolated directly into a URL used for server-side HTTP requests to The Movie Database (TMDB) API, allowing attackers to manipulate the destination of outbound requests. The fix introduces a strict allowlist that only permits `"movie"` or `"tv"` as valid media types.

high

How React Router SSR XSS in ScrollRestoration Happens and How to Fix It

CVE-2026-21884 is a high-severity cross-site scripting (XSS) vulnerability in React Router's ScrollRestoration component that affects server-side rendering (SSR) implementations. The vulnerability was introduced through unsafe handling of scroll position data that could be influenced by untrusted input. This fix upgrades react-router from version 7.9.5 to 8.3.0, replacing the vulnerable `cookie` dependency with `cookie-es` and removing the `set-cookie-parser` dependency entirely.

high

How Client-Side Denial of Service happens in Node.js FTP clients and how to fix it

CVE-2026-44240 is a client-side Denial of Service vulnerability in the `basic-ftp` Node.js package (versions prior to 5.3.1) caused by improper handling of unterminated multiline FTP server responses. An attacker controlling an FTP server—or capable of intercepting FTP traffic—could send a malformed response that causes the client to hang indefinitely. Upgrading `basic-ftp` to 5.3.1 and adding a package override in `package.json` closes the attack surface entirely.

high

How Route Guard Bypass via Path Traversal happens in Fastify and how to fix it

A high-severity path traversal vulnerability (CVE-2026-15074) in @fastify/static version 9.0.0 allowed attackers to bypass route guards and access restricted files. The agentchatbus-ts service was upgraded from @fastify/static 9.0.0 to 10.1.2, which includes proper path normalization to prevent directory traversal attacks.

high

How javascript.express.security.audit.express-check-csurf-middleware-usage.express-check-csurf-middleware-usage happens in Express.js and how to fix it

A publicly accessible Express.js API endpoint in `app/api/cameras.js` was missing CSRF protection, leaving state-changing requests (POST, PUT, DELETE, PATCH) vulnerable to cross-site request forgery attacks. The fix introduces Origin/Referer header validation middleware in `app/index.js` and removes a redundant Express instance from `cameras.js` that bypassed the application's middleware chain.

high

How Regular Expression Denial of Service happens in JavaScript and how to fix it

CVE-2026-33671 is a Regular Expression Denial of Service (ReDoS) vulnerability in the picomatch glob-matching library, triggered by specially crafted extglob patterns that cause catastrophic regex backtracking. The fix upgrades picomatch to version 4.0.4 (with overrides pinning all transitive copies) in the client's dependency tree, eliminating the vulnerable regex evaluation path. Left unpatched, any code path that passes user-influenced glob patterns to picomatch could be weaponized to stall a