# [OneCollector] 限制响应体读取大小 #4117 ## 漏洞概述 该 Pull Request 修复了 `OneCollector` 组件中 HTTP 响应体读取时未限制长度的问题。当 OneCollector 通过 HTTP JSON 传输发送遥测数据时,如果服务器返回过大的响应体,可能导致内存耗尽或拒绝服务。 ## 影响范围 - **组件**: OpenTelemetry .NET Contrib 中的 OneCollector 导出器 - **传输方式**: HTTP JSON 传输 - **风险**: 未限制响应体大小可能导致应用程序内存溢出 ## 修复方案 1. 引入共享辅助方法 `TryGetResponseBodyAsString`,默认限制为 4MB 2. 在 `HttpJsonPostTransport` 中使用新的辅助方法 3. 添加单元测试验证截断和字符集/流行为 ## 代码变更 ### src/Shared/HttpClientHelpers.cs ```csharp internal static class HttpClientHelpers { private const int DefaultMaxResponseBodyLength = 4 * 1024 * 1024; // 4MB internal static bool TryGetResponseBodyAsString(HttpResponseMessage response, out string? responseBody) { responseBody = null; if (response.Content == null) { return false; } try { // 限制响应体大小,防止内存溢出 var contentLength = response.Content.Headers.ContentLength; if (contentLength.HasValue && contentLength.Value > DefaultMaxResponseBodyLength) { return false; } responseBody = response.Content.ReadAsStringAsync().Result; return true; } catch { return false; } } } ``` ### src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs ```csharp // 修改前 var responseBody = await response.Content.ReadAsStringAsync(); // 修改后 if (!HttpClientHelpers.TryGetResponseBodyAsString(response, out var responseBody)) { // 处理响应体过大或读取失败的情况 if (this.logger.IsEnabled(LogLevel.Information)) { this.logger.LogInformation("Response body too large or failed to read."); } return; } ``` ## 测试覆盖 - 添加了单元测试验证截断行为 - 验证字符集和流处理 - 测试 4MB 限制边界情况