Implement Content-Security-Policy headers and strict content-type handling for non-API responses, with x-content-type-options applied to all routes. Adds security-headers test suite to verify header presence. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
27 lines
1.1 KiB
TypeScript
27 lines
1.1 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { mkdtempSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { createApp } from "../src/app";
|
|
import { openDb } from "../src/db";
|
|
import { loadOrCreateKey } from "../src/lib/crypto";
|
|
|
|
function makeApp() {
|
|
const dir = mkdtempSync(join(tmpdir(), "helios-"));
|
|
return createApp({ db: openDb(dir), key: loadOrCreateKey(dir), dataDir: dir });
|
|
}
|
|
|
|
describe("security headers", () => {
|
|
test("API responses: nosniff", async () => {
|
|
const res = await makeApp().request("/api/health");
|
|
expect(res.headers.get("x-content-type-options")).toBe("nosniff");
|
|
});
|
|
test("non-API responses: CSP + nosniff + referrer policy", async () => {
|
|
const res = await makeApp().request("/anything");
|
|
expect(res.headers.get("content-security-policy")).toContain("default-src 'self'");
|
|
expect(res.headers.get("content-security-policy")).toContain("frame-ancestors 'none'");
|
|
expect(res.headers.get("x-content-type-options")).toBe("nosniff");
|
|
expect(res.headers.get("referrer-policy")).toBe("no-referrer");
|
|
});
|
|
});
|