Skip to content

fix: truncate baggage/tag values to prevent metrics cardinality explosion#861

Open
SajanGhimire1 wants to merge 2 commits into
microsoft:mainfrom
SajanGhimire1:fix/baggage-cardinality-dos
Open

fix: truncate baggage/tag values to prevent metrics cardinality explosion#861
SajanGhimire1 wants to merge 2 commits into
microsoft:mainfrom
SajanGhimire1:fix/baggage-cardinality-dos

Conversation

@SajanGhimire1
Copy link
Copy Markdown

Problem

SendActivityMetric() writes W3C baggage header values
directly into metrics tag dimensions without any length
validation:

// Before fix — no length check
tagList.Add(dimension, baggageItem);

In distributed systems, baggage propagates across service
boundaries via HTTP headers. If baggage values are externally
controlled (e.g. user-supplied correlation IDs), each unique
value creates a new permanent time series in the metrics backend.

This can cause:

  • Metrics cardinality explosion
  • Metrics backend memory exhaustion
  • Loss of observability (alerts stop firing)
  • Unexpected Azure Monitor cost spikes

Same class of issue as GHSA-rcjv-mgp8-qvmr in
OpenTelemetry-Go, which was assigned a CVE.

Fix

Added MaxMetricTagValueLength = 256 constant and truncate
both baggage values and tag object values before writing
to metrics dimensions.

// After fix — length capped
tagList.Add(dimension, baggageItem.Length > MaxMetricTagValueLength
    ? baggageItem[..MaxMetricTagValueLength]
    : baggageItem);

Impact of Fix

  • Prevents unbounded time series growth
  • Preserves legitimate low-cardinality usage
  • No breaking change to existing behavior

References

…sion

Baggage header values written to metrics dimensions without length
validation could cause unbounded time series growth if values are
externally controlled (e.g. user-supplied correlation IDs passed
via W3C baggage header).

Each unique value creates a permanent new time series in the metrics
backend, causing:
- Metrics cardinality explosion
- Metrics backend memory exhaustion
- Loss of observability (alerts stop firing)
- Unexpected Azure Monitor cost spikes

Fix: truncate baggage and tag object values to 256 characters
before writing to metrics dimensions.

Related: GHSA-rcjv-mgp8-qvmr (same class, OpenTelemetry-Go)
CWE-400: Uncontrolled Resource Consumption
Copilot AI review requested due to automatic review settings May 26, 2026 00:13
@SajanGhimire1 SajanGhimire1 requested a review from a team as a code owner May 26, 2026 00:13
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds defensive truncation for Activity baggage/tag values before emitting metric dimensions to help reduce risk from unbounded external inputs.

Changes:

  • Introduced MaxMetricTagValueLength constant for tag value length limits
  • Truncated W3C baggage-derived metric tag values before adding to TagList
  • Converted Activity tag values to strings and truncated before adding to TagList

Comment on lines +91 to +96
// Truncate string representation to prevent
// cardinality explosion via high-cardinality tag values
string tagValue = tagItem.ToString() ?? string.Empty;
tagList.Add(dimension, tagValue.Length > MaxMetricTagValueLength
? tagValue[..MaxMetricTagValueLength]
: tagValue);
Comment on lines +80 to +82
tagList.Add(dimension, baggageItem.Length > MaxMetricTagValueLength
? baggageItem[..MaxMetricTagValueLength]
: baggageItem);
Comment on lines +93 to +96
string tagValue = tagItem.ToString() ?? string.Empty;
tagList.Add(dimension, tagValue.Length > MaxMetricTagValueLength
? tagValue[..MaxMetricTagValueLength]
: tagValue);
Comment on lines +27 to +29
/// Maximum length for metric tag values to prevent
/// cardinality explosion via externally controlled
/// baggage or tag values.
- Preserve original type for non-string tag values
- Use surrogate-pair-safe string truncation
- Simplify constant comment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants