Performance & Security

HSTS: Forcing Browsers to Use HTTPS on Your Site

What HSTS is, how the Strict-Transport-Security header forces HTTPS, when to enable preload and what to fix before you turn it on.

Quick answer: HSTS (HTTP Strict Transport Security) is a response header that tells browsers to speak HTTPS only to your host for a set time. After the first successful HTTPS visit, the browser refuses plain HTTP, which blocks SSL stripping and accidental insecure requests. Enable HSTS only after your site works fully on HTTPS, including redirects, cookies and mixed content cleanup. Start with a short max-age, then lengthen it, and treat preload as a later step.

Why HTTPS alone is not the whole story

Migrating to TLS is step one. Users (and some tools) still type http:// or follow old links. A redirect to HTTPS helps, but the first request can still travel unprotected. HSTS removes that first-request window on subsequent visits by teaching the browser a hard rule: this host is HTTPS-only.

If you are still planning the move, read HTTPS migration SEO before you think about HSTS. Certificate issues also matter; Let’s Encrypt covers obtaining and renewing certificates commonly used in 2020 stacks.

What the header looks like

A typical header:

Strict-Transport-Security: max-age=31536000; includeSubDomains

Pieces:

  • max-age: seconds the browser should remember the rule
  • includeSubDomains: optional; applies the policy to all subdomains
  • preload: optional signal that you intend to be on the browser preload list

Browsers only honour HSTS when it arrives over a valid HTTPS response. You cannot set HSTS on pure HTTP and expect it to stick.

Benefits in practice

  • Reduces SSL stripping success on repeat visits
  • Cuts accidental mixed cookie behaviour when users retype URLs
  • Signals operational seriousness about TLS
  • Pairs well with secure cookie flags and modern TLS configuration

HSTS does not fix weak passwords, plugin holes or open redirects. It is transport policy, not a full WordPress security programme.

Prerequisites before enabling

Checklist:

  1. HTTPS works on the apex and www (pick a canonical and redirect cleanly)
  2. No mixed content (HTTP images, scripts or iframes on HTTPS pages)
  3. APIs and webhooks called on HTTPS endpoints
  4. CDN and load balancers pass or set the header deliberately (avoid duplicates that conflict)
  5. Staging hosts considered so you do not preload a junk hostname by mistake

Mixed content shows as browser warnings and broken features. Clear it first.

Rollout strategy (safe order)

Week 1: max-age=300 (five minutes) on production HTTPS responses. Browse the site. Watch support for odd login or asset issues.

Week 2: raise to a day or a week if clean.

Later: raise to months or a year when confident.

Only after long stable max-age and full subdomain HTTPS should you consider includeSubDomains and preload.

Sudden max-age of a year plus includeSubDomains on day one is how teams lock themselves out of an HTTP-only internal tool on a subdomain they forgot.

includeSubDomains and preload: respect the blast radius

includeSubDomains means app, old, dev and every other subdomain must speak HTTPS correctly. Forgotten blog mirrors and legacy landers break hard.

Preload submits your domain to a list shipped in major browsers so even first visits use HTTPS. Removal is slow. Do not preload until:

  • You can keep HTTPS forever on all included hosts
  • Redirects from HTTP to HTTPS are correct
  • You understand the [preload] process requirements current at the time you submit

If unsure, skip preload. HSTS without preload still helps repeat visitors.

Where to set the header

Common places:

  • Web server config (Nginx add_header, Apache Header always set)
  • Application middleware
  • CDN / edge rules

Set it in one layer to avoid conflicting values. Confirm with browser dev tools or curl -I on HTTPS.

During TLS upgrades and old protocol shutdowns, verify HSTS still ships after config reloads.

SEO and analytics notes

HSTS does not replace 301 redirects from HTTP to HTTPS. Keep redirects for the first visit and for clients that do not store HSTS. Search engines rely on consistent canonical HTTPS URLs. HSTS is complementary.

Watch for redirect chains (HTTP to HTTPS to www leftover). Collapse them.

Failure modes

  • Enabling HSTS while some assets remain on HTTP
  • Preloading before staging subdomains are ready
  • Setting HSTS on a shared temporary hostname
  • Certificate expiry while long max-age is active (browsers will not quietly fall back to HTTP)
  • Mobile apps or old integrations still hard-coded to HTTP endpoints

Certificate monitoring becomes more important after HSTS because users cannot bypass as easily.

Testing

  1. curl -I https://example.com and confirm the header
  2. Visit once in a fresh browser profile
  3. Try http:// and confirm upgrade behaviour after HSTS is stored
  4. Check subdomains individually if includeSubDomains is on
  5. Review console for mixed content

Document how to clear HSTS state in browsers for your team (it varies by browser) so QA is not stuck during the short max-age phase.

Alongside HSTS:

  • Redirect HTTP to HTTPS
  • Secure and HttpOnly cookies where appropriate
  • Turn off obsolete protocols when clients allow (POODLE / SSLv3 history is a reminder why old crypto dies)
  • Keep renewals automated

Coordination with CDNs and multiple environments

Set HSTS on production hostnames only. Preview sites and QA hosts should use separate domains so a long max-age on prod never traps testers on a broken HTTPS lab URL.

When a CDN sits in front, confirm whether the CDN adds HSTS and whether origin also adds it. One consistent policy is enough.

Incident response note

Add HSTS to your TLS incident runbook: if certificates fail, browsers will not allow an HTTP fallback. Prioritise renewal monitoring and redundant issuance paths before you crank max-age to a year.

Header examples for common servers

Nginx often uses add_header Strict-Transport-Security "max-age=31536000" always; inside the SSL server block. Apache uses Header always set Strict-Transport-Security "max-age=31536000". The always style matters so error responses also carry the policy when you intend that.

Verify with multiple paths: home, a 404, and an API route. Some app layers override server headers accidentally.

Team education

Tell support that “just use HTTP” is no longer a workaround after HSTS. Give them a certificate escalation path instead. A long max-age without operational readiness creates louder outages.

Relationship to CSP and other headers

HSTS sits beside Content-Security-Policy, X-Content-Type-Options and others. Add headers one at a time with monitoring. Shipping five new policies on the same afternoon makes breakages hard to attribute.

FAQ

Is HSTS required for PCI or compliance?

Requirements vary. Many programmes expect strong TLS and redirects; HSTS is often recommended. Check your assessor’s current guidance.

Will HSTS boost rankings by itself?

HTTPS is a light ranking signal historically discussed by Google; HSTS is mainly a security mechanism. Do it for users and integrity.

Can I set HSTS only on the checkout subdomain?

Yes. Start where risk is highest if the rest of the estate is not ready. Be careful with cookies scoped across subdomains.

What if we need to kill HTTPS temporarily?

With long max-age or preload, you largely cannot. That is the point. Plan certificate and hosting continuity instead.

Turn on HSTS after HTTPS is boring

HSTS forces browsers to stick with HTTPS once they have seen a valid header. Make HTTPS uneventful first, roll max-age up gradually and treat preload as optional advanced commitment. If you want help hardening site transport and security headers as part of a wider build, see Turn visitors into customers.

About the author

Imran M

Leave a Reply

Your email address will not be published. Required fields are marked *

Ready to improve your website?

Let's build a faster, higher performing website.