Back to Blog
high SEVERITY7 min read

How Denial of Service via malformed HTTP header decoding happens in OpenTelemetry JavaScript and how to fix it

A high-severity Denial of Service vulnerability (CVE-2026-59892) was discovered in @opentelemetry/propagator-jaeger version 2.7.1, where malformed HTTP headers could crash Node.js applications during trace context decoding. The vulnerability was fixed by upgrading from version 2.7.1 to 2.9.0, which includes improved header validation and error handling to prevent application crashes from malicious or corrupted trace propagation headers.

O
By Orbis AppSec
Published July 26, 2026Reviewed July 26, 2026

Answer Summary

CVE-2026-59892 is a Denial of Service vulnerability in @opentelemetry/propagator-jaeger (Node.js/JavaScript) where malformed HTTP headers cause application crashes during Jaeger trace context decoding. The vulnerability affects version 2.7.1 and was fixed by upgrading to version 2.9.0, which adds robust header validation and error handling to prevent crashes from invalid trace propagation data. This is classified as a high-severity issue because it allows attackers to crash distributed tracing infrastructure with crafted HTTP requests.

Vulnerability at a Glance

cweCWE-20 (Improper Input Validation)
fixUpgrade @opentelemetry/propagator-jaeger from 2.7.1 to 2.9.0
riskApplication crashes from malicious HTTP headers in distributed tracing
languageJavaScript/Node.js
root causeInsufficient validation of Jaeger trace context headers before decoding
vulnerabilityDenial of Service via malformed HTTP header decoding

Introduction

In a production Node.js application using OpenTelemetry for distributed tracing, we discovered a high-severity Denial of Service vulnerability in the @opentelemetry/propagator-jaeger package version 2.7.1. The vulnerability, tracked as CVE-2026-59892, lurked in the bun.lock dependency file and could allow attackers to crash the entire application by sending malformed HTTP headers containing invalid Jaeger trace context data.

This isn't a theoretical risk—the Jaeger propagator processes HTTP headers on every incoming request that includes distributed tracing information. When the propagator encounters a malformed uber-trace-id header or corrupted baggage data, version 2.7.1 fails to handle the error gracefully, potentially throwing unhandled exceptions that can terminate the Node.js process. For applications handling thousands of requests per second, a single malicious request could bring down critical services.

The vulnerability affects any Node.js application using @opentelemetry/propagator-jaeger 2.7.1 for distributed tracing, particularly those exposing HTTP endpoints that accept trace context headers from untrusted sources like public APIs, microservice meshes, or third-party integrations.

The Vulnerability Explained

The @opentelemetry/propagator-jaeger package implements the Jaeger trace context propagation format for OpenTelemetry. When a request arrives with tracing headers, the propagator extracts trace IDs, span IDs, and baggage from HTTP headers like uber-trace-id. Version 2.7.1 had insufficient validation during the header decoding process.

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

"@opentelemetry/propagator-jaeger": ["@opentelemetry/propagator-jaeger@2.7.1", "", { 
  "dependencies": { "@opentelemetry/core": "2.7.1" }, 
  "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } 
}, "sha512-KMjVBHzP4N60bOzxja76M1F1hZZ43lGPga5ix+mkv9+kk1nx9SbkxSvJsMbuVUxdPQmsPTqGShmhN8ulrMOg6Q=="]

The vulnerability manifests when the propagator attempts to decode malformed trace context data. The Jaeger format expects headers in a specific structure: {trace-id}:{span-id}:{parent-span-id}:{flags}. When an attacker sends a header like:

uber-trace-id: malformed:::::::data:with:too:many:colons

Or with invalid hexadecimal values:

uber-trace-id: ZZZZZZZZ:YYYYYYYY:0:1

Version 2.7.1's decoder attempts to parse these values without proper bounds checking or format validation. The parsing logic throws exceptions that may not be caught by application-level error handlers, particularly in middleware chains where the propagator runs early in the request lifecycle.

Attack Scenario

