GHSA-45RX-2JWX-CXFR
Vulnerability from github – Published: 2026-07-21 19:07 – Updated: 2026-07-21 19:07Summary
@opentelemetry/propagator-jaeger decodes incoming HTTP header values with decodeURIComponent() without handling decode errors. A single request carrying a malformed percent-encoded value (for example a bare %) in an uber-trace-id or uberctx-* header throws an uncaught URIError, terminating any Node.js process that uses JaegerPropagator as its active propagator.
Impact
Denial of Service: Any unauthenticated remote attacker who can send an HTTP request to a service that has JaegerPropagator registered as the global propagator (e.g. via OTEL_PROPAGATORS=jaeger or propagation.setGlobalPropagator(new JaegerPropagator())) can terminate the process with a single request. Confidentiality and integrity are not affected.
Am I affected?
This issue affects only a specific, opt-in configuration. If you use OpenTelemetry's default propagators (W3C TraceContext and Baggage), you are not affected.
You are affected only if you have registered JaegerPropagator as the active propagator. Check for:
@opentelemetry/propagator-jaegerin your dependency tree, andOTEL_PROPAGATORSset tojaeger(Jaeger only), or a directpropagation.setGlobalPropagator(new JaegerPropagator())call in your code.
Note: if JaegerPropagator is combined with other propagators through a CompositePropagator (for example OTEL_PROPAGATORS=jaeger,tracecontext), the process does not terminate - the composite propagator catches the error - but affected requests silently fail to extract context. You should still upgrade.
Patched versions
@opentelemetry/propagator-jaeger2.9.0
Remediation
Update @opentelemetry/propagator-jaeger to 2.9.0 or later. The propagator now ignores header values it cannot decode instead of throwing.
Interim mitigation (if you cannot update): Trace-context headers should never be accepted unfiltered from untrusted callers. Until you can upgrade, strip or validate the uber-trace-id and uberctx-* headers on inbound requests at your edge - for example with a reverse proxy, API gateway, or load balancer (nginx, Envoy, etc.) - so that only trusted upstream services can set them.
Details
JaegerPropagator.extract() calls decodeURIComponent() on raw header values at two unguarded call sites: the uber-trace-id trace header and each uberctx-* baggage value. decodeURIComponent() throws URIError: URI malformed on invalid percent-encoding. Because the HTTP instrumentation extracts context before its request-handler error wrapper, and a single configured propagator is not wrapped in a CompositePropagator (which would otherwise catch the error), the exception propagates as an uncaughtException and terminates the process.
Proof of concept
Against a service using JaegerPropagator:
curl -H 'uberctx-user: %' http://target/
# or
curl -H 'uber-trace-id: %' http://target/
The Node.js process exits with URIError: URI malformed and subsequent requests are refused.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "@opentelemetry/propagator-jaeger"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.9.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-59892"
],
"database_specific": {
"cwe_ids": [
"CWE-248"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-21T19:07:28Z",
"nvd_published_at": "2026-07-08T17:17:27Z",
"severity": "HIGH"
},
"details": "## Summary\n\n`@opentelemetry/propagator-jaeger` decodes incoming HTTP header values with `decodeURIComponent()` without handling decode errors. A single request carrying a malformed percent-encoded value (for example a bare `%`) in an `uber-trace-id` or `uberctx-*` header throws an uncaught `URIError`, terminating any Node.js process that uses `JaegerPropagator` as its active propagator.\n\n\n## Impact\n\n**Denial of Service:** Any unauthenticated remote attacker who can send an HTTP request to a service that has `JaegerPropagator` registered as the global propagator (e.g. via `OTEL_PROPAGATORS=jaeger` or `propagation.setGlobalPropagator(new JaegerPropagator())`) can terminate the process with a single request. Confidentiality and integrity are not affected.\n\n## Am I affected?\n\nThis issue affects only a specific, opt-in configuration. If you use OpenTelemetry\u0027s default propagators (W3C TraceContext and Baggage), you are **not** affected. \n\nYou are affected only if you have registered `JaegerPropagator` as the active propagator. Check for:\n\n- `@opentelemetry/propagator-jaeger` in your dependency tree, **and**\n- `OTEL_PROPAGATORS` set to `jaeger` (Jaeger only), **or** a direct `propagation.setGlobalPropagator(new JaegerPropagator())` call in your code.\n\nNote: if `JaegerPropagator` is combined with other propagators through a `CompositePropagator` (for example `OTEL_PROPAGATORS=jaeger,tracecontext`), the process does not terminate - the composite propagator catches the error - but affected requests silently fail to extract context. You should still upgrade.\n\n\n## Patched versions\n\n- `@opentelemetry/propagator-jaeger` 2.9.0\n\n## Remediation\n\nUpdate `@opentelemetry/propagator-jaeger` to 2.9.0 or later. The propagator now ignores header values it cannot decode instead of throwing.\n\n**Interim mitigation (if you cannot update):** Trace-context headers should never be accepted unfiltered from untrusted callers. Until you can upgrade, strip or validate the `uber-trace-id` and `uberctx-*` headers on inbound requests at your edge - for example with a reverse proxy, API gateway, or load balancer (nginx, Envoy, etc.) - so that only trusted upstream services can set them.\n\n## Details\n\n`JaegerPropagator.extract()` calls `decodeURIComponent()` on raw header values at two unguarded call sites: the `uber-trace-id` trace header and each `uberctx-*` baggage value. `decodeURIComponent()` throws `URIError: URI malformed` on invalid percent-encoding. Because the HTTP instrumentation extracts context before its request-handler error wrapper, and a single configured propagator is not wrapped in a `CompositePropagator` (which would otherwise catch the error), the exception propagates as an `uncaughtException` and terminates the process.\n\n## Proof of concept\n\nAgainst a service using `JaegerPropagator`:\n\n```bash\ncurl -H \u0027uberctx-user: %\u0027 http://target/\n# or\ncurl -H \u0027uber-trace-id: %\u0027 http://target/\n```\n\nThe Node.js process exits with `URIError: URI malformed` and subsequent requests are refused.",
"id": "GHSA-45rx-2jwx-cxfr",
"modified": "2026-07-21T19:07:28Z",
"published": "2026-07-21T19:07:28Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/open-telemetry/opentelemetry-js/security/advisories/GHSA-45rx-2jwx-cxfr"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-59892"
},
{
"type": "WEB",
"url": "https://github.com/open-telemetry/opentelemetry-js/commit/b1c196d49d54caae59741cca0a9d57d101d7ea88"
},
{
"type": "PACKAGE",
"url": "https://github.com/open-telemetry/opentelemetry-js"
},
{
"type": "WEB",
"url": "https://github.com/open-telemetry/opentelemetry-js/releases/tag/v2.9.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "OpenTelemetry JavaScript: Denial of service in `JaegerPropagator` via unhandled exception on a malformed header"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.