Skip to content

feat(game): enforce the Content-Security-Policy - #306

Merged
arrzdev merged 3 commits into
mainfrom
feat/enforce-csp
Nov 9, 2026
Merged

arrzdev merged 3 commits into
mainfrom
feat/enforce-csp

Conversation

@arrzdev

@arrzdev arrzdev commented Nov 9, 2026

Copy link
Copy Markdown
Owner

What and why

The site sent its Content-Security-Policy as Content-Security-Policy-Report-Only, so an injected script would still run. It now sends Content-Security-Policy, the same value from the Worker (security-headers.ts) and from public/_headers. The policy text did not change, except that 'unsafe-inline' in script-src now has a comment saying why it stays: the server-rendered pages carry inline scripts without a nonce. A nonce or hash rewrite is out of scope.

  • e2e/support/test.ts: every spec's test now fails when a page fires securitypolicyviolation or prints a CSP error in the console, in every context including a second player's.
  • e2e/csp.spec.ts: checks the enforced header on a page and a build asset, that the guard catches a refused request, and that no spec imports test from @playwright/test directly.
  • A dev or e2e run has its backend on another port than the page, so the Worker adds that origin to connect-src and img-src (plus its ws:// form for connect-src) when VITE_BACKEND_URL is set. Production does not set it, so its policy is the static one and public/_headers still matches.

Violations the guard found with the policy enforced (Chromium, whole suite): the e2e backend origin in connect-src (nearly every spec, from /api/v1/auth/get-session, /events/game, sign-up, sign-in and invite links) and in img-src (avatar.spec.ts, avatar images). No script, style, font or eval violations.

How to verify

  • pnpm test:e2e on both projects: 1009 passed, 219 skipped, 0 failed (Chromium + WebKit, guard on).
  • pnpm typecheck, pnpm biome:check and the scoped game build pass.
  • A production-mode build with an analytics token set loads https://static.cloudflareinsights.com/beacon.min.js with no violation (the request was stubbed locally).
  • After deploy: curl -sI https://abalone.tudu.dev/ and one /assets/*.js show content-security-policy, and no report-only header.

@arrzdev
arrzdev merged commit 1dccf91 into main Nov 9, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant