From 038d57a063fd0d43d8a5bd404efaebbdd729a8a6 Mon Sep 17 00:00:00 2001 From: ttbombadil Date: Mon, 12 Oct 2026 10:44:03 +0200 Subject: [PATCH] fix(security): drop Replit and Google Fonts hosts from the CSP Since #244 the client loads no third-party resources, so script-src, style-src, connect-src and font-src only allow the UnoSim origin. The entrypoint test now also rejects any third-party host in the policy (test change approved by the owner). Co-Authored-By: Claude Opus 5.5 --- server/index.ts | 8 ++++---- tests/server/dev-entrypoint.test.ts | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/server/index.ts b/server/index.ts index 275d6f8e8..236823d5e 100644 --- a/server/index.ts +++ b/server/index.ts @@ -60,11 +60,11 @@ app.use( contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], - scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", "https://replit.com", "blob:"], - styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"], + scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", "blob:"], + styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", "data:", "blob:"], - connectSrc: ["'self'", "ws:", "wss:", "https://fonts.googleapis.com", "https://fonts.gstatic.com"], - fontSrc: ["'self'", "data:", "https://fonts.gstatic.com"], + connectSrc: ["'self'", "ws:", "wss:"], + fontSrc: ["'self'", "data:"], workerSrc: ["'self'", "blob:", "data:"], childSrc: ["'self'", "blob:"], // Wichtig für ältere Browser/Playwright frameAncestors: parseAllowedFrameAncestors(), diff --git a/tests/server/dev-entrypoint.test.ts b/tests/server/dev-entrypoint.test.ts index 3427a2e7e..f2af6ed6e 100644 --- a/tests/server/dev-entrypoint.test.ts +++ b/tests/server/dev-entrypoint.test.ts @@ -167,9 +167,9 @@ describe("local development entrypoint", () => { })); expect(directives.get("default-src")).toEqual(["'self'"]); expect(directives.get("script-src")).toContain("'self'"); - expect(directives.get("connect-src")).toEqual([ - "'self'", "ws:", "wss:", "https://fonts.googleapis.com", "https://fonts.gstatic.com", - ]); + expect(directives.get("connect-src")).toEqual(["'self'", "ws:", "wss:"]); + // Fonts are self-hosted; the page loads nothing from third-party hosts. + expect(policy).not.toMatch(/https?:\/\/(?!course\.example)/); expect(directives.get("worker-src")).toEqual(["'self'", "blob:", "data:"]); expect(directives.get("frame-ancestors")).toEqual(["'self'", "https://course.example"]); expect(response.headers.get("x-frame-options")).toBeNull();