CVE-2026-128086: OpenTelemetry-Go: Eager W3C baggage-property materialization causes bounded memory-allocation amplification

Published Nov 13, 2026
·
Updated

Summary

OpenTelemetry Go eagerly materializes W3C baggage metadata into property objects during parsing. Slice growth, serialization, and copying into the internal representation cause bounded but disproportionate memory-allocation amplification for a valid, densely populated header. In v1.46.0 and v1.47.0-rc.1, the 8,192-byte raw-input limit is checked before member parsing; this is not unlimited allocation or a bypass of that limit.

A valid 8,191-byte value containing one member and 4,094 properties causes approximately 778 KB of cumulative allocation per parse. A corrected measurement with forced garbage collection before and after parsing retains approximately 164 KB per result while it remains live. These are different metrics: approximately 95 times the input in allocation traffic versus approximately 20 times in incremental live heap in the measured environment.

The relevant security configuration is a service that enables Baggage propagation and extracts attacker-controlled inbound context before authentication or on a public route. Concurrent or sustained requests can increase allocation and GC pressure. The evidence establishes allocation amplification, but does not establish reliable OOM, process termination, or complete denial of service.

This is a pre-existing, independent allocation-amplification path not addressed by GHSA-5wrp-cwcj-q835 / CVE-2026-41178. It predates that advisory; it is not described as having been introduced by its fix.

Affected module, versions, and symbols

