HomeFix guides → Strict-Transport-Security

security

How to fix: Strict-Transport-Security

OWASP A02 NIS2 Art. 21(2)(a) RFC 6797

Why this matters

Without HSTS, a man-in-the-middle on a visitor's first connection can downgrade the request to plain HTTP and harvest credentials before the redirect runs. HSTS tells browsers to refuse plain HTTP for your domain entirely.

Background

Strict-Transport-Security tells browsers to refuse plain-HTTP connections to your origin for a set period. Without it, a network-on-path attacker can downgrade the first request (typed-URL, HTTP link from another site) and intercept the session. After one successful HSTS-bearing visit the protection kicks in; first contact remains the weak link unless you also submit the domain to the HSTS Preload list.

References

RFC 6797 · OWASP A02 (Cryptographic Failures)

How to fix

Code snippet for each stack we cover. Pick the one matching your server / framework.

nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
apache
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
cloudflare
SSL/TLS → Edge Certificates → Enable HSTS. Set Max-Age = 12 months, includeSubDomains ON, Preload ON.
wordpress
Use the Headers Security Advanced plugin OR add the header in your reverse-proxy / Cloudflare. Don't set it from PHP — it won't apply on cached responses.
flask
Flask-Talisman(app, force_https=True, strict_transport_security=True, strict_transport_security_max_age=31536000)
express
app.use(helmet.strictTransportSecurity({ maxAge: 31536000, includeSubDomains: true, preload: true }))
rails
config.force_ssl = true (sets HSTS with includeSubDomains by default).

Verify it's working

curl -sI https://your-site/ | grep -i 'strict-transport-security:'

Want to know if your site has this issue?

Run a free 53-check audit — security, GDPR, NIS2, and technical SEO.

Audit my site →