GHSA-rrfc-gjm9-cgrj

Suggest an improvement
Source
https://github.com/advisories/GHSA-rrfc-gjm9-cgrj
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/11/GHSA-rrfc-gjm9-cgrj/GHSA-rrfc-gjm9-cgrj.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-rrfc-gjm9-cgrj
Aliases
  • CVE-2026-128086
Downstream
CGA (28)
Published
2026-11-13T19:08:10Z
Modified
2026-11-13T19:15:06Z
Severity
  • 5.3 (Medium) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L CVSS Calculator
Summary
OpenTelemetry-Go: Eager W3C baggage-property materialization causes bounded memory-allocation amplification
Details

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.

Database specific
{
    "cwe_ids": [
        "CWE-400",
        "CWE-405"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-11-13T19:08:10Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
}
References

Affected packages

Go / go.opentelemetry.io/otel/baggage

Package

Name
go.opentelemetry.io/otel/baggage
View open source insights on deps.dev
Purl
pkg:golang/go.opentelemetry.io/otel/baggage

Affected ranges

Type
SEMVER
Events
Introduced
1.0.0-RC1
Fixed
1.47.0

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/11/GHSA-rrfc-gjm9-cgrj/GHSA-rrfc-gjm9-cgrj.json"

Go / go.opentelemetry.io/otel/propagation

Package

Name
go.opentelemetry.io/otel/propagation
View open source insights on deps.dev
Purl
pkg:golang/go.opentelemetry.io/otel/propagation

Affected ranges

Type
SEMVER
Events
Introduced
1.0.0-RC1
Fixed
1.47.0

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/11/GHSA-rrfc-gjm9-cgrj/GHSA-rrfc-gjm9-cgrj.json"