From 67d771869b9a4bad26b27cded0f49a4b87310daa Mon Sep 17 00:00:00 2001 From: pmlanger Date: Tue, 5 Nov 2024 12:01:54 +0100 Subject: [PATCH] fix(instrumentation-http): skip malformed forwarded headers (#5099) --- experimental/CHANGELOG.md | 2 ++ .../src/utils.ts | 12 ++++++++++-- .../test/integrations/http-enable.test.ts | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index aad560d8fc..bb08a41082 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -11,6 +11,8 @@ All notable changes to experimental packages in this project will be documented ### :bug: (Bug Fix) +* fix(instrumentation-http): skip malformed forwarded headers. [#5095](https://github.com/open-telemetry/opentelemetry-js/issues/5095) @pmlanger + ### :books: (Refine Doc) ### :house: (Internal) diff --git a/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts b/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts index a03600dfd4..ffbdeff675 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/src/utils.ts @@ -572,7 +572,7 @@ function getServerAddress( ): { host: string; port?: string } | null { const forwardedHeader = request.headers['forwarded']; if (forwardedHeader) { - for (const entry of forwardedParse(forwardedHeader)) { + for (const entry of parseForwardedHeader(forwardedHeader)) { if (entry.host) { return parseHostHeader(entry.host, entry.proto); } @@ -635,7 +635,7 @@ export function getRemoteClientAddress( ): string | null { const forwardedHeader = request.headers['forwarded']; if (forwardedHeader) { - for (const entry of forwardedParse(forwardedHeader)) { + for (const entry of parseForwardedHeader(forwardedHeader)) { if (entry.for) { return entry.for; } @@ -916,3 +916,11 @@ function normalizeMethod(method?: string | null) { return '_OTHER'; } + +function parseForwardedHeader(header: string): Record[] { + try { + return forwardedParse(header); + } catch { + return []; + } +} diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/integrations/http-enable.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/integrations/http-enable.test.ts index ef42ced2e9..558bbcb8ff 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/integrations/http-enable.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/integrations/http-enable.test.ts @@ -277,6 +277,20 @@ describe('HttpInstrumentation Integration tests', () => { assert.ok(result.reqHeaders[DummyPropagation.SPAN_CONTEXT_KEY]); }); + it('should succeed even with malformed Forwarded header', async () => { + const spans = memoryExporter.getFinishedSpans(); + assert.strictEqual(spans.length, 0); + + const headers = { 'x-foo': 'foo', forwarded: 'malformed' }; + const result = await httpRequest.get( + new url.URL(`${protocol}://localhost:${mockServerPort}/?query=test`), + { headers } + ); + + assert.ok(result.reqHeaders[DummyPropagation.TRACE_CONTEXT_KEY]); + assert.ok(result.reqHeaders[DummyPropagation.SPAN_CONTEXT_KEY]); + }); + it('should create a span for GET requests and add propagation headers with Expect headers', async () => { let spans = memoryExporter.getFinishedSpans(); assert.strictEqual(spans.length, 0);