CVE-2026-42191
Description
OpenTelemetry.Exporter.OpenTelemetryProtocol is the OTLP (OpenTelemetry Protocol) exporter implementation. From 1.8.0 to 1.15.2, the OTLP disk retry feature in OpenTelemetry.Exporter.OpenTelemetryProtocol silently fell back to Path.GetTempPath() when OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY=disk was set but OTEL_DOTNET_EXPERIMENTAL_OTLP_DISK_RETRY_DIRECTORY_PATH was not configured. The exporter stored and loaded *.blob files under fixed, signal-named subdirectories (traces, metrics, logs) beneath that shared temporary root path. On multi-user systems where the temporary directory is accessible to other local accounts, this allows an attacker to write crafted *.blob files, read *.blob files written by the application between export failures, or deposit numerous or oversized blob files, degrading retry-loop performance or consuming disk space. This vulnerability is fixed in 1.15.3.
Affected products
1- Range: >= 1.8.0, <= 1.15.2
Patches
178dffdc5ebdf[Exporter.OTLP] Require path when disk-retry is configured (#7106)
4 files changed · +60 −11
src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md+14 −0 modified@@ -7,6 +7,20 @@ Notes](../../RELEASENOTES.md). ## Unreleased +* **Breaking change:** Fixed an insecure disk retry default. Disk retry now + requires `OTEL_DOTNET_EXPERIMENTAL_OTLP_DISK_RETRY_DIRECTORY_PATH` when + `OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY=disk` is configured. The exporter no + longer falls back to a shared temp directory by default. + To retain the previous behaviour, set the + `OTEL_DOTNET_EXPERIMENTAL_OTLP_DISK_RETRY_DIRECTORY_PATH` environment + variable to the value one of the following environment variables: + + * `TMP`, `TMP`, or `USERPROFILE` ([Windows](https://learn.microsoft.com/windows/win32/api/fileapi/nf-fileapi-gettemppath2w#remarks)) + * `TMPDIR` (or the literal value `/tmp/`) ([Linux](https://learn.microsoft.com/dotnet/api/system.io.path.gettemppath?tabs=linux), + [macOS](https://learn.microsoft.com/dotnet/api/system.io.path.gettemppath?tabs=macos)). + + ([#7106](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7106)) + * Fixed an issue in OTLP/gRPC retry handling where parsing gRPC status. ([#7064](https://github.com/open-telemetry/opentelemetry-dotnet/pull/7064))
src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExperimentalOptions.cs+2 −2 modified@@ -42,8 +42,8 @@ public ExperimentalOptions(IConfiguration configuration) } else { - // Fallback to temp location. - this.DiskRetryDirectoryPath = Path.GetTempPath(); + throw new NotSupportedException( + $"Retry Policy '{retryPolicy}' requires '{OtlpDiskRetryDirectoryPathEnvVar}' to be configured."); } } else
src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md+3 −6 modified@@ -652,12 +652,9 @@ want to solicit feedback from the community. Added in `1.8.0`. * When set to `disk`, it enables retries by storing telemetry on disk during - transient errors. The default path where the telemetry is stored is - obtained by calling - [Path.GetTempPath()](https://learn.microsoft.com/dotnet/api/system.io.path.gettemppath) - or can be customized by setting - `OTEL_DOTNET_EXPERIMENTAL_OTLP_DISK_RETRY_DIRECTORY_PATH` environment - variable. + transient errors. You MUST set + `OTEL_DOTNET_EXPERIMENTAL_OTLP_DISK_RETRY_DIRECTORY_PATH` to a dedicated + directory location. The OTLP exporter utilizes a forked version of the [OpenTelemetry.PersistentStorage.FileSystem](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.PersistentStorage.FileSystem)
test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsExtensionsTests.cs+41 −3 modified@@ -102,14 +102,11 @@ public void AppendPathIfNotPresent_TracesPath_AppendsCorrectly(string input, str #pragma warning disable CS0618 // Suppressing gRPC obsolete warning [InlineData(OtlpExportProtocol.Grpc, typeof(OtlpGrpcExportClient), false, 10000, null)] [InlineData(OtlpExportProtocol.Grpc, typeof(OtlpGrpcExportClient), false, 10000, "in_memory")] - [InlineData(OtlpExportProtocol.Grpc, typeof(OtlpGrpcExportClient), false, 10000, "disk")] #pragma warning restore CS0618 // Suppressing gRPC obsolete warning [InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpExportClient), false, 10000, null)] [InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpExportClient), true, 8000, null)] [InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpExportClient), false, 10000, "in_memory")] [InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpExportClient), true, 8000, "in_memory")] - [InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpExportClient), false, 10000, "disk")] - [InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpExportClient), true, 8000, "disk")] public void GetTransmissionHandler_InitializesCorrectHandlerExportClientAndTimeoutValue(OtlpExportProtocol protocol, Type exportClientType, bool customHttpClient, int expectedTimeoutMilliseconds, string? retryStrategy) { var exporterOptions = new OtlpExporterOptions() { Protocol = protocol }; @@ -129,6 +126,47 @@ public void GetTransmissionHandler_InitializesCorrectHandlerExportClientAndTimeo AssertTransmissionHandler(transmissionHandler, exportClientType, expectedTimeoutMilliseconds, retryStrategy); } + [Theory] +#pragma warning disable CS0618 // Suppressing gRPC obsolete warning + [InlineData(OtlpExportProtocol.Grpc, typeof(OtlpGrpcExportClient), false, 10000)] +#pragma warning restore CS0618 // Suppressing gRPC obsolete warning + [InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpExportClient), false, 10000)] + [InlineData(OtlpExportProtocol.HttpProtobuf, typeof(OtlpHttpExportClient), true, 8000)] + public void GetTransmissionHandler_DiskRetryWithDirectory_InitializesCorrectHandlerExportClientAndTimeoutValue(OtlpExportProtocol protocol, Type exportClientType, bool customHttpClient, int expectedTimeoutMilliseconds) + { + var exporterOptions = new OtlpExporterOptions() { Protocol = protocol }; + if (customHttpClient) + { + exporterOptions.HttpClientFactory = () => + { + return new HttpClient { Timeout = TimeSpan.FromMilliseconds(expectedTimeoutMilliseconds) }; + }; + } + + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection( + new Dictionary<string, string?> + { + [ExperimentalOptions.OtlpRetryEnvVar] = "disk", + [ExperimentalOptions.OtlpDiskRetryDirectoryPathEnvVar] = Path.GetTempPath(), + }) + .Build(); + + var transmissionHandler = exporterOptions.GetExportTransmissionHandler(new ExperimentalOptions(configuration), OtlpSignalType.Traces); + AssertTransmissionHandler(transmissionHandler, exportClientType, expectedTimeoutMilliseconds, "disk"); + } + + [Fact] + public void GetTransmissionHandler_DiskRetryWithoutDirectory_Throws() + { + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary<string, string?> { [ExperimentalOptions.OtlpRetryEnvVar] = "disk" }) + .Build(); + + var exception = Assert.Throws<NotSupportedException>(() => new ExperimentalOptions(configuration)); + Assert.Contains(ExperimentalOptions.OtlpDiskRetryDirectoryPathEnvVar, exception.Message, StringComparison.Ordinal); + } + [Theory] [InlineData("Traces", "traces")] [InlineData("Logs", "logs")]
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-4625-4j76-fww9ghsaADVISORY
- github.com/open-telemetry/opentelemetry-dotnet/commit/78dffdc5ebdf3dc090fdb94e3f1a32d3d1e26dfdghsa
- github.com/open-telemetry/opentelemetry-dotnet/pull/7106nvd
- github.com/open-telemetry/opentelemetry-dotnet/security/advisories/GHSA-4625-4j76-fww9nvd
- nvd.nist.gov/vuln/detail/CVE-2026-42191ghsa
News mentions
0No linked articles in our index yet.