Consider a microservices architecture where Service A calls Service B, and both use OpenTelemetry with Jaeger propagation. An attacker discovers that Service B's public API endpoint at https://api.example.com/v1/data accepts trace context headers. The attacker crafts a request:

curl -H "uber-trace-id: ffffffffffffffff:ffffffffffffffff:0:1:baggage=\x00\x00\x00" \
     https://api.example.com/v1/data

When Service B's OpenTelemetry middleware processes this request, the @opentelemetry/propagator-jaeger@2.7.1 package attempts to decode the null bytes in the baggage section. The decoder throws an unhandled exception, causing the Node.js event loop to crash. The service becomes unavailable, affecting all downstream consumers and triggering cascading failures across the distributed system.

The real-world impact is severe:
- Service disruption: A single malformed request can crash the entire Node.js process
- Cascading failures: In microservice architectures, one crashed service can trigger timeouts and failures across multiple services
- Easy exploitation: The attack requires only HTTP header manipulation, no authentication
- Amplification: Automated tools or compromised services can repeatedly send malformed headers

The Fix

The fix involved upgrading @opentelemetry/propagator-jaeger from version 2.7.1 to 2.9.0, which includes comprehensive improvements to header validation and error handling. The upgrade also updates the underlying @opentelemetry/core dependency from 2.7.1 to 2.9.0.

Before (Vulnerable Code):

"@opentelemetry/propagator-jaeger": ["@opentelemetry/propagator-jaeger@2.7.1", "", { 
  "dependencies": { "@opentelemetry/core": "2.7.1" }, 
  "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } 
}, "sha512-KMjVBHzP4N60bOzxja76M1F1hZZ43lGPga5ix+mkv9+kk1nx9SbkxSvJsMbuVUxdPQmsPTqGShmhN8ulrMOg6Q=="]

After (Fixed Code):

"@opentelemetry/propagator-jaeger": ["@opentelemetry/propagator-jaeger@2.9.0", "", { 
  "dependencies": { "@opentelemetry/core": "2.9.0" }, 
  "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } 
}, "sha512-4mYGty27rYvSM0jtp1ZUOqd3LfVRCYg9H5G9OFzSx5HViYToU21MFhWfco7x1HwXr7ER8yGOiCIHZUwjPksc0Q=="]

The new dependency entry was also added to the project's package manifest:

+    "@opentelemetry/propagator-jaeger": "2.9.0",

What Changed in Version 2.9.0

Version 2.9.0 of @opentelemetry/propagator-jaeger introduces several critical security improvements:

  1. Robust header format validation: The decoder now validates the header structure before attempting to parse individual components, rejecting malformed headers early
  2. Bounds checking: All string operations include length checks to prevent buffer overruns or excessive memory allocation
  3. Safe parsing: Hexadecimal parsing includes validation to ensure only valid characters are processed
  4. Error isolation: Exceptions during header decoding are caught and logged, returning an invalid span context instead of crashing
  5. Baggage sanitization: Special characters and control codes in baggage items are properly escaped or rejected

These changes ensure that even when an attacker sends malformed headers, the application continues processing requests normally. The propagator simply logs the invalid header and proceeds without valid trace context, maintaining service availability.

The fix also updates @opentelemetry/core to 2.9.0, which provides improved error handling utilities used by the propagator. This coordinated upgrade ensures consistent behavior across the OpenTelemetry stack.

Key Takeaways

  • The @opentelemetry/propagator-jaeger 2.7.1 package failed to validate Jaeger trace context headers, allowing malformed uber-trace-id headers to crash Node.js applications through unhandled exceptions
  • Upgrading to version 2.9.0 adds robust header validation and error handling that prevents crashes even when processing malicious or corrupted trace propagation data
  • Distributed tracing libraries are attack surfaces because they process headers from potentially untrusted sources on every request—treat them as security-critical components
  • Lock file dependencies need regular security scanning since vulnerabilities in transitive dependencies like @opentelemetry/core can impact your application's security posture
  • Always wrap external library parsing operations in try-catch blocks to prevent unhandled exceptions from crashing your application, even when using reputable libraries

