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:
- An attacker sets up a malicious server or compromises an API that @jackwener/opencli connects to
- 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:
- Version upgrade: undici was upgraded from
^7.24.6to7.29.0 - Version pinning: The caret (
^) was removed, pinning the exact version to7.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:
- Strict Cache-Control parsing: The library now validates directive syntax before processing, rejecting malformed headers early
- Escape sequence sanitization: Proper handling of quoted strings and escape sequences prevents injection attacks
- Input length limits: Maximum lengths for directive values prevent resource exhaustion
- 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:
- Automated scanning: Use tools to identify vulnerable dependencies
- Impact assessment: Evaluate the severity and exploitability of vulnerabilities
- Testing: Test updates in staging before production deployment
- 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.6to7.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.6referenced inbun.lockat 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.