security(.htaccess): force HTTPS + add HSTS

- Redirect all plain-http requests to https (double condition guards against
  a redirect loop behind a TLS-terminating proxy).
- Add Strict-Transport-Security (6-month max-age, no preload/includeSubDomains
  so it stays easy to adjust) so browsers refuse http after the first visit.

Closes the "HTTPS everywhere" gap: previously http:// served in the clear.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
popovskik 2026-08-04 10:37:37 +02:00
parent f30c9c6155
commit 0c07b05b1f
1 changed files with 12 additions and 0 deletions

View File

@ -1,6 +1,14 @@
RewriteEngine on RewriteEngine on
# ----- Force HTTPS everywhere -----
# Redirect any plain-http request to https. The two conditions together avoid
# a redirect loop when TLS is terminated by an upstream proxy (which forwards
# X-Forwarded-Proto: https while %{HTTPS} may read as off).
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# ----- Language root redirect ----- # ----- Language root redirect -----
# Send the bare root to the default-language homepage, on WHATEVER host is # Send the bare root to the default-language homepage, on WHATEVER host is
# serving the site (relative — no cross-domain redirect). Do NOT force # serving the site (relative — no cross-domain redirect). Do NOT force
@ -74,6 +82,10 @@ Options -Indexes
</IfModule> </IfModule>
<IfModule mod_headers.c> <IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff" Header set X-Content-Type-Options "nosniff"
# HSTS: after the first HTTPS visit, browsers refuse plain HTTP for this
# host. Conservative 6-month max-age, no preload/includeSubDomains so it
# stays easy to adjust. (Ignored by browsers over plain HTTP — harmless.)
Header always set Strict-Transport-Security "max-age=15768000"
# Clickjacking protection — the site should never be framed by other origins. # Clickjacking protection — the site should never be framed by other origins.
Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Frame-Options "SAMEORIGIN"
# Don't leak full page URLs to third parties (analytics, external links). # Don't leak full page URLs to third parties (analytics, external links).