Files
OmniRoute/tests/unit/mitm-sanitize-headers.test.ts
Diego Rodrigues de Sa e Souza 3026183120 refactor(mitm): replace inspector utilities clean-room (#11748)
Merged via /merge-batch (v3.8.51 provenance sweep). Boarded and validated together with the batch's other provenance PRs in a combined worktree — full gate suite green. Thank you.
2026-08-28 05:04:49 -03:00

69 lines
2.8 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import { sanitizeHeaders } from "../../src/mitm/sanitizeHeaders.ts";
// `set-cookie` is a response-side credential header. maskSecret()'s format
// heuristics (Bearer / sk- / >=40-char) do NOT match an arbitrary session or
// CSRF cookie, so before this fix a Set-Cookie value landed verbatim in the
// sanitized output (and thus in inspector JSON). It must be fully redacted.
test("sanitizeHeaders — set-cookie (string) is fully redacted", () => {
const out = sanitizeHeaders({ "set-cookie": "session=abc123DEF; Path=/; HttpOnly" });
assert.equal(out["set-cookie"], "[REDACTED]");
assert.ok(!JSON.stringify(out).includes("abc123DEF"), "raw cookie value must not leak");
});
test("sanitizeHeaders — set-cookie (array of cookies) is fully redacted", () => {
const out = sanitizeHeaders({
"set-cookie": ["sid=s3cr3tValue; HttpOnly", "csrf=t0kenValue; Secure"],
});
assert.equal(out["set-cookie"], "[REDACTED]");
assert.ok(!/s3cr3tValue|t0kenValue/.test(JSON.stringify(out)), "no cookie value may leak");
});
test("sanitizeHeaders — Set-Cookie header name is matched case-insensitively", () => {
const out = sanitizeHeaders({ "Set-Cookie": "session=abc123DEF" });
assert.equal(out["set-cookie"], "[REDACTED]");
});
test("sanitizeHeaders — request cookies are fully redacted regardless of token shape", () => {
const out = sanitizeHeaders({ Cookie: "session=short; csrf=also-short" });
assert.deepEqual(out, { cookie: "[REDACTED]" });
});
test("sanitizeHeaders — authorization bearer token is still masked, not leaked", () => {
const out = sanitizeHeaders({ authorization: "Bearer sk-proj-abcdefghijklmnop" });
assert.ok(
!out["authorization"].includes("sk-proj-abcdefghijklmnop"),
"bearer token must be masked"
);
});
test("sanitizeHeaders — drops framing, hop-by-hop, and proxy credential headers", () => {
const out = sanitizeHeaders({
Host: "provider.example",
Connection: "keep-alive",
"Content-Length": "42",
"Proxy-Authorization": "Basic c2VjcmV0",
"Proxy-Authenticate": "Basic realm=proxy",
TE: "trailers",
Upgrade: "websocket",
"X-Keep": "visible",
});
assert.deepEqual(out, { "x-keep": "visible" });
});
test("sanitizeHeaders — non-secret headers pass through unchanged", () => {
const out = sanitizeHeaders({ "content-type": "application/json", "x-request-id": "req-42" });
assert.equal(out["content-type"], "application/json");
assert.equal(out["x-request-id"], "req-42");
});
test("sanitizeHeaders — lowercases names, joins arrays predictably, and omits undefined", () => {
const out = sanitizeHeaders({
"X-Trace": ["edge-a", "edge-b"],
"X-Missing": undefined,
});
assert.deepEqual(out, { "x-trace": "edge-a, edge-b" });
});