security: add HSTS header to nginx config - #674
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
birme
left a comment
There was a problem hiding this comment.
Code Review
Verdict: LGTM
Summary: A single, correct one-line HSTS header addition. The header value follows best practice and nginx placement is valid. One important operational caveat about TLS termination is worth confirming, but it is not a merge blocker.
Blocking
None.
Warnings
nginx/nginx.conf:2— The server block is plain HTTP (listen 8080;with nossldirective). Per the HSTS spec (RFC 6797, §7.2), conforming browsers MUST ignore theStrict-Transport-Securityheader when it is received over a non-secure (HTTP) transport. This container therefore only delivers a working HSTS policy if TLS is terminated upstream (ingress/reverse proxy) AND that proxy forwards this header unaltered to the client over HTTPS. Please confirm the deployment topology: if the upstream proxy strips or overrides response headers, this header is a no-op. If TLS terminates upstream, consider whether HSTS is better owned at the proxy layer where the HTTPS connection actually exists. The header itself is harmless here, so this is a Warning, not a blocker.
Suggestions
nginx/nginx.conf:4— Header value is correct:max-age=31536000(1 year) meets the commonly required minimum,includeSubDomainsis present, and thealwaysflag correctly ensures the header is emitted on error responses (4xx/5xx) as well as 2xx. No change needed.nginx/nginx.conf:4—preloadis intentionally (and reasonably) omitted. CombiningincludeSubDomainswithpreloadhas a large, hard-to-reverse blast radius across every subdomain, so leaving it off is the safer default. If a future task targets the HSTS preload list, gate it behind explicit confirmation that every subdomain can serve HTTPS.- Placement note: defining
add_headerin theserverblock is valid — it is inherited by the nestedlocation /because that location defines noadd_headerof its own (nginxadd_headerinheritance is all-or-nothing per level). If anylocationlater adds its ownadd_header, this HSTS directive must be repeated there or it will be dropped for that location. - Test plan: the two checklist items (
nginx -tparse + verify the header over HTTPS end-to-end through the real proxy chain) are the right validation. Please ensure the HTTPS check is run against the deployed edge, not just the container, to catch the upstream-forwarding concern above.
Domain Note
Not applicable — this change does not touch audio routing, PTT, dominant speaker, data channel parsing, or WHIP/WHEP session lifecycle.
birme
left a comment
There was a problem hiding this comment.
Code Review
Verdict: LGTM
Summary: A single-line, well-scoped security hardening change that adds the Strict-Transport-Security header to the nginx server block exactly as specified in issue #642. The directive is correct, uses the always flag so the header is emitted on error responses too, and nginx header inheritance works as intended here.
Blocking
None.
Warnings
None.
The change intentionally omits X-Content-Type-Options and Referrer-Policy, which the PR description correctly defers to a separate issue (#664/#624). Scoping HSTS-only is a reasonable, deliberate choice, so this is not flagged.
Suggestions
nginx/nginx.conf:4— Header inheritance note (informational, no action required):add_headerat theserverlevel is inherited into alocationblock only when that block defines noadd_headerof its own. The currentlocation /block has none, so HSTS is correctly emitted for all responses. If a future PR adds anyadd_headerinside alocationblock, the server-level HSTS directive will need to be repeated there (or consolidated) to avoid silently dropping it. Worth a brief comment in the config if more headers land later.nginx/nginx.conf:4— Thealwaysflag is correctly present, ensuring the header is sent on the=404/ error path fromtry_files. Good.- Optional hardening for a follow-up: consider whether
preloadis desired onmax-age=31536000; includeSubDomains. Addingpreloadimplies a commitment to HSTS preload-list submission and affects all subdomains permanently, so keeping it out of this PR is the safer default. No change requested.
Test plan note: The PR checklist (nginx -t parse check, and verifying the response header over HTTPS) is the right validation. Since this is a config-only change with no application code, no unit/integration test is expected. Confirming the header appears on a real HTTPS response before merge is sufficient.
No Blocking issues. Verdict: LGTM.
Summary
Strict-Transport-Security: max-age=31536000; includeSubDomainsheader to the nginx server block so browsers enforce HTTPS on subsequent visits (mitigates SSL-strip / downgrade MITM).Test plan
nginx -t) in the built imageStrict-Transport-Securityheader over HTTPSCloses #642
🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com