mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-27 01:22:10 +03:00
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.
46 lines
1.5 KiB
TypeScript
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);
|
|
});
|
|
}
|
|
});
|