- Go module: go.opentelemetry.io/otel. - Import paths and entry points: go.opentelemetry.io/otel/baggage.Parse and go.opentelemetry.io/otel/propagation.Baggage.Extract. - Implementation: parseMember, property-slice growth and serialization, and conversion into internal/baggage.Item. - Source history places the eager-property implementation at commit 4bf6150fa94e18bdf01c96ed78ee6d1c76f8e308, first included in v1.0.0-RC1; the stable release line starts at v1.0.0. - Affected release range: >= 1.0.0-RC1, < 1.47.0. - Patched release: v1.47.0 (https://github.com/open-telemetry/opentelemetry-go/pull/9024), which validates and normalizes W3C property metadata in place during Parse and materializes Property structs lazily only when Member.Properties() is explicitly called. - Small parser measurements were run on v1.0.0-RC1, v1.0.0, v1.46.0, and v1.47.0-rc.1; this is not a claim to have dynamically tested every intervening release. The v1.46.0 and v1.47.0-rc.1 parser source is identical to the inspected main commit 901e812ec023f45f791cd4d49cfbbef353ae21ae.

Early releases have a 4,096-byte per-member limit. They reproduce the same mechanism with a 4,095-byte member containing 2,046 properties; the 8,191-byte single-member input is rejected there. The 8 KB example and its numerical allocation result must not be projected onto every historical version.

Root cause and input bounds

For the valid dense input, each short property becomes a Go Property, and the slice grows as parsing proceeds. The parser subsequently serializes the member and copies its properties into the internal representation. A two-byte wire fragment can therefore produce substantially more than two bytes of allocation work. Temporary parser objects and internal retained objects must not be added together and described as permanently retained memory.

In the currently measured parser, the raw 8,192-byte limit and 64-member limit still apply. The number of accepted properties is consequently bounded by input length even though there is no separate property-count guard. Eager representation and copying are the defect described here; the absence of an arbitrary count cap is not, by itself, the defect.

The primary input is constructed as "k=v" + strings.Repeat(";a", 4094) (8,191 bytes); the equal-size value-only control is "k=" + strings.Repeat("v", 8189). Call baggage.Parse once for each measured result. To verify the property count separately, inspect bag.Members()[0].Properties() outside the measured interval; this accessor itself allocates. The primary example remains the valid 8,191-byte, 4,094-property input already supplied in this private report. Empty-property input discussed in the maintainer review is malformed and is supplementary parser-hardening evidence, not the standards-compliant primary example or the basis of the severity score.

HTTP reachability and authentication ordering

The Go global propagator is initially a no-op. Installing the library alone does not expose this path. Baggage must be enabled explicitly or by applicable auto-configuration; standardized auto-configuration defaults do not establish an individual application's configuration.

An ordinary HTTP composition can place otelhttp.NewHandler outside the authentication handler. With propagation.Baggage{} enabled and the request not excluded by a filter, the checked otelhttp implementation calls h.propagators.Extract(r.Context(), propagation.HeaderCarrier(r.Header)) before next.ServeHTTP. Authentication inside next therefore runs after extraction, including for a request that is ultimately rejected with 401/403. Reversing the composition so authentication rejects before entering otelhttp prevents this unauthenticated extraction path. This is a source-level ordering check of a normal integration, not a claim about all services or an executed HTTP benchmark.

Source checked: otelhttp handler at ce138eb092f223e4e41e0420c58fc34910bc2b56, extraction at line 98 and downstream handler at line 185. A filter that bypasses instrumentation takes a separate path and is outside this stated composition.

Remote reachability requires all of the following: Baggage extraction is enabled; attacker-controlled input reaches it; the transport and proxy accept the relevant header size; and extraction runs before authentication or on a public route. Material service impact further depends on request rate, concurrency, request lifetime, GC behavior, and resource limits. Authentication is a mitigation only if it precedes extraction. A path that requires a properly authenticated triggering client must also be evaluated under the project's authenticated-client DoS exclusion.

Other sources

OpenTelemetry-Go is the Go implementation of OpenTelemetry. From version 1.0.0-RC1 until version 1.47.0, baggage.Parse and propagation.Baggage.Extract eagerly materialize every W3C baggage property through parseMember, grow property slices, serialize members, and copy properties into internal/baggage.Item. A valid densely populated baggage header can therefore cause allocation traffic and retained memory disproportionate to its bounded input size. Remote impact requires baggage extraction to be enabled, attacker-controlled input to reach it, and extraction to run before authentication or on a public route; the evidence establishes increased allocation and garbage-collection pressure but not reliable process termination. This issue is fixed in version 1.47.0.

— MITRE

Affected Software

2 affected componentsFixes available
go/go.opentelemetry.io/otel/propagation>=1.0.0-RC1<1.47.0
1.47.0
go/go.opentelemetry.io/otel/baggage>=1.0.0-RC1<1.47.0
1.47.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade go/go.opentelemetry.io/otel/propagation to a version that resolves this vulnerability.

    Fixed in 1.47.0
  2. Upgrade

    Upgrade go/go.opentelemetry.io/otel/baggage to a version that resolves this vulnerability.

    Fixed in 1.47.0
  3. Upgrade

    Upgrade go.opentelemetry.io/otel to a version that resolves this vulnerability.

    Fixed in v1.47.0
  4. Compensating control

    Reorder the HTTP handler composition so authentication rejects requests before they enter otelhttp and baggage extraction runs.

Event History

Nov 13, 2026
CVE Published
via MITRE·06:54 PM
Data Sourced
via MITRE·06:54 PM
DescriptionSeverityWeakness
Advisory Published
via GitHub·07:08 PM
Data Sourced
via GitHub·07:08 PM
DescriptionSeverityWeaknessAffected Software
Data Sourced
via NVD·07:19 PM
DescriptionSeverityWeakness

Frequently Asked Questions

1

Which deployments are exposed to this issue?

Exposure requires a service to enable Baggage propagation and extract attacker-controlled inbound context before authentication or on a public route. Services that do not process attacker-controlled baggage headers in those conditions are not identified as exposed by the available data.

2

What does an attacker need to send to create the largest measured allocation pressure?

The measured case uses a valid 8,191-byte baggage value containing one member and 4,094 properties. Exploitation depends on the target parsing such inbound context; concurrent or sustained requests can increase allocation and garbage-collection pressure.

3

Does the input-size limit prevent the observed effect?

The 8,192-byte raw-input limit is enforced before member parsing and is not bypassed. However, a header within that limit can still produce disproportionate allocation: approximately 778 KB of cumulative allocation per parse and approximately 164 KB of retained live heap while the parsed result remains live in the measured environment.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203