CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-40891
5.3

CVE-2026-40891: Denial of Service via Unbounded Memory Allocation in OpenTelemetry .NET gRPC Trailer Parsing

Alon Barad
Alon Barad
Software Engineer

Apr 23, 2026·6 min read·4 visits

PoC Available

Executive Summary (TL;DR)

A memory allocation vulnerability in the OpenTelemetry .NET SDK allows a malicious gRPC endpoint to crash the client application via a crafted grpc-status-details-bin trailer.

The OpenTelemetry .NET SDK is vulnerable to a Denial of Service (DoS) flaw due to unbounded memory allocation during the deserialization of gRPC status details. An attacker controlling the telemetry endpoint or performing a Man-in-the-Middle attack can crash the instrumented application by supplying a crafted Protobuf payload.

Vulnerability Overview

The OpenTelemetry .NET SDK provides a framework for generating and exporting telemetry data. The OpenTelemetry.Exporter.OpenTelemetryProtocol package handles the transmission of this data to an OpenTelemetry Protocol (OTLP) collector via gRPC. This component is widely integrated into .NET enterprise applications to monitor performance and trace distributed requests.

During telemetry export, the gRPC client processes response metadata from the collector. If the collector returns a retryable status code, such as ResourceExhausted or Unavailable, the client intercepts the grpc-status-details-bin trailer. This trailer contains a serialized Protobuf payload specifying retry delay information.

The parser handling this trailer exhibits a CWE-789 vulnerability, classified as Memory Allocation with Excessive Size Value. The manual Protobuf deserialization routine fails to validate the declared length of length-delimited fields against the actual byte stream size. An attacker can supply a malicious trailer to force arbitrary heap allocations, resulting in an unhandled memory exception that terminates the application process.

Root Cause Analysis

The root cause of this vulnerability lies in the manual Protobuf parsing logic implemented within the GrpcStatusDeserializer class. Specifically, the flaw exists in methods handling length-delimited fields, such as DecodeBytes, DecodeDuration, and DecodeAny. Protobuf encodes length-delimited data using a variable-length integer (varint) to specify the subsequent payload size.

Upon encountering a length-delimited field, the vulnerable deserializer reads the varint from the network stream using the DecodeVarint method. The returned 64-bit integer is cast to a 32-bit integer and directly utilized as the size parameter for a new byte array allocation. The operation executes new byte[length] unconditionally.

The deserializer omits critical bounds checking prior to this allocation step. It does not evaluate whether the requested array length exceeds the remaining bytes available in the underlying stream. Consequently, a small network payload containing an artificially inflated varint instructs the .NET runtime to allocate an array far larger than the actual data transfer.

Code Analysis

Prior to version 1.15.2, the DecodeBytes method allocated memory blindly based on the parsed varint. The underlying flaw manifests directly in the array instantiation logic. The runtime trusts the externally supplied length value entirely.

// Vulnerable Implementation (prior to 1.15.2)
private static byte[] DecodeBytes(Stream stream)
{
    var length = (int)DecodeVarint(stream);
    // Unbounded allocation based on untrusted input
    var buffer = new byte[length];
    int read = stream.Read(buffer, 0, length);
    return buffer;
}

The remediation introduced in PR #7064 adds a dedicated CheckLength validation method. This function intercepts the parsing flow immediately after the varint decoding phase. It imposes strict constraints on the requested allocation size.

// Patched Implementation (1.15.2)
private static byte[] DecodeBytes(Stream stream)
{
    var length = (int)DecodeVarint(stream);
    CheckLength(length, stream);
    var buffer = new byte[length];
    int read = stream.Read(buffer, 0, length);
    return buffer;
}
 
private static void CheckLength(long length, Stream stream)
{
    if (length < 0 || length > int.MaxValue)
    {
        throw new InvalidDataException($"Invalid length: {length}.");
    }
 
    long available = stream.Length - stream.Position;
    if (length > available)
    {
        throw new EndOfStreamException();
    }
}

The CheckLength method introduces dual validation requirements. First, a sanity check ensures the value is non-negative and within the limits of a standard .NET array index. Second, a bounds check verifies that the requested memory capacity does not exceed the remaining readable bytes in the stream buffer.

