Caddyfile 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. # FrankenPHP Caddyfile for the ui container.
  2. # Serves Slim from public/ on :8080.
  3. {
  4. frankenphp
  5. order php_server before file_server
  6. auto_https off
  7. admin off
  8. servers {
  9. trusted_proxies static private_ranges
  10. }
  11. }
  12. :8080 {
  13. root * /app/public
  14. encode zstd gzip
  15. # ── Security headers (M14) ──────────────────────────────────────────
  16. # CSP is set per-response by `App\Http\CspMiddleware` so the
  17. # `script-src 'nonce-…'` value can change per request, dropping
  18. # `'unsafe-inline'` / `'unsafe-eval'` (SEC_REVIEW F24).
  19. header {
  20. -Server
  21. -X-Powered-By
  22. X-Content-Type-Options "nosniff"
  23. X-Frame-Options "DENY"
  24. Referrer-Policy "strict-origin-when-cross-origin"
  25. Permissions-Policy "geolocation=(), microphone=(), camera=()"
  26. # SEC_REVIEW F59: modern cross-origin isolation headers.
  27. # - COOP `same-origin` isolates the browsing context from any
  28. # popups it opens; a `window.opener.location = …` from a
  29. # newly-spawned cross-origin tab can no longer reach back.
  30. # - CORP `same-origin` tells the browser this resource may
  31. # only be loaded by same-origin documents (defeats sub-
  32. # resource leaks via cross-origin <img>/<script>/<link>
  33. # inclusion).
  34. # - X-Permitted-Cross-Domain-Policies `none` blocks legacy
  35. # Adobe Flash / Acrobat cross-domain.xml lookups.
  36. # COEP `require-corp` is deliberately NOT set — that requires
  37. # every cross-origin resource (e.g. the jsDelivr-hosted
  38. # RapiDoc on /api/docs) to opt in via CORP, which we don't
  39. # control. We're only after the COOP/CORP/legacy-Flash
  40. # benefits the SEC_REVIEW called out.
  41. Cross-Origin-Opener-Policy "same-origin"
  42. Cross-Origin-Resource-Policy "same-origin"
  43. X-Permitted-Cross-Domain-Policies "none"
  44. }
  45. # HSTS: prod-only (setting it in dev would lock you out of plain-HTTP
  46. # localhost on the same hostname for a year). The value is operator-
  47. # tuneable via the `HSTS_HEADER` env var so a deployment that wants
  48. # to apply for the browser preload list can opt in by setting:
  49. # HSTS_HEADER="max-age=31536000; includeSubDomains; preload"
  50. # Default keeps the conservative no-preload value — preload-listing
  51. # is a one-way commitment (browser preload removals take months) so
  52. # we don't enable it by default (SEC_REVIEW F60).
  53. @prod expression `{env.APP_ENV} == "production"`
  54. header @prod Strict-Transport-Security "{$HSTS_HEADER:max-age=31536000; includeSubDomains}"
  55. php_server
  56. }