Skip to content

fix: enforce Content-Security-Policy instead of report-only mode#126

Merged
rubenhensen merged 1 commit into
mainfrom
fix/enforce-csp
Jul 2, 2026
Merged

fix: enforce Content-Security-Policy instead of report-only mode#126
rubenhensen merged 1 commit into
mainfrom
fix/enforce-csp

Conversation

@dobby-coder

@dobby-coder dobby-coder Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Closes #124

What

Rename the reportOnly key to directives inside the csp block of svelte.config.js so the Content-Security-Policy is enforced by browsers rather than only reported.

Why

Closes the draft security advisory tracked in #124 (GHSA-pcw7-qg5v-c99f). The CSP had been in Report-Only mode while issue #60 collected violation reports; the directives are now known-good, so the policy is switched to enforcement.

Details

  • csp.reportOnlycsp.directives (identical directive set, mode: 'auto' unchanged).
  • report-uri: ['/api/csp-report'] is retained inside the enforced directives, so browsers still POST reports for blocked violations to the existing /api/csp-report sink.
  • I did not add a parallel reportOnly block: with an identical directive set it would only re-report violations that are already being blocked, adding noise without value. (SvelteKit supports both keys simultaneously if a stricter preview policy is wanted later.)
  • Updated tests/unit/csp-config.test.ts to assert the enforced (directives) mode instead of report-only.

Verification

  • vite build — ✅

  • npm run check (svelte-check) — ✅

  • vitest run — ✅ 94/94 tests pass

  • Ran the built adapter-node server and confirmed the response header is now the enforcing content-security-policy: (not -report-only), and still carries report-uri /api/csp-report:

    content-security-policy: default-src 'self'; connect-src 'self' https://api.iconify.design; ...
      script-src 'self' 'sha256-…' 'nonce-…'; style-src 'self' 'unsafe-inline'; base-uri 'self';
      form-action 'self'; frame-ancestors 'none'; report-uri /api/csp-report
    

🤖 Generated with Claude Code

Rename the `reportOnly` key to `directives` in the SvelteKit `csp` config so
browsers enforce the Content-Security-Policy rather than only reporting
violations. `report-uri` is retained inside the enforced directives so
blocked-violation reports still reach /api/csp-report.

Update tests/unit/csp-config.test.ts to assert the enforced (`directives`)
mode.

Refs #124

@dobby-coder dobby-coder Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rules Dobby 2 — consolidated review (cycle 1)

The code change is clean and correct: csp.reportOnlycsp.directives switches the CSP to enforced, report-uri: ['/api/csp-report'] is retained inside the enforced directives, and the tests are updated accordingly. Review Dobby 2 found no code findings, and the built adapter-node server was verified to serve an enforcing content-security-policy header (not -report-only) that still carries report-uri /api/csp-report. The rule checks (sveltekit-csp-report-only-needs-report-uri, conventional-commit-pr-titles, tests-required-on-fixes, no-justification-paragraphs-for-simple-changes, promised-vs-delivered) all pass.

One issue to fix before sign-off:

PR body — the closing keyword will not auto-close #124 (pr-close-issue-keywords)
The body intends to resolve #124 ("Closes the draft security advisory tracked in #124"), but a GitHub closing keyword only fires when it immediately precedes the reference. The prose "the draft security advisory tracked in" sits between Closes and #124, so this is a soft mention that will not close the issue on merge. The trailing Refs #124 also does not auto-close. On merge, #124 will be left open and need manual closing.

Fix: add a dedicated line with the keyword immediately followed by the reference, e.g.

Closes #124

@dobby-coder dobby-coder Bot requested a review from rubenhensen July 2, 2026 03:00

@dobby-coder dobby-coder Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rules Dobby 2 — consolidated review (cycle 2): SIGN-OFF

Verdict is APPROVE — posted as COMMENT only because GitHub blocks self-approval on a bot-authored PR (Can not approve your own pull request). Treat this as a clean approval; marking the PR ready for review.

The cycle-1 finding is resolved: the PR body now opens with a dedicated Closes #124 line (closing keyword immediately followed by the reference, same-repo, base main), so the security-advisory issue will auto-close on merge.

Code change is correct and minimal: csp.reportOnlycsp.directives switches the Content-Security-Policy to enforced, the identical directive set is preserved, and report-uri: ['/api/csp-report'] is retained inside the enforced directives (the src/routes/api/csp-report/+server.ts sink exists). tests/unit/csp-config.test.ts was updated to assert the enforced (directives) mode; 94/94 vitest pass and the built adapter-node server was confirmed to emit an enforcing content-security-policy header (not -report-only).

Rule checks all pass: sveltekit-csp-report-only-needs-report-uri (report-uri + sink retained), pr-close-issue-keywords (fixed), conventional-commit-pr-titles (fix:), tests-required-on-fixes, no-justification-paragraphs-for-simple-changes, promised-vs-delivered (body claims match the diff), vitest-mock-hoisting (n/a). pr-review-assignments was the only gap — no reviewer was assigned; I assigned @rubenhensen directly.

Review Dobby 2 reported no code findings. No blocking issues remain.

@dobby-coder dobby-coder Bot marked this pull request as ready for review July 2, 2026 03:01
@rubenhensen rubenhensen merged commit 0231588 into main Jul 2, 2026
17 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.

security: enforce Content-Security-Policy instead of report-only mode

1 participant