Exploitation Mechanics

Exploitation requires the attacker to control the network traffic flowing from the instrumented client to the telemetry collector. The attacker must act as a malicious OTLP endpoint or successfully execute a Man-in-the-Middle attack. The attack surface relies on the target client attempting an export operation and subsequently parsing the provided gRPC response.

The attacker crafts an HTTP/2 response utilizing a gRPC retryable status code, such as RESOURCE_EXHAUSTED. This response is configured to include the grpc-status-details-bin trailer. The trailer payload is engineered as a minimal Protobuf structure where the length varint declares a required size near the 2GB limit (e.g., 0x7FFFFFF0), but the physical payload size is negligible.

When the client processes the trailer, the DecodeBytes function invokes the memory allocation routine. The .NET Common Language Runtime (CLR) attempts to secure a contiguous memory block on the Large Object Heap corresponding to the malicious varint. This immediate allocation request exhausts the available application memory, triggering a fatal System.OutOfMemoryException.

Impact Assessment

The exploitation of CVE-2026-40891 results in an absolute Denial of Service condition for the application hosting the OpenTelemetry .NET SDK. The unhandled memory exception bypasses standard application error handling mechanisms, leading to instantaneous process termination. This failure disrupts the primary business functions of the instrumented software.

The assigned CVSS vector (CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H) accurately reflects the attack constraints. The High Attack Complexity (AC:H) and Adjacent Network (AV:A) metrics acknowledge the necessity of intercepting or terminating the specific gRPC connection. The attacker requires precise network positioning to inject the malicious trailer.

In containerized and orchestrated environments, such as Kubernetes clusters, this vulnerability introduces secondary operational risks. A process crashing continuously upon initialization or during its first telemetry export cycle causes orchestration controllers to enter crash-loop backoff states. This behavior induces unnecessary resource thrashing and prolongs service outages.

Remediation and Mitigation

The authoritative resolution for CVE-2026-40891 requires updating the target application dependencies. Security teams must ensure that the OpenTelemetry.Exporter.OpenTelemetryProtocol NuGet package is upgraded to version 1.15.2 or later. This version implements the necessary bounds-checking logic within the Protobuf deserialization pipeline.

Organizations should enforce strict Transport Layer Security (TLS) configuration across all gRPC export channels. Mandating encrypted, mutually authenticated connections mitigates the risk of Man-in-the-Middle attacks. This defensive measure restricts the exploitability of the vulnerability strictly to compromised or explicitly malicious OTLP collectors.

As a defense-in-depth strategy, administrators should harden the gRPC client configurations. Setting aggressive limits on the MaxResponseHeadersSize property ensures the client rejects abnormally large metadata payloads prior to invoking the deserialization logic. This configuration limits the attack surface available for complex payload injection.

Official Patches

OpenTelemetryPull Request containing the bounds checking fix.

Technical Appendix

CVSS Score
5.3/ 10
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H

Affected Systems

.NET applications utilizing OpenTelemetry.Exporter.OpenTelemetryProtocol versions 1.13.1 through 1.15.1

Affected Versions Detail

Product
Affected Versions
Fixed Version
OpenTelemetry.Exporter.OpenTelemetryProtocol
OpenTelemetry
1.13.1 - < 1.15.21.15.2
AttributeDetail
CWE IDCWE-789
Attack VectorAdjacent Network
CVSS v3.1 Score5.3
Exploit StatusProof of Concept
ImpactDenial of Service (DoS)
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-789
Memory Allocation with Excessive Size Value

The product allocates memory based on an untrusted size value, but it does not sufficiently validate the size, allowing the allocation of a large amount of memory leading to a denial of service.

Vulnerability Timeline

Fix Released (Internal PRs merged)
2026-04-08
Public Disclosure
2026-04-23
NVD Publication
2026-04-23

References & Sources

  • [1]GitHub Security Advisory GHSA-mr8r-92fq-pj8p
  • [2]NVD Vulnerability Detail for CVE-2026-40891
  • [3]Introduction Pull Request (#5980)

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.