Introduction
In a production Node.js application, we discovered a high-severity vulnerability lurking in the OpenTelemetry observability stack. The @opentelemetry/propagator-jaeger package at version 2.8.0, listed in package-lock.json, contained CVE-2026-59892—a denial of service flaw that could crash the entire application through a single malformed HTTP header.
This vulnerability is particularly insidious because OpenTelemetry propagators operate on every incoming request that carries distributed tracing headers. The Jaeger propagator, which handles the uber-trace-id header format, failed to properly validate malformed input before processing, allowing attackers to trigger resource exhaustion or crashes.
The Vulnerability Explained
What Happens Under the Hood
The @opentelemetry/propagator-jaeger package is responsible for extracting and injecting Jaeger-format trace context from HTTP headers. When a request arrives with an uber-trace-id header, the propagator parses it to extract trace ID, span ID, parent span ID, and sampling flags.
In version 2.8.0, the header decoding logic lacked proper bounds checking and input validation. An attacker could craft a malicious uber-trace-id header with:
- Extremely long strings that consume excessive memory during parsing
- Malformed encoding sequences that trigger infinite loops or stack overflows
- Special characters that cause the decoder to enter error states without proper cleanup
The Vulnerable Dependency Chain
Looking at the original package-lock.json:
"node_modules/@opentelemetry/propagator-jaeger": {
"version": "2.8.0",
"license": "Apache-2.0",
"dependencies": {
"@opentelemetry/core": "2.8.0"
}
}
The propagator-jaeger 2.8.0 depends on @opentelemetry/core 2.8.0, which also contained related parsing vulnerabilities. This meant the entire trace context handling pipeline was affected.
Attack Scenario
An attacker targeting this application could:
- Identify that the application uses OpenTelemetry (often visible through response headers or public documentation)
- Send HTTP requests with crafted
uber-trace-idheaders containing malformed data - Each malformed header triggers the vulnerable parsing code path
- The application crashes or becomes unresponsive, denying service to legitimate users
# Example malicious request
curl -H "uber-trace-id: $(python -c 'print("A"*1000000 + ":" + "B"*1000000)')" \
https://target-application.com/api/endpoint
This single request could exhaust memory or CPU resources, taking down the service.
The Fix
Dependency Upgrade
The fix involved upgrading @opentelemetry/propagator-jaeger from 2.8.0 to 2.9.0. This was accomplished through two changes:
1. Adding an npm override in package.json:
"overrides": {
"refractor": "4.8.0",
"@opentelemetry/propagator-jaeger": "2.9.0"
}
The override ensures that regardless of what version other dependencies request, npm will resolve to the patched 2.9.0 version.
2. Updated package-lock.json with the new version:
"node_modules/@opentelemetry/propagator-jaeger": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-2.9.0.tgz",
"integrity": "sha512-4mYGty27rYvSM0jtp1ZUOqd3LfVRCYg9H5G9OFzSx5HViYToU21MFhWfco7x1HwXr7ER8yGOiCIHZUwjPksc0Q==",
"license": "Apache-2.0",
"dependencies": {
"@opentelemetry/core": "2.9.0"
}
}
What Changed in 2.9.0
The patched version includes:
- Input length validation: Headers exceeding reasonable bounds are rejected before parsing
- Safe decoding: Malformed encoding sequences are handled gracefully with proper error boundaries
- Resource limits: The parser now has built-in protections against resource exhaustion
- Updated core dependency: The
@opentelemetry/corepackage was also upgraded to 2.9.0, ensuring the entire parsing pipeline is protected
Before and After
Before (Vulnerable):
"@opentelemetry/propagator-jaeger": {
"version": "2.8.0",
"dependencies": {
"@opentelemetry/core": "2.8.0"
}
}
After (Patched):
"@opentelemetry/propagator-jaeger": {
"version": "2.9.0",
"dependencies": {
"@opentelemetry/core": "2.9.0"
}
}
Prevention & Best Practices
1. Automated Dependency Scanning
Integrate vulnerability scanners like Trivy, Snyk, or npm audit into your CI/CD pipeline:
# Run Trivy on your project
trivy fs --scanners vuln .
# Or use npm's built-in audit
npm audit
2. Keep Dependencies Updated
Regularly update dependencies, especially those that handle untrusted input:
# Check for outdated packages
npm outdated
# Update to latest compatible versions
npm update
3. Use npm Overrides Strategically
When transitive dependencies are vulnerable, npm overrides provide a powerful mechanism to force specific versions:
{
"overrides": {
"vulnerable-package": "^patched-version"
}
}
4. Input Validation at Multiple Layers
Don't rely solely on libraries for input validation. Implement defense in depth:
- Validate header sizes at the reverse proxy/load balancer level
- Set reasonable timeouts for request processing
- Implement rate limiting for requests with tracing headers
5. Monitor for Anomalies
Set up monitoring to detect potential DoS attempts:
- Track request processing times
- Alert on memory usage spikes
- Monitor for unusual patterns in tracing headers
Key Takeaways
- Observability libraries process every request: Vulnerabilities in OpenTelemetry propagators affect your entire application's request handling pipeline
- Transitive dependencies matter: The vulnerability existed in
@opentelemetry/propagator-jaeger2.8.0, which you might not directly depend on but inherit through other packages - npm overrides are essential for security: When you can't wait for upstream packages to update their dependencies, overrides let you force patched versions
- Header parsing is a common attack vector: Any code that parses HTTP headers from untrusted sources must implement strict input validation
- CVE-2026-59892 specifically targets Jaeger trace context: If you use Jaeger-format distributed tracing, ensure you're running propagator-jaeger 2.9.0 or later
How Orbis AppSec Detected This
- Source: HTTP request headers, specifically the
uber-trace-idJaeger trace context header - Sink:
@opentelemetry/propagator-jaegerheader decoding logic in the trace context extraction pipeline - Missing control: Input validation and bounds checking on malformed header values before parsing
- CWE: CWE-400 (Uncontrolled Resource Consumption)
- Fix: Upgraded
@opentelemetry/propagator-jaegerfrom 2.8.0 to 2.9.0 via npm override, which includes proper input validation and safe header decoding
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-59892 demonstrates how vulnerabilities in observability infrastructure can have outsized impact—a single malformed HTTP header could bring down an entire application. The fix was straightforward: upgrade @opentelemetry/propagator-jaeger to version 2.9.0 using npm overrides.
This incident reinforces several security principles: keep dependencies updated, scan continuously for known vulnerabilities, and remember that any code processing untrusted input—including tracing headers—is part of your attack surface. By implementing automated dependency scanning and maintaining awareness of your transitive dependency tree, you can catch and fix vulnerabilities like this before they reach production.