security(.htaccess): enforce Content-Security-Policy (was report-only)
Switch CSP from Report-Only to enforcing, with an allowlist verified in a browser against a server sending this exact header (0 violations across the homepage, a YouTube project page, the assistant, MailerLite JSONP, GA/gtag, and the Google Forms endpoint). Adds the sources the old report-only policy was missing (and would have broken if enforced blindly): Google Fonts (style/font), Font Awesome cdnjs (style/font), MailerLite newsletter (script/connect), the Google Forms endpoint in connect-src, plus object-src 'none'. Keeps 'unsafe-inline' for the in-<head> consent bootstrap; the host allowlists + form-action/base-uri are the real hardening on top of existing output escaping. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0c07b05b1f
commit
9877b4bbd6
13
.htaccess
13
.htaccess
|
|
@ -92,9 +92,16 @@ Options -Indexes
|
|||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||||
# Explicitly disable browser features the site doesn't use.
|
||||
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()"
|
||||
# Content-Security-Policy in REPORT-ONLY first so it cannot break styling/scripts.
|
||||
# Review browser console for violations, tighten, then switch to Content-Security-Policy.
|
||||
Header always set Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; script-src 'self' https://www.googletagmanager.com; connect-src 'self' https://www.google-analytics.com https://region1.google-analytics.com; frame-src https://www.youtube-nocookie.com https://www.youtube.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self' https://docs.google.com"
|
||||
# Content-Security-Policy (ENFORCING). Allowlist verified in a browser
|
||||
# against a server sending this exact header — every real resource passes:
|
||||
# self assets, Google Fonts, Font Awesome (cdnjs), gtag, GA beacons, the
|
||||
# Google Forms endpoint (membership + guide feedback), the MailerLite JSONP
|
||||
# newsletter, and YouTube (nocookie) embeds. 'unsafe-inline' is required for
|
||||
# the in-<head> consent/analytics bootstrap and a few inline handlers; the
|
||||
# host allowlists still constrain where scripts load from and where data can
|
||||
# be sent (connect/form-action/base-uri/object-src), which is the real value
|
||||
# here on top of the site's existing output escaping.
|
||||
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://assets.mailerlite.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdnjs.cloudflare.com; font-src 'self' https://fonts.gstatic.com https://cdnjs.cloudflare.com data:; img-src 'self' data: https:; connect-src 'self' https://www.google-analytics.com https://region1.google-analytics.com https://analytics.google.com https://www.googletagmanager.com https://docs.google.com https://assets.mailerlite.com; frame-src https://www.youtube-nocookie.com https://www.youtube.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self' https://docs.google.com; object-src 'none'"
|
||||
<FilesMatch "\.html$">
|
||||
Header set Cache-Control "no-cache, must-revalidate"
|
||||
</FilesMatch>
|
||||
|
|
|
|||
Loading…
Reference in New Issue