diff --git a/CHANGELOG.md b/CHANGELOG.md index ad618f37c..d0519e0d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ You can also check the ## Unreleased +- Fixes + - Correctly set CSP headers for index pages + ## 6.5.0 – 2026-06-01 - Features diff --git a/app/middleware.ts b/app/middleware.ts index 0dfbc5f5f..f081184f9 100644 --- a/app/middleware.ts +++ b/app/middleware.ts @@ -64,6 +64,12 @@ export function middleware(request: NextRequest) { export const config = { matcher: [ + // The negative-lookahead pattern below gets compiled by Next.js (when i18n + // is configured) into a regex that requires two path segments (locale + + // rest), which silently excludes bare locale-root paths like "/", "/de", + // "/en". Add those explicitly so they still go through the middleware. + "/", + "/(de|fr|it|en)", { source: "/((?!_next/static|_next/image|favicon\\.ico).*)", missing: [ diff --git a/e2e/csp-headers.spec.ts b/e2e/csp-headers.spec.ts new file mode 100644 index 000000000..9f932f5b5 --- /dev/null +++ b/e2e/csp-headers.spec.ts @@ -0,0 +1,25 @@ +import { setup } from "./common"; + +const { test, describe, expect } = setup(); + +describe("CSP headers", () => { + test("should be set on the index page", async ({ page }) => { + const response = await page.goto("/en"); + expect(response).not.toBeNull(); + const csp = + response!.headers()["content-security-policy"] ?? + response!.headers()["content-security-policy-report-only"]; + expect(csp).toBeTruthy(); + expect(csp).toContain("frame-ancestors"); + }); + + test("should be set on the imprint page", async ({ page }) => { + const response = await page.goto("/en/imprint"); + expect(response).not.toBeNull(); + const csp = + response!.headers()["content-security-policy"] ?? + response!.headers()["content-security-policy-report-only"]; + expect(csp).toBeTruthy(); + expect(csp).toContain("frame-ancestors"); + }); +});