HSTS.
Forces HTTPS-only connections — prevents protocol downgrade attacks
What does this check test?
HTTP Strict Transport Security (HSTS) is a response header (`Strict-Transport-Security`) that instructs browsers to only communicate with your site over HTTPS for a specified duration. Once a browser sees this header, it will automatically convert any HTTP request to HTTPS before it ever leaves the client. The header accepts a `max-age` directive (in seconds), an optional `includeSubDomains` directive, and an optional `preload` directive for inclusion in browser preload lists.
Why does it matter?
Without HSTS, users who type your domain without `https://` or follow an HTTP link are vulnerable to SSL stripping attacks, where an attacker on the same network intercepts the initial plaintext request and proxies the connection. HSTS eliminates this window of vulnerability after the first visit. For maximum protection, sites should be submitted to the HSTS preload list, which hardcodes HTTPS enforcement into browsers so even the very first visit is protected.
Who is affected?
HSTS is critical for any site that handles user authentication, personal data, or financial transactions. It is equally important for marketing sites that set cookies or embed third-party scripts, since session cookies sent over HTTP can be intercepted. Every production website should set HSTS — there is no legitimate reason to allow HTTP connections to a site that supports HTTPS.
Where does this apply?
The `Strict-Transport-Security` header must be set on HTTPS responses from your server or CDN. It is typically configured at the web server level (Nginx, Apache, Caddy), in your CDN dashboard (Cloudflare, AWS CloudFront), or via middleware in your application framework. The header is ignored by browsers when served over HTTP, so your site must already support HTTPS for it to take effect.
How to fix it
Nginx
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; Node.js / Express
const helmet = require('helmet');
app.use(helmet.hsts({ maxAge: 63072000, includeSubDomains: true, preload: true })); Django
SECURE_HSTS_SECONDS = 63072000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True Flask
from flask_talisman import Talisman
Talisman(app, strict_transport_security=True,
strict_transport_security_max_age=63072000,
strict_transport_security_include_subdomains=True,
strict_transport_security_preload=True) Next.js
module.exports = {
async headers() {
return [{
source: '/(.*)',
headers: [{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload'
}]
}];
}
}; Spring Boot
server.servlet.session.cookie.secure=true
// In a WebSecurityConfigurerAdapter or SecurityFilterChain:
http.headers().httpStrictTransportSecurity()
.includeSubDomains(true)
.maxAgeInSeconds(63072000)
.preload(true); References
- MDN: Strict-Transport-Security
- OWASP: HTTP Strict Transport Security Cheat Sheet
- HSTS Preload List Submission
AppVet checks HSTS automatically
Run a free security scan and get a full report with actionable fixes, including a Fix with AI prompt you can paste into any coding tool.
Run Audit