SEC-005 critical Security Headers
HTTPS-only headers (HSTS)
Strict-Transport-Security header must be present to ensure browsers always use HTTPS, preventing downgrade attacks.
Question to ask
"Can your app still be reached over plain HTTP?"
Pass criteria
- ✓ HSTS header present on production
- ✓ max-age >= 31536000 (1 year)
- ✓ includeSubDomains present if applicable
Fail criteria
- ✗ No HSTS header on production
- ✗ max-age too short (< 6 months)
- ✗ HTTP accessible without redirect
Verification guide
Severity: Critical
Check automatically:
- Check for HSTS header:
# Check Strict-Transport-Security header
curl -sI https://example.com | grep -i "strict-transport-security"
# Expected format:
# Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
- Check Cloudflare HSTS settings:
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/ZONE_ID/settings/security_header" \
-H "Authorization: Bearer $CF_API_TOKEN" | jq '.result'
- Check HSTS preload status:
# Check if domain is on HSTS preload list
curl -s "https://hstspreload.org/api/v2/status?domain=example.com" | jq '.status'
# "preloaded" = best, "pending" = submitted, "unknown" = not submitted
# Manual check: https://hstspreload.org/?domain=example.com
- Check all environments:
# Production (required)
curl -sI https://example.com | grep -i "strict-transport-security"
# Staging (recommended)
curl -sI https://staging.example.com | grep -i "strict-transport-security"
HSTS header components:
max-age=31536000- 1 year minimum for preload eligibilityincludeSubDomains- applies to all subdomainspreload- allows browser preload list inclusion
Pass criteria:
- HSTS header present on production
max-age>= 31536000 (1 year) for productionincludeSubDomainspresent (if subdomains should be HTTPS-only)- Preload submitted (recommended, not required)
Fail criteria:
- No HSTS header on production
max-agetoo short (< 6 months / 15768000)- Missing
includeSubDomainswhen subdomains exist - HTTP still accessible without redirect
Evidence to capture:
- HSTS header value
- max-age duration
- Preload status
- Cloudflare HSTS configuration