From 7b0e279a30705c4bd5f89c1cd250f54a34d58f36 Mon Sep 17 00:00:00 2001 From: shekohex Date: Wed, 1 Apr 2026 15:19:20 +0200 Subject: [PATCH] fix(server): strip hop-by-hop proxy response headers (#813) * fix(server): strip hop-by-hop proxy response headers * chore(ui): remove unused markdown runtime destructures --- packages/web/server/lib/opencode/proxy.js | 9 +++++++++ packages/web/server/proxy-headers.test.js | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/packages/web/server/lib/opencode/proxy.js b/packages/web/server/lib/opencode/proxy.js index 0991aa4d..4547f115 100644 --- a/packages/web/server/lib/opencode/proxy.js +++ b/packages/web/server/lib/opencode/proxy.js @@ -1,6 +1,8 @@ import express from 'express'; import { createProxyMiddleware } from 'http-proxy-middleware'; +import { shouldForwardProxyResponseHeader } from '../../proxy-headers.js'; + export const registerOpenCodeProxy = (app, deps) => { const { fs, @@ -160,6 +162,13 @@ export const registerOpenCodeProxy = (app, deps) => { // This avoids compressed-body/header mismatches in multi-proxy setups. proxyReq.setHeader('accept-encoding', 'identity'); }, + proxyRes: (proxyRes) => { + for (const key of Object.keys(proxyRes.headers || {})) { + if (!shouldForwardProxyResponseHeader(key)) { + delete proxyRes.headers[key]; + } + } + }, error: (err, _req, res) => { console.error('[proxy] OpenCode proxy error:', err.message); if (res && !res.headersSent && typeof res.status === 'function') { diff --git a/packages/web/server/proxy-headers.test.js b/packages/web/server/proxy-headers.test.js index b0e85353..f3270814 100644 --- a/packages/web/server/proxy-headers.test.js +++ b/packages/web/server/proxy-headers.test.js @@ -23,6 +23,11 @@ describe('OpenCode proxy header handling', () => { expect(shouldForwardProxyResponseHeader('Content-Encoding')).toBe(false); }); + it('drops transfer-encoding from forwarded response headers', () => { + expect(shouldForwardProxyResponseHeader('transfer-encoding')).toBe(false); + expect(shouldForwardProxyResponseHeader('Transfer-Encoding')).toBe(false); + }); + it('still keeps ordinary response headers', () => { expect(shouldForwardProxyResponseHeader('content-type')).toBe(true); expect(shouldForwardProxyResponseHeader('etag')).toBe(true);