HSTS (HSTS)

Security

HTTP Strict Transport Security. A response header telling browsers to only connect via HTTPS for a specified duration. Prevents protocol downgrade attacks and insecure redirects. Once set, browsers refuse plain HTTP connections to that domain.

Updated Mar 9, 2026

Full Explanation

HSTS solves the problem of the first HTTP request. Even if your CDN redirects HTTP to HTTPS, that initial redirect is unencrypted and vulnerable to man-in-the-middle attacks (SSL stripping). HSTS tells the browser: "For the next N seconds, don't even try HTTP—go straight to HTTPS."

The header looks like Strict-Transport-Security: max-age=31536000; includeSubDomains; preload. The includeSubDomains directive applies HSTS to all subdomains, and preload lets you submit your domain to browser preload lists so HSTS is enforced even on the very first visit.

For CDN deployments, HSTS needs to be set at the CDN edge, not just the origin. If the CDN serves the response, it needs to include the HSTS header. Be careful with includeSubDomains—make sure every subdomain actually supports HTTPS before enabling it, or you'll break things.

Examples

Setting HSTS in Nginx:

server {
    listen 443 ssl;
    server_name cdn.example.com;

    # HSTS: 1 year, include subdomains, preload-ready
    add_header Strict-Transport-Security
        "max-age=31536000; includeSubDomains; preload"
        always;
}

# Redirect HTTP to HTTPS (needed before HSTS kicks in)
server {
    listen 80;
    server_name cdn.example.com;
    return 301 https://$host$request_uri;
}

Checking HSTS status:

# Verify HSTS header
curl -sI https://cdn.example.com/ | grep -i strict
# strict-transport-security: max-age=31536000; includeSubDomains; preload

# Check preload status
# Visit: https://hstspreload.org/?domain=example.com

Video Explanation

Frequently Asked Questions

HTTP Strict Transport Security. A response header telling browsers to only connect via HTTPS for a specified duration. Prevents protocol downgrade attacks and insecure redirects. Once set, browsers refuse plain HTTP connections to that domain.

Setting HSTS in Nginx:

server {
    listen 443 ssl;
    server_name cdn.example.com;

    # HSTS: 1 year, include subdomains, preload-ready
    add_header Strict-Transport-Security
        "max-age=31536000; includeSubDomains; preload"
        always;
}

# Redirect HTTP to HTTPS (needed before HSTS kicks in)
server {
    listen 80;
    server_name cdn.example.com;
    return 301 https://$host$request_uri;
}

Checking HSTS status:

# Verify HSTS header
curl -sI https://cdn.example.com/ | grep -i strict
# strict-transport-security: max-age=31536000; includeSubDomains; preload

# Check preload status
# Visit: https://hstspreload.org/?domain=example.com