CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
27 lines
1.2 KiB
JavaScript
27 lines
1.2 KiB
JavaScript
import { describe, expect, it } from "vitest";
|
|
import nextConfig from "./next.config.mjs";
|
|
import { securityHeaders } from "./security-headers.mjs";
|
|
|
|
describe("Sicherheits-Header (QA-15 F-16)", () => {
|
|
it("next.config liefert die Header fuer alle Pfade", async () => {
|
|
const rules = await nextConfig.headers();
|
|
expect(rules).toHaveLength(1);
|
|
expect(rules[0].source).toBe("/:path*");
|
|
expect(rules[0].headers).toEqual(securityHeaders);
|
|
});
|
|
|
|
it("enthaelt nosniff, Rahmenverbot und eine CSP gegen Einbettung", () => {
|
|
const byKey = Object.fromEntries(securityHeaders.map((h) => [h.key, h.value]));
|
|
expect(byKey["X-Content-Type-Options"]).toBe("nosniff");
|
|
expect(byKey["X-Frame-Options"]).toBe("DENY");
|
|
expect(byKey["Content-Security-Policy"]).toContain("frame-ancestors 'none'");
|
|
expect(byKey["Content-Security-Policy"]).toContain("object-src 'none'");
|
|
expect(byKey["Referrer-Policy"]).toBeTruthy();
|
|
});
|
|
|
|
it("verbietet keine Skripte oder Verbindungen (Next.js braucht Inline-Skripte)", () => {
|
|
const csp = securityHeaders.find((h) => h.key === "Content-Security-Policy").value;
|
|
expect(csp).not.toMatch(/script-src|default-src|connect-src/);
|
|
});
|
|
});
|