| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 |
- # FrankenPHP Caddyfile for the ui container.
- # Serves Slim from public/ on :8080.
- {
- frankenphp
- order php_server before file_server
- auto_https off
- admin off
- servers {
- trusted_proxies static private_ranges
- }
- }
- :8080 {
- root * /app/public
- encode zstd gzip
- # ── Security headers (M14) ──────────────────────────────────────────
- # CSP is set per-response by `App\Http\CspMiddleware` so the
- # `script-src 'nonce-…'` value can change per request, dropping
- # `'unsafe-inline'` / `'unsafe-eval'` (SEC_REVIEW F24).
- header {
- -Server
- -X-Powered-By
- X-Content-Type-Options "nosniff"
- X-Frame-Options "DENY"
- Referrer-Policy "strict-origin-when-cross-origin"
- Permissions-Policy "geolocation=(), microphone=(), camera=()"
- # SEC_REVIEW F59: modern cross-origin isolation headers.
- # - COOP `same-origin` isolates the browsing context from any
- # popups it opens; a `window.opener.location = …` from a
- # newly-spawned cross-origin tab can no longer reach back.
- # - CORP `same-origin` tells the browser this resource may
- # only be loaded by same-origin documents (defeats sub-
- # resource leaks via cross-origin <img>/<script>/<link>
- # inclusion).
- # - X-Permitted-Cross-Domain-Policies `none` blocks legacy
- # Adobe Flash / Acrobat cross-domain.xml lookups.
- # COEP `require-corp` is deliberately NOT set — that requires
- # every cross-origin resource (e.g. the jsDelivr-hosted
- # RapiDoc on /api/docs) to opt in via CORP, which we don't
- # control. We're only after the COOP/CORP/legacy-Flash
- # benefits the SEC_REVIEW called out.
- Cross-Origin-Opener-Policy "same-origin"
- Cross-Origin-Resource-Policy "same-origin"
- X-Permitted-Cross-Domain-Policies "none"
- }
- @prod expression `{env.APP_ENV} == "production"`
- header @prod Strict-Transport-Security "max-age=31536000; includeSubDomains"
- php_server
- }
|