Skip to content

Harden production configuration: security headers, secrets, CSRF (#526)#543

Open
maltehuebner wants to merge 1 commit into
mainfrom
fix/prod-hardening-526
Open

Harden production configuration: security headers, secrets, CSRF (#526)#543
maltehuebner wants to merge 1 commit into
mainfrom
fix/prod-hardening-526

Conversation

@maltehuebner

Copy link
Copy Markdown
Contributor

Addresses the production-hardening gaps in #526.

Changes

  • Security headers: new SecurityHeadersSubscriber on kernel.response sets X-Content-Type-Options: nosniff, X-Frame-Options: SAMEORIGIN, Referrer-Policy: strict-origin-when-cross-origin, Strict-Transport-Security (only on secure requests), and a Content-Security-Policy: frame-ancestors 'self'. Headers are set with replace=false so per-controller overrides still win. Registered automatically via autoconfigure.
  • CSRF: enabled framework.csrf_protection (symfony/security-csrf is already installed). JSON API endpoints are unaffected (form-only feature).
  • APP_SECRET: committed value replaced with a placeholder; must be provided in production via env var / secrets vault. Rotate the old value where it may have been reused.
  • APP_ENV: tracked default flipped from dev to prod so a deploy that forgets to set it does not silently boot in debug/profiler mode. Local development now overrides with APP_ENV=dev in the untracked .env.local.
  • .env.test: removed the ADMIN_PASSWORD=123 default (grep shows zero consumers in config/, src/, tests/).

Deliberately not implemented

  • Full script/style/connect CSP. A restrictive Content-Security-Policy (script-src, style-src, connect-src, img-src for Leaflet tiles, Algolia autocomplete, fonts, etc.) requires a complete inventory of external asset hosts plus runtime verification of the rendered frontend, which cannot be done safely without a running app (PostGIS/Redis). Only the safe, host-independent frame-ancestors directive is enforced here. A follow-up should build the enforced CSP behind report-only first. The issue's suggestion of nelmio/security-bundle was not added to avoid a new dependency for the small header set needed today.

Verification

  • vendor/bin/phpunit --testsuite="Project Test Suite" — OK (121 tests, 131 assertions)
  • vendor/bin/phpstan analyse --no-progress — No errors

Closes #526

🤖 Generated with Claude Code

Addresses several configuration hardening gaps:

- Add SecurityHeadersSubscriber (kernel.response) setting
  X-Content-Type-Options: nosniff, X-Frame-Options: SAMEORIGIN,
  Referrer-Policy and HSTS (on secure requests), plus a
  frame-ancestors Content-Security-Policy. A full script/style CSP
  is intentionally deferred (needs a frontend asset audit + runtime
  verification).
- Enable framework csrf_protection (symfony/security-csrf is present).
- Replace the committed APP_SECRET with a placeholder and flip the
  tracked APP_ENV default to prod; local dev overrides via .env.local.
- Drop the ADMIN_PASSWORD=123 default from .env.test (unused anywhere).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

[Mittel] Produktions-Härtung: Security-Header, APP_SECRET, APP_ENV, CSRF

1 participant