Missing Strict-Transport-Security
What it is
Your site doesn’t send the Strict-Transport-Security (HSTS) header. This header tells the browser “on this site, never use HTTP again—always go straight to HTTPS”.
Why it’s a problem
Even if you have working HTTPS and an HTTP redirect, the very first visit has a weak spot. A user types example.com — the browser starts with an HTTP attempt. If an attacker is between you and the server at that moment (public Wi-Fi, a compromised router), they can:
- Intercept the cookies the browser sends with the HTTP request.
- Perform an SSL strip — keep the user on HTTP while talking to the server over HTTPS themselves.
With HSTS, the browser knows in advance that example.com must not be accessed over HTTP, and the attack fails.
How to fix it
Step 1 — make sure HTTPS is stable
The browser “learns” HSTS for an extended period. If you then break HTTPS (an expired cert, SSL accidentally turned off), your site becomes unreachable for returning visitors — the browser refuses even to fall back to HTTP.
Before turning on HSTS, verify:
- Certificate auto-renewal works (Let’s Encrypt, certbot, alerting).
- Every subdomain you want to cover has a valid cert.
Step 2 — set a short value for testing
Strict-Transport-Security: max-age=3005 minutes. If something breaks, it clears within 5 minutes. Monitor uptime and run a few tests.
Step 3 — deploy the production value
Strict-Transport-Security: max-age=15552000; includeSubDomainsmax-age=15552000= 6 months.includeSubDomains= applies to all subdomains too. Caution: if you have a subdomain without HTTPS (a legacy admin, an intranet), this directive will break it.
Step 4 (optional) — preload
If you want to be in the browsers’ built-in list (Chrome, Firefox, Safari) and have HSTS apply even on the very first visit from a fresh browser:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preloadThen register the domain at hstspreload.org.This step is hard to reverse — removal from the list takes weeks to months.
Specific configurations
nginx:
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;Apache:
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"Cloudflare: SSL/TLS → Edge Certificates → HTTP Strict Transport Security — UI checkbox.