What is HSTS (HTTP Strict Transport Security)? How it works and why it matters
HTTP Strict Transport Security (HSTS) is a web security policy that forces browsers to only use HTTPS. Learn how the Strict-Transport-Security header works, what it protects against, and how HSTS preload lists eliminate the SSL-stripping window.
On this page
- The problem HSTS solves
- How the Strict-Transport-Security header works
- The three HSTS directives
- What HSTS protects against
- The trust-on-first-use limitation
- The HSTS preload list
- Mixed content and HSTS
- Deploying HSTS: practical steps
- HSTS and CDN edge deployments
- FAQ
- What does HSTS protect against?
- Does HSTS make a site completely secure?
- Why is a preload list needed if max-age is set?
- What is the difference between HSTS and HTTPS redirect?
- How does HSTS interact with subdomains?
- Verdict
Every time you visit http://example.com instead of https://example.com, your browser makes the first request over an unencrypted connection. Even if the server immediately redirects to HTTPS, an attacker sitting between you and the server can intercept that initial unencrypted request — and all the data it carries. This is called an SSL stripping attack, and it was the problem HTTP Strict Transport Security was designed to solve.
HSTS (HTTP Strict Transport Security) is a web security policy mechanism defined in RFC 6797 that tells browsers to only ever connect to a domain over HTTPS. Once a browser receives the HSTS header from a server over a secure connection, it automatically upgrades any future request — including those typed as http:// — to HTTPS, before sending a single byte over the wire.
The problem HSTS solves
The web uses HTTP over TLS (HTTPS) to protect communication between browsers and servers. HTTPS encrypts data in transit, authenticates the server, and prevents tampering. But HTTP — the unencrypted predecessor — still works on most servers, and users still type http:// into their address bars.
This creates an attack window. A man-in-the-middle (MITM) attacker on a shared Wi-Fi network can intercept the first unencrypted HTTP request a user makes to a website. The attacker forwards nothing, or forwards a tampered version. The user sees the page, but the attacker has read or modified everything. This class of attack — where the attacker downgrades a secure connection to an insecure one — is called a protocol downgrade attack or SSL stripping.
The Wikipedia article on HSTS describes the mechanism: when a server sends the Strict-Transport-Security header over HTTPS, it instructs user agents to "automatically interact with it using only HTTPS connections." Browsers that obey this policy refuse to make plain HTTP requests to that domain.
How the Strict-Transport-Security header works
The MDN TLS documentation explains that browsers only respect the HSTS header when it arrives over a secure (HTTPS) connection. An HTTP response carrying this header is simply ignored — a server cannot force browsers to use HTTPS over an insecure channel.
A minimal HSTS header looks like this:
Strict-Transport-Security: max-age=31536000
This tells the browser to only use HTTPS when connecting to this domain for the next 315,360 seconds — one year. After the browser has received this header once, it will refuse HTTP requests to the domain until the max-age period expires.
The three HSTS directives
The HSTS specification (RFC 6797) defines three directives:
| Directive | What it does | Example |
|---|---|---|
max-age=<seconds> |
How long the browser should enforce HTTPS-only (in seconds) | max-age=31536000 (1 year) |
includeSubDomains |
Applies the policy to all subdomains too | max-age=31536000; includeSubDomains |
preload |
Requests inclusion in the browser preload list | max-age=31536000; includeSubDomains; preload |
max-age is the only mandatory directive. A value of 0 disables HSTS for that domain. Security-sensitive sites typically use max-age=63072000 (two years) or higher with includeSubDomains and preload.
What HSTS protects against
The Wikipedia TLS article describes TLS as providing three properties: confidentiality (encryption, so eavesdroppers cannot read data), integrity (tampering is detected), and authenticity (client and server prove their identities). HSTS extends these guarantees by preventing the protocol downgrade that would break all three.
Specifically, HSTS prevents:
- SSL stripping attacks — where an attacker intercepts the first HTTP request and leaves the user on an unencrypted connection.
- Mixed content warnings — browsers automatically upgrade subresource requests from
http://tohttps://on HSTS-enabled sites. - Cookie hijacking — session cookies sent over HTTP can be stolen; HSTS ensures all traffic (including cookie transmission) goes over HTTPS.
As the Wikipedia HSTS article notes, HSTS also addresses "cookie hijacking," where an attacker steals a session cookie over an unencrypted connection.
The trust-on-first-use limitation
The main weakness of HSTS is described in the Wikipedia HSTS article: the protection "normally only applies after a user has visited the site at least once." The first visit to a domain — whether typed manually, clicked from an email, or followed from a bookmark — is still made over HTTP unless the browser already has a cached HSTS policy.
This is called trust on first use (TOFU). An attacker who can intercept that first connection can still perform an SSL stripping attack, because the browser has not yet received the HSTS header.
The HSTS preload list
To eliminate this first-visit window, major browsers maintain HSTS preload lists — hard-coded lists of domains that must always be accessed over HTTPS, baked into the browser binary. The Wikipedia HSTS article explains: "If a domain is on this list, the browser skips the initial request and encrypts all communication immediately."
The Chrome HSTS preload list (also used by Safari, Firefox, and other Chromium-based browsers) is managed at hstspreload.org. Any domain can submit itself, provided it meets these requirements:
- A valid certificate for the domain and all subdomains.
- Serving a redirect from HTTP to HTTPS, or refusing HTTP connections entirely.
- Serving the HSTS header on the HTTPS response with at least
max-age=31536000; includeSubDomains; preload.
Once on the list, removing a domain is difficult — it requires browser updates, which can take months. This makes the preload commitment serious. Sites should only request preload after they are certain HTTPS will be permanent.
Mixed content and HSTS
The MDN TLS documentation explains that an HTTPS page loading subresources over HTTP is called mixed content — the main page is encrypted, but the scripts, images, or stylesheets loaded over HTTP are not. An attacker who intercepts the page can replace those subresources with malicious code.
HSTS helps here too. When a browser has a cached HSTS policy for a domain, it automatically upgrades any http:// subresource requests to https:// before sending them. The MDN TLS documentation describes how browsers "either upgrade the load request to use HTTPS, or block the request entirely" for mixed content on secure pages.
Deploying HSTS: practical steps
- Enable HTTPS first — HSTS only works over HTTPS. A site must fully migrate to HTTPS before setting the header.
- Start with a short max-age — begin with
max-age=300(5 minutes) and verify nothing breaks. - Increase gradually — once verified, increase to
max-age=86400(1 day), then a week, then a month. - Add includeSubDomains — once stable, add the directive to cover all subdomains.
- Request preload — after running at
max-age=31536000; includeSubDomainsfor a few weeks with no issues, submit to hstspreload.org.
The MDN TLS documentation also recommends sending the Strict-Transport-Security header on every HTTPS response, not just the first one, to refresh the browser's policy and extend its expiry.
HSTS and CDN edge deployments
When a site uses a CDN, the HSTS header must be set at the CDN edge, not just the origin server. Cloudflare, for example, adds HSTS headers through its dashboard (Speed → Optimization → HSTS) or via a Strict-Transport-Security Page Rule. If the CDN terminates TLS, the HSTS header should be set on the CDN's response — it is the response the browser receives.
Sites using Cloudflare Pages can set HSTS via the public/_headers file:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
FAQ
What does HSTS protect against?
HSTS protects against protocol downgrade attacks (SSL stripping) and cookie hijacking. When a browser has a cached HSTS policy for a domain, it refuses to make unencrypted HTTP requests to that domain — even if the user types http:// directly. This prevents attackers on shared networks from intercepting the first request or stealing session cookies.
Does HSTS make a site completely secure?
No. HSTS protects the transport layer — it ensures all connections use HTTPS. It does not protect against vulnerabilities in the application itself, such as XSS (cross-site scripting), CSRF, SQL injection, or weak passwords. It also cannot protect the very first visit to a domain, unless the domain is on the browser's HSTS preload list. HSTS is one layer of a defense-in-depth strategy.
Why is a preload list needed if max-age is set?
The first visit to a domain is made before the browser has received the HSTS header. An attacker who intercepts this first unencrypted request can strip HTTPS and leave the user on HTTP. The preload list bakes the HTTPS requirement into the browser itself, so the upgrade happens on the very first request — before any network traffic leaves the browser. The Wikipedia HSTS article describes this as addressing "the problem of the first request."
What is the difference between HSTS and HTTPS redirect?
An HTTPS redirect (a server responding to http:// requests with a 301 Moved Permanently or 302 Found redirect to the HTTPS URL) tells the browser where to go. HSTS tells the browser never to ask for the HTTP URL in the first place. Redirects can be intercepted and stripped before they take effect; HSTS eliminates the unencrypted request. The two work together: redirects handle existing links and bookmarks, while HSTS prevents the initial unencrypted connection.
How does HSTS interact with subdomains?
The includeSubDomains directive in the HSTS header extends the HTTPS-only policy to every subdomain of the domain. If example.com sets Strict-Transport-Security: max-age=31536000; includeSubDomains, then api.example.com, cdn.example.com, and any other subdomain are also covered. Without includeSubDomains, only the exact domain receives HSTS protection — a subdomain served over HTTP is unaffected.
Verdict
HSTS is a simple, high-impact security header. A single Strict-Transport-Security response header eliminates the SSL stripping attack class on every subsequent visit — for free, with no performance cost, and minimal deployment risk when introduced with a short max-age. The combination of a long max-age, includeSubDomains, and preload registration makes it a near-complete defense against protocol downgrade for the vast majority of users.
The practical takeaway: set max-age=31536000; includeSubDomains on your HTTPS responses today, submit to hstspreload.org once stable, and never serve any part of your site over HTTP again.
Sources
- Wikipedia — HTTP Strict Transport Security (en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
- CC BY-SA 4.0
- Wikipedia contributors)
- MDN — Transport Layer Security (developer.mozilla.org/en-US/docs/Web/Security/Transport_Layer_Security
- CC-BY-SA 2.5+
- MDN contributors)
- Wikipedia — Transport Layer Security (en.wikipedia.org/wiki/Transport_Layer_Security
- CC BY-SA 4.0
- Wikipedia contributors)
Share this guide
Related guides
- TLS versions explained: from SSL 3.0 to TLS 1.3
Every TLS version from SSL 3.0 to TLS 1.3 explained — what changed, what broke, and why old versions are now disabled by default.
- SSH explained: how Secure Shell works
SSH explained: what Secure Shell is, how the protocol works end to end, and why it replaced telnet and rsh.
- What is SSRF (Server-Side Request Forgery)? How it works and how to prevent it
Server-Side Request Forgery (SSRF) lets an attacker abuse a server's own URL-fetching feature to reach internal systems and cloud metadata. This guide explains the attack and the defenses that stop it.