Files
OmniRoute/tests/unit/generated-relay-header-denylist.test.ts
Paco Cartones 28601b456e fix(relay): strip unsafe forwarded headers (#11533)
Validated in a combined 10-PR batch worktree off release/v3.8.51 tip.
- Focused test: tests/unit/generated-relay-header-denylist.test.ts — 3/3 contract pass plus 30/30 related SSRF tests
- typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity gates — all OK
- Full-repo lint: 503 pre-existing problems confirmed identical on the pure release/v3.8.51 tip — unrelated to this diff

⚠️ base-red inherited: #11449

Thanks for applying one canonical header denylist across the generated Cloudflare/Vercel/Deno relays so hop-by-hop, framing, and proxy-auth/relay-control headers stop leaking upstream.
2026-08-25 13:12:50 -03:00

46 lines
1.5 KiB
TypeScript

import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { __buildRelayWorkerForTest } from "../../src/app/api/settings/proxy/deno-deploy/route";
import { __buildRelayFunctionForTest } from "../../src/app/api/settings/proxy/vercel-deploy/route";
import { buildCloudflareWorkerScript } from "../../src/lib/proxyRelay/cloudflareWorkerScript";
const FORBIDDEN_RELAY_HEADERS = [
"host",
"connection",
"content-length",
"keep-alive",
"proxy-connection",
"proxy-authenticate",
"proxy-authorization",
"transfer-encoding",
"te",
"trailer",
"upgrade",
"x-relay-target",
"x-relay-path",
"x-relay-auth",
];
const relays = {
Cloudflare: buildCloudflareWorkerScript("relay-secret"),
Vercel: __buildRelayFunctionForTest("relay-secret"),
Deno: __buildRelayWorkerForTest("relay-secret"),
};
describe("generated relay request header sanitization", () => {
for (const [runtime, source] of Object.entries(relays)) {
it(`${runtime} strips relay controls, framing, and hop-by-hop headers`, () => {
const deletionBlock = source.match(
/const headers = new Headers\([^;]+\);\s*\[([\s\S]*?)\]\.forEach\(\(?h\)?\s*=>\s*headers\.delete\(h\)\);/
);
assert.ok(deletionBlock, `${runtime} generated source must sanitize forwarded headers`);
const deletedHeaders = [...deletionBlock[1].matchAll(/["']([^"']+)["']/g)].map(
(match) => match[1]
);
assert.deepEqual(deletedHeaders, FORBIDDEN_RELAY_HEADERS);
});
}
});