From 6293a62e47a666aabf496b34d94b3bb687872425 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Thu, 2 Jul 2026 14:41:08 -0400 Subject: [PATCH] feat(nginx): add HSTS + Permissions-Policy to chat.lotusguild.org (P6-4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds Strict-Transport-Security (2y, includeSubDomains, preload) and a Permissions-Policy that allows only the features the app uses (camera/mic/ display-capture for calls, geolocation for location share, autoplay/fullscreen/ encrypted-media) and denies the rest. Complements the existing X-Frame/CSP/ Referrer headers. Apply: reload nginx on the LXC. TLS terminates upstream (listen 80), so verify the header reaches the browser (front proxy must pass it through) — else set HSTS at the TLS terminator. Verify a call + location share still work. Co-Authored-By: Claude Opus 4.8 --- cinny/nginx.conf | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cinny/nginx.conf b/cinny/nginx.conf index 77df5a4..56942fb 100644 --- a/cinny/nginx.conf +++ b/cinny/nginx.conf @@ -23,6 +23,16 @@ server { add_header X-Content-Type-Options nosniff always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy strict-origin-when-cross-origin always; + # HSTS: TLS terminates upstream (this server is listen 80), so this reaches + # the browser only if the front proxy passes upstream response headers + # through; otherwise set it at the TLS terminator. includeSubDomains covers + # all *.lotusguild.org (all HTTPS); `preload` is inert until submitted to + # hstspreload.org. + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; + # Permissions-Policy: allow only what the app uses (self) — calls + # (camera/microphone/display-capture), location share (geolocation), sounds + # (autoplay), Element Call (fullscreen/encrypted-media) — and deny the rest. + add_header Permissions-Policy "accelerometer=(), autoplay=(self), camera=(self), display-capture=(self), encrypted-media=(self), fullscreen=(self), geolocation=(self), gyroscope=(), magnetometer=(), microphone=(self), midi=(), payment=(), usb=()" always; # Block all source map files and dotfiles from public access location ~* \.(js|css)\.map$ {