to load // its live-reload client and talks over a websocket. Allow exactly that // in dev only; production stays strict. Inline *styles* are blocked in // dev too, so a stray style="" still shows up while developing. $isDev = PHP_SAPI === 'cli-server'; $csp = [ "default-src 'self'", "script-src 'self'" . ($isDev ? " 'unsafe-inline'" : ''), "style-src 'self' https://fonts.googleapis.com", "font-src https://fonts.gstatic.com", "img-src 'self'", "connect-src 'self'" . ($isDev ? ' ws: wss:' : ''), "object-src 'none'", "base-uri 'self'", "form-action 'self'", "frame-ancestors 'none'", ]; header('Content-Security-Policy: ' . implode('; ', $csp)); header('X-Content-Type-Options: nosniff'); header('X-Frame-Options: DENY'); header('Referrer-Policy: strict-origin-when-cross-origin'); header('Permissions-Policy: camera=(), microphone=(), geolocation=()'); // HSTS only over HTTPS (browsers ignore it on HTTP anyway). No // includeSubDomains: this site is one subdomain of daviddyer.me and // shouldn't dictate policy for the others. if (request_is_https()) { header('Strict-Transport-Security: max-age=31536000'); } }