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.

Prevention & Best Practices

To prevent similar vulnerabilities in distributed tracing implementations:

1. Validate All External Input

Always validate HTTP headers before processing, especially those from untrusted sources. For trace context headers:

function validateJaegerHeader(header) {
  if (!header || typeof header !== 'string') return false;
  if (header.length > 1024) return false; // Prevent DoS via large headers

  const parts = header.split(':');
  if (parts.length < 4) return false;

  // Validate hex format for trace and span IDs
  const hexRegex = /^[0-9a-f]+$/i;
  if (!hexRegex.test(parts[0]) || !hexRegex.test(parts[1])) return false;

  return true;
}

2. Use Try-Catch Around External Library Calls

Even when using well-maintained libraries, wrap parsing operations in try-catch blocks:

try {
  const spanContext = propagator.extract(context, carrier, getter);
  // Process trace context
} catch (error) {
  logger.warn('Failed to extract trace context', { error: error.message });
  // Continue without tracing rather than crashing
}

3. Keep Dependencies Updated

Regularly update OpenTelemetry and other security-critical dependencies. Use tools like:
- Dependabot: Automated pull requests for dependency updates
- Renovate: Intelligent dependency update automation
- npm audit or pnpm audit: Identify known vulnerabilities in dependencies
- Trivy: Comprehensive vulnerability scanning for container images and dependencies

4. Implement Defense in Depth

Don't rely solely on library validation:
- Set maximum header size limits at the HTTP server level
- Use rate limiting to prevent DoS attempts
- Implement circuit breakers for distributed tracing to prevent cascading failures
- Monitor for unusual patterns in trace header formats

5. Test with Malformed Input

Include fuzzing and negative test cases in your test suite:

describe('Trace propagation', () => {
  it('should handle malformed uber-trace-id headers', () => {
    const malformedHeaders = [
      'invalid',
      ':::',
      'ZZZZ:YYYY:0:1',
      'a'.repeat(10000), // Very long header
      '\x00\x00\x00', // Null bytes
    ];

    malformedHeaders.forEach(header => {
      expect(() => {
        propagator.extract(context, { 'uber-trace-id': header }, getter);
      }).not.toThrow();
    });
  });
});

6. Follow OWASP Guidelines

Refer to the OWASP Input Validation Cheat Sheet for comprehensive input validation strategies.

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.

References

Frequently Asked Questions

What is Denial of Service via malformed HTTP header decoding?

It's a vulnerability where an application crashes or becomes unresponsive when processing specially crafted HTTP headers. In this case, the OpenTelemetry Jaeger propagator failed to validate trace context headers, allowing malformed data to trigger exceptions that could crash the Node.js process.

How do you prevent Denial of Service via malformed headers in Node.js?

Implement strict input validation on all HTTP headers before processing, use try-catch blocks around header parsing logic, set maximum header size limits, validate header format against expected schemas, and use libraries that have been hardened against malformed input (like @opentelemetry/propagator-jaeger 2.9.0+).

What CWE is Denial of Service via malformed HTTP header decoding?

This vulnerability maps to CWE-20 (Improper Input Validation) and CWE-400 (Uncontrolled Resource Consumption). The root cause is failing to validate input data before processing, which allows malicious input to consume resources or trigger crashes.

Is rate limiting enough to prevent Denial of Service from malformed headers?

No, rate limiting alone is insufficient. While it can reduce the frequency of attacks, a single malformed request can still crash the application. You need input validation, proper error handling, and defensive parsing in addition to rate limiting for comprehensive protection.

Can static analysis detect Denial of Service via malformed header decoding?

Yes, static analysis tools like Trivy can detect vulnerable library versions with known CVEs. However, detecting the underlying code pattern requires dependency scanning combined with vulnerability databases. In this case, Trivy identified the vulnerable @opentelemetry/propagator-jaeger version 2.7.1 in the bun.lock file.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #1380

Related Articles

critical

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

A critical Server-Side Request Forgery vulnerability in `popup.js` allowed attackers to inject malicious URLs from scraped webpages directly into fetch() calls, potentially accessing internal network resources and AWS metadata endpoints. The fix adds URL validation to ensure only HTTP/HTTPS protocols are used and blocks requests to private IP ranges and localhost addresses.

high

How NO_PROXY bypass via crafted URL happens in Node.js axios and how to fix it

A high-severity vulnerability (CVE-2026-42043) in axios versions prior to 1.15.1 allowed attackers to bypass NO_PROXY environment variable restrictions using specially crafted URLs. This meant HTTP requests intended to stay internal could be routed through an attacker-controlled proxy, potentially exposing sensitive data. The fix upgrades axios to version 1.15.1, which correctly validates URLs against NO_PROXY rules.

critical

How JSON request validation bypass happens in Node.js API handlers and how to fix it

A critical validation bypass in the `/api/agents/jobs` endpoint allowed attackers to send malformed JSON with arbitrary properties that could trigger prototype pollution or unexpected behavior. The fix added comprehensive validation checks including array detection and property existence verification to prevent malicious payloads from reaching downstream processing logic.

critical

How Server-Side Request Forgery happens in Node.js httpProxy.js and how to fix it

A critical Server-Side Request Forgery (SSRF) vulnerability was discovered in `hubcmdui/routes/httpProxy.js` where the `/proxy/test` endpoint passed a user-controlled `testUrl` parameter directly to `axios.get()` without any validation. An attacker could exploit this to probe internal infrastructure — including AWS metadata endpoints, Redis instances, and private network ranges. The fix introduces a strict URL validation function that blocks private IP ranges, loopback addresses, and non-HTTP(S)

critical

How Remote Configuration Injection happens in JavaScript fetch() and how to fix it

A critical vulnerability in `js/config.js` allowed attackers to inject malicious configuration data through DNS spoofing or man-in-the-middle attacks. The application fetched remote JSON configuration from GitHub without validating the response structure, enabling arbitrary code execution through crafted payloads. A single validation check now ensures only properly-formed configuration objects are accepted.

high

How missing Dependabot cooldown configuration happens in GitHub Actions and how to fix it

A high-severity vulnerability was discovered in the `.github/dependabot.yml` configuration file where no cooldown period was set for dependency updates. This exposed the Node.js library and its downstream consumers to potentially malicious or unstable packages immediately after publication. The fix adds a 7-day cooldown period to all package ecosystem entries, providing a critical safety buffer before accepting newly published package versions.