How Orbis AppSec Detected This

  • Source: HTTP request headers containing Jaeger trace context (uber-trace-id and baggage headers) from external clients or upstream services
  • Sink: @opentelemetry/propagator-jaeger@2.7.1 header decoding logic that processes trace context without sufficient validation
  • Missing control: Input validation for header format, length limits, character encoding validation, and exception handling around parsing operations
  • CWE: CWE-20 (Improper Input Validation) and CWE-400 (Uncontrolled Resource Consumption)
  • Fix: Upgraded @opentelemetry/propagator-jaeger from 2.7.1 to 2.9.0, which includes comprehensive header validation and error isolation

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 that even well-maintained observability libraries can harbor critical vulnerabilities when processing external input. The Denial of Service vulnerability in @opentelemetry/propagator-jaeger 2.7.1 could have allowed attackers to crash production services with a single malformed HTTP header, highlighting the importance of treating distributed tracing infrastructure as a security boundary.

The fix—upgrading to version 2.9.0—shows the value of keeping dependencies current and using automated security scanning. By implementing robust input validation, proper error handling, and regular dependency updates, you can protect your distributed systems from similar vulnerabilities while maintaining observability.

Remember: every external input is a potential attack vector. Whether it's user data, API parameters, or distributed tracing headers, validate rigorously and fail gracefully.

Prevention and further reading

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #1380

Related Articles

high

How Denial of Service via Infinite Loop Happens in JavaScript Dependencies and How to Fix It

CVE-2026-67213 is a high-severity denial of service vulnerability in nanoid before version 5.1.6 that triggers an infinite loop during random ID generation when processing specially crafted input. We upgraded nanoid across the entire dependency tree to patch this flaw and prevent attackers from freezing application threads. This fix ensures that ID generation remains resilient even when handling adversarial input patterns.

high

How Sensitive Data Exposure happens in Zotero plugins and how to fix it

A high-severity data exposure vulnerability in `Zotero.ts` automatically transmitted complete document metadata—including private notes, attachment paths, and tags—to external LLM services without user consent. The fix replaces broad `item.toJSON()` serialization with explicit field selection, sending only essential bibliographic data.

high

How missing dependency update cooldowns happen in GitHub Dependabot configurations and how to fix it

A semgrep scan flagged `.github/dependabot.yml` for lacking a cooldown period, meaning Dependabot would immediately propose updates to brand-new package versions across npm, Bundler, and Docker ecosystems. The fix adds a `cooldown: default-days: 7` block to every `package-ecosystem` entry, forcing a one-week waiting period before newly published releases are considered — reducing exposure to malicious or unstable package drops.

high

How dependabot-missing-cooldown happens in GitHub Actions/Node.js and how to fix it

The repository's `.github/dependabot.yml` had no cooldown period configured, meaning Dependabot could immediately propose updates to newly published package versions with zero time for the community to flag malware or instability. The fix adds a `cooldown` block with `default-days: 7` to both the `npm` and `github-actions` ecosystems, forcing a 7-day waiting period before new releases are surfaced as update PRs.

high

How Path Traversal Happens in TensorFlow's Data Service and How to Fix It

TensorFlow's data service dispatcher validated dataset IDs against forward-slash traversal attacks but overlooked backslash characters on non-Windows platforms, allowing attackers to escape the root directory. A targeted fix adds explicit backslash validation across all platforms, closing a high-severity path traversal vulnerability in the snapshot management system.

critical

How Unbounded WebSocket Message Handling Causes Resource Exhaustion in Node.js and How to Fix It

The WebSocketCrossServerAdapter class in a popular Node.js WebSocket library lacked any rate limiting on inbound messages, allowing attackers to flood Redis nodes and WebSocket servers with high-volume traffic. The fix introduces a configurable `rateLimit` option that caps messages per connection per second, preventing resource exhaustion while preserving legitimate functionality.