HTTP Strict Transport Security (HSTS) is the most important security header for HTTPS sites. It instructs browsers to only connect to your site via HTTPS, preventing protocol downgrade attacks, SSL stripping, and accidental HTTP connections.
Without HSTS, users who type your domain without "https://" or click HTTP links might connect insecurely before redirecting. This is a window attackers can exploit.
HSTS closes this gap by making browsers enforce HTTPS automatically.
What is HSTS?
HSTS is an HTTP response header that declares your site should only be accessed via HTTPS. When browsers receive this header, they remember the policy and automatically convert any HTTP requests to HTTPS before sending them.
The Header Format
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
| Directive | Purpose |
|---|---|
| max-age | How long (in seconds) browsers remember the HTTPS-only policy |
| includeSubDomains | Extends the policy to all subdomains |
| preload | Enables inclusion in browser preload lists |
How HSTS Enforcement Works
Once a browser receives HSTS, it will refuse to connect via HTTP:
- Even if users explicitly type "http://"
- Even if links point to HTTP URLs
- Even if attackers attempt to downgrade connections
The browser enforces HTTPS regardless of how the request originated.
Why HSTS Matters
The SSL Stripping Attack
Without HSTS, consider a user at a coffee shop connecting to "example.com":
- Browser connects via HTTP
- Attacker on the network intercepts this connection
- Attacker presents a fake HTTP version of your site
- Your server's HTTPS redirect never reaches the user
Protection Against Accidental Insecure Access
HSTS protects against unintentional HTTP access:
- Old bookmarks pointing to HTTP
- Links in emails without HTTPS
- Manual URL entry without "https://"
- Mixed content from your own site pointing to HTTP pages
All get automatically upgraded to HTTPS.
Security Maturity Signal
Sites implementing HSTS demonstrate security maturity. This is often required for:
- Compliance certifications
- Enterprise partnerships
- Security audits
How to Implement HSTS Safely
HSTS implementation should be staged to avoid locking users out if problems exist with your HTTPS setup.
Stage 1: Ensure HTTPS Works Everywhere
Before enabling HSTS:
- Test your entire site via HTTPS
- Fix all mixed content issues
- Verify all functionality works over HTTPS
- Confirm you can maintain valid certificates continuously
Stage 2: Deploy with Short max-age
Start with 5 minutes (300 seconds):
Strict-Transport-Security: max-age=300
Monitor for any issues with HTTPS access. If problems occur, browsers will revert to allowing HTTP after 5 minutes.
Stage 3: Progressively Increase max-age
Increase gradually, monitoring at each stage:
| Stage | max-age | Duration |
|---|---|---|
| Initial | 300 | 5 minutes |
| Short | 86400 | 1 day |
| Medium | 604800 | 1 week |
| Extended | 2592000 | 1 month |
| Production | 31536000 | 1 year |
Stage 4: Add includeSubDomains
Only after verifying all subdomains work with HTTPS:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Stage 5 (Optional): Submit for Preloading
Once running production HSTS with includeSubDomains for several months without issues, consider preloading.
Preloading adds your domain to browser preload lists, providing protection from the very first visit.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Submit at hstspreload.org.
Server Configuration Examples
Nginx
server {
listen 443 ssl http2;
server_name example.com;
# HSTS with 1-year max-age
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Redirect HTTP to HTTPS
# (In a separate server block for port 80)
}
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
Apache
<VirtualHost *:443>
ServerName example.com
# Enable HSTS
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</VirtualHost>
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>
Caddy
example.com {
header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
}
HSTS Best Practices and Common Mistakes
Never Enable HSTS If You Might Need HTTP
Verify Subdomains Before includeSubDomains
A subdomain without valid HTTPS becomes completely inaccessible once this directive is active. Consider:
- Development subdomains
- Staging environments
- Legacy systems
- Internal tools
- Third-party hosted services on your subdomains
Don't Rush to Preloading
Preload list removal is slow (can take months) and requires clearing from users' browsers. Only preload after extensive production stability validation.
Configure at Server Level
HSTS should apply to all responses, including error pages. Server configuration ensures consistent header delivery. Don't rely on application-level header setting.
Implement HSTS Monitoring
Configuration changes, deployments, or CDN updates could accidentally remove the header. Monitor that HSTS headers are being served correctly.
# Check HSTS header
curl -sI https://example.com | grep -i strict-transport-security
Monitor Certificate Expiration Aggressively
With HSTS active, expired certificates don't just show warnings. Browsers refuse connection entirely. The consequences of certificate expiration are more severe with HSTS.
Testing HSTS Implementation
Command Line Verification
# Check HSTS header is present
curl -sI https://example.com | grep -i strict-transport-security
# Verify header value
curl -sI https://example.com 2>&1 | grep -i "strict-transport-security"
Browser Developer Tools
- Open Developer Tools (F12)
- Go to Network tab
- Load your site
- Click on the main request
- Check Response Headers for Strict-Transport-Security
Online Tools
- securityheaders.com
- SSL Labs Server Test
- hstspreload.org for preload eligibility
Conclusion
HSTS is essential for secure HTTPS deployment, preventing downgrade attacks and ensuring users always connect securely.
Implementation Checklist
- Verify all content works over HTTPS
- Start with short max-age (5 minutes)
- Verify stability and increase gradually
- Add includeSubDomains only after auditing all subdomains
- Preload only after extended production stability
- Monitor continuously for header presence
- Maintain impeccable certificate management
With HSTS properly deployed, your users gain strong protection against some of the most practical attacks against HTTPS security.