From ee408653ddba661d1a29e833a40b8ff65aeacd58 Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Sun, 10 May 2026 21:16:52 -0300 Subject: [PATCH] fix(chatcore): stop leaking provider credentials in response headers Remove upstream provider headers from non-stream chatCore JSON responses to prevent authorization and API key values from being exposed to clients. Add coverage to verify sensitive provider request headers are omitted while OmniRoute metadata headers remain present. --- open-sse/handlers/chatCore.ts | 1 - tests/unit/chatcore-translation-paths.test.ts | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/open-sse/handlers/chatCore.ts b/open-sse/handlers/chatCore.ts index 5e60a86260..ec187039c5 100644 --- a/open-sse/handlers/chatCore.ts +++ b/open-sse/handlers/chatCore.ts @@ -4200,7 +4200,6 @@ export async function handleChatCore({ success: true, response: new Response(JSON.stringify(translatedResponse), { headers: { - ...Object.fromEntries(providerHeaders.entries()), "Content-Type": "application/json", [OMNIROUTE_RESPONSE_HEADERS.cache]: "MISS", ...buildOmniRouteResponseMetaHeaders({ diff --git a/tests/unit/chatcore-translation-paths.test.ts b/tests/unit/chatcore-translation-paths.test.ts index 944ab8b6c3..d5779e5583 100644 --- a/tests/unit/chatcore-translation-paths.test.ts +++ b/tests/unit/chatcore-translation-paths.test.ts @@ -1354,6 +1354,25 @@ test("chatCore attaches OmniRoute response metadata headers to non-stream respon assert.match(String(result.response.headers.get("X-OmniRoute-Response-Cost")), /^\d+\.\d{10}$/); }); +test("chatCore does not expose provider request credentials in non-stream response headers", async () => { + const { result } = await invokeChatCore({ + provider: "openai", + model: "gpt-4o-mini", + body: { + model: "gpt-4o-mini", + stream: false, + messages: [{ role: "user", content: "hide provider credentials" }], + }, + responseFormat: "openai", + }); + + assert.equal(result.success, true); + assert.equal(result.response.headers.get("authorization"), null); + assert.equal(result.response.headers.get("x-api-key"), null); + assert.equal(result.response.headers.get("Content-Type"), "application/json"); + assert.equal(result.response.headers.get("X-OmniRoute-Cache"), "MISS"); +}); + test("chatCore normalizes tool finish reasons and estimates usage when upstream omits it", async () => { const { result } = await invokeChatCore({ provider: "openai",