import { describe, expect, it } from "vitest"; import { applyDocumentSecurityHeaders, applySitesSecurityHeaders, buildDocumentCsp, } from "@/worker/lib/security-headers"; describe("document security headers", () => { it("includes the Sentry origin in connect-src when a DSN is configured", () => { const csp = buildDocumentCsp({ nonce: "nonce-test", requestUrl: "https://bland.tools/acme/page-1", sentryDsn: "https://public@example.ingest.sentry.io/1", }); expect(csp).toContain("connect-src 'self' https://cloudflareinsights.com https://example.ingest.sentry.io"); expect(csp).toContain("script-src 'self' 'nonce-nonce-test' https://static.cloudflareinsights.com"); expect(csp).not.toContain("challenges.cloudflare.com"); expect(csp).toContain("upgrade-insecure-requests"); }); it("omits the Sentry origin when no DSN is configured", () => { const csp = buildDocumentCsp({ nonce: "nonce-test", requestUrl: "https://bland.tools/acme/page-1", sentryDsn: null, }); expect(csp).not.toContain("ingest.sentry.io"); expect(csp).not.toContain("fonts.googleapis.com"); expect(csp).not.toContain("fonts.gstatic.com"); expect(csp).toContain("style-src 'self' 'unsafe-inline'"); expect(csp).toContain("font-src 'self' https://esm.sh"); }); it("relaxes connect-src for localhost without forcing insecure upgrades", () => { const csp = buildDocumentCsp({ nonce: "nonce-test", requestUrl: "http://localhost:8787/acme/page-1", sentryDsn: null, }); expect(csp).toContain("connect-src 'self' https://cloudflareinsights.com http: https: ws: wss:"); expect(csp).toContain("script-src 'self' https://static.cloudflareinsights.com 'unsafe-inline' 'unsafe-eval'"); expect(csp).not.toContain("upgrade-insecure-requests"); }); it("applies CSP and baseline headers to document responses", async () => { const response = applyDocumentSecurityHeaders(new Response(""), { nonce: "nonce-test", requestUrl: "https://bland.tools/acme/page-1", sentryDsn: null, }); expect(response.headers.get("Content-Security-Policy")).toContain("'nonce-nonce-test'"); expect(response.headers.get("X-Frame-Options")).toBe("DENY"); expect(response.headers.get("Referrer-Policy")).toBe("strict-origin-when-cross-origin"); expect(response.headers.get("X-Content-Type-Options")).toBe("nosniff"); expect(await response.text()).toBe(""); }); it("allows same-origin scripts and Cloudflare Insights on Sites responses", () => { const response = applySitesSecurityHeaders(new Response("")); const csp = response.headers.get("Content-Security-Policy"); expect(csp).toContain("script-src 'self' https://static.cloudflareinsights.com"); expect(csp).toContain("connect-src 'self' https://cloudflareinsights.com"); expect(csp).not.toContain("script-src 'self' 'unsafe-inline'"); expect(csp).not.toContain("'unsafe-eval'"); }); });