HTTPS, SSL & Security
What is HSTS?
HSTS, HTTP Strict Transport Security, is a web security policy mechanism that instructs browsers to connect to a domain exclusively over HTTPS for a specified period, eliminating HTTP connections entirely rather than relying on server-side redirects to upgrade them. Once a browser receives an HSTS header from a domain it remembers that the domain requires HTTPS and automatically upgrades all future HTTP requests to HTTPS before they leave the device, without making any network request over HTTP at all.
The problem HSTS solves is the vulnerability window created by HTTP-to-HTTPS redirects. When a user types example.com without specifying a protocol their browser first attempts an HTTP connection, sending a request over the insecure channel before receiving the redirect to HTTPS. During this brief HTTP connection an attacker who can intercept network traffic, on a public Wi-Fi network, through a compromised router, or through network-level surveillance, can intercept the HTTP request, strip the redirect response, and serve malicious content over HTTP without the user ever reaching the secure HTTPS version. This attack is called SSL stripping.
HSTS eliminates this vulnerability window. After a browser receives an HSTS policy for a domain it never makes an HTTP request to that domain during the policy’s validity period, the browser upgrades HTTP to HTTPS internally before any network communication occurs. An attacker who can intercept network traffic sees only HTTPS connections, the HTTP connection that could be stripped never exists.
How HSTS works
HSTS operates through a response header that the server includes in HTTPS responses, instructing the browser to enforce HTTPS-only connections for the domain going forward.
The HSTS header: the server includes the Strict-Transport-Security header in HTTPS responses:
The header has three components, max-age, includeSubDomains, and preload: each controlling a different aspect of the policy.
max-age: the duration in seconds that the browser should enforce the HSTS policy. max-age=31536000 specifies one year. During this period the browser upgrades all HTTP requests to HTTPS and refuses to connect over HTTP even if explicitly instructed to by the user. When the browser encounters a new HSTS header for the same domain it updates its stored policy, resetting the countdown to the new max-age value. The browser’s HSTS policy for a domain is refreshed on every HTTPS visit to the domain as long as the header is present.
includeSubDomains: extends the HSTS policy to all subdomains of the domain. With includeSubDomains the browser enforces HTTPS not only for example.com but also for www.example.com, api.example.com, blog.example.com, and every other subdomain. Without this directive the HSTS policy applies only to the exact domain that served the header.
includeSubDomains requires that every subdomain of the domain supports HTTPS correctly, including valid SSL certificates. If any subdomain does not support HTTPS the browser’s HSTS enforcement makes that subdomain inaccessible, the browser upgrades HTTP to HTTPS but the subdomain cannot complete the TLS handshake. Before adding includeSubDomains verify that every subdomain has valid SSL.
preload: signals that the domain owner wants the domain included in browser HSTS preload lists, a hardcoded list of HSTS domains distributed with browsers. Preloaded domains have HSTS enforced from the very first visit, before the browser has ever received an HSTS header from the domain. Including the preload directive in the header is the first step in the preloading process, the domain owner must also submit the domain to the preload list registry.
HSTS and the first visit problem
HSTS provides strong protection for returning visitors whose browsers have already received and stored the policy. It does not inherently protect first-time visitors, and this gap is the motivation for HSTS preloading.
The first visit vulnerability: when a browser visits a domain for the first time it has no stored HSTS policy for that domain. The browser attempts HTTP first, http://example.com: and receives the redirect to HTTPS. During this initial HTTP connection the browser is vulnerable to SSL stripping attacks. Only after reaching the HTTPS version and receiving the HSTS header does the browser store the policy and begin enforcing HTTPS-only connections on subsequent visits.
HSTS preloading: the solution to the first visit problem. Browser vendors, Google Chrome, Mozilla Firefox, Apple Safari, Microsoft Edge, maintain hardcoded lists of domains that should always be accessed over HTTPS regardless of whether the browser has visited the domain before. Domains on the preload list have HSTS enforced from the very first visit, the browser never makes an HTTP request to these domains.
The preload list is compiled by Google and distributed with browsers, all major browsers use the same list. The list is compiled from domain submissions at hstspreload.org: domain owners submit their domains and must meet requirements for inclusion.
Preload list requirements: to be accepted for preloading a domain must meet several requirements. The domain must serve a valid HTTPS response. The domain must serve an HSTS header with a max-age of at least one year. The HSTS header must include the includeSubDomains directive, preloading applies to the entire domain including all subdomains. The HSTS header must include the preload directive signalling intent to be preloaded. All subdomains must support HTTPS, every subdomain will be forced to HTTPS by the preload policy.
Preload list permanence: inclusion in the preload list is difficult to undo. Browsers ship with the preload list embedded, removing a domain from the list does not affect browsers that have already been distributed with the list. A domain that is preloaded and later stops supporting HTTPS, or has a subdomain that stops supporting HTTPS, becomes inaccessible for browsers with the preloaded policy. Preload list removal requests are accepted and the domain is removed from future list updates, but the change only reaches users after a browser update propagates the new list.
This semi-permanence means preload list submission should be made only after careful consideration, once submitted and included the domain is committed to HTTPS-only operation across all subdomains essentially permanently.
HSTS and redirects
The interaction between HSTS and redirect management is important, HSTS changes how browsers handle both the redirect source and the redirect response.
HSTS eliminates the HTTP-to-HTTPS redirect cost: without HSTS browsers accessing http://example.com make an HTTP request, receive the 301 redirect to https://example.com, make a new HTTPS request, and finally receive the page. Two requests are required, one HTTP and one HTTPS. With HSTS in place the browser upgrades http://example.com to https://example.com internally, making only one HTTPS request directly. The HTTP-to-HTTPS redirect overhead is eliminated for returning visitors whose browsers have the HSTS policy stored.
This performance benefit is significant for redirect chains involving HTTP-to-HTTPS transitions. An HTTP-to-HTTPS redirect that would add one round trip of latency is eliminated entirely for HSTS-covered visitors.
HSTS on redirect source domains: when a domain is configured as a redirect source, old-domain.com redirecting to new-domain.com: HSTS on the redirect source domain changes browser behaviour for returning visitors. Browsers with a stored HSTS policy for old-domain.com upgrade HTTP requests to HTTPS before making any network request. The HTTPS request to old-domain.com requires a valid SSL certificate: the TLS handshake must succeed before the browser receives the redirect response.
This interaction means that once HSTS is established on a redirect source domain that domain requires SSL indefinitely, browsers with stored HSTS policies continue to make HTTPS requests to the domain until the HSTS max-age expires. Removing SSL from a redirect source domain after HSTS has been established causes connection failures for browsers with stored HSTS policies.
HSTS and permanent redirect caching: 301 permanent redirects are cached by browsers, a browser that has followed a 301 from example.com to www.example.com goes directly to www.example.com on subsequent visits without querying example.com. HSTS and permanent redirect caching compound, a browser with both a cached 301 redirect and a stored HSTS policy for the redirect destination applies both simultaneously. The browser upgrades HTTP to HTTPS through HSTS and goes directly to the redirect destination through the cached redirect, optimising the navigation path significantly.
Removing HSTS from redirect infrastructure: when a domain is being retired as a redirect source and will eventually stop being renewed removing the HSTS header well in advance is important. The max-age should be set to zero, max-age=0: to instruct browsers to remove the stored HSTS policy. After the max-age has expired across all stored browser policies the HSTS policy is cleared and the domain can eventually be decommissioned without leaving browsers with policies that will cause connection failures.
Implementing HSTS
Implementing HSTS involves a progressive process, starting with a low max-age to test and gradually increasing to a long-term value once HTTPS is fully working.
Step 1, ensure HTTPS is fully working: before implementing HSTS verify that HTTPS works correctly for all variants of the domain, root domain and all subdomains if includeSubDomains will be used. Valid SSL certificates must be present for every subdomain. The mixed content audit should be clean, all resources loaded over HTTPS. HTTP-to-HTTPS redirects should be working for all URL variants.
HSTS is unforgiving, once in place browsers will not connect over HTTP to the domain. Any HTTPS configuration problems that exist when HSTS is implemented will make the affected URLs inaccessible for browsers with stored HSTS policies.
Step 2, start with a low max-age: begin with a short max-age, 300 seconds or 3600 seconds, and monitor for any HTTPS issues. The low max-age means that if problems are discovered the HSTS policy expires quickly, browsers that received the header will clear the policy within minutes to hours. This provides an escape hatch while the configuration is being validated.
Step 3, increase max-age progressively: once HTTPS is confirmed to be working correctly across all scenarios increase the max-age progressively, to one day, then one week, then one month. At each step monitor for any HTTPS issues before increasing further. The increasing max-age extends the window during which stored policies protect browsers while the escape hatch gets progressively smaller.
Step 4, long-term max-age: once confident that HTTPS is stable and will remain so set a long-term max-age, one year, max-age=31536000: is the standard recommendation. Adding includeSubDomains if all subdomains support HTTPS.
Step 5, preload list submission (optional): for maximum security submit the domain to the HSTS preload list at hstspreload.org. Only after thorough testing and confidence in permanent HTTPS support for all subdomains. Remember that preloading is difficult to reverse.
Server configuration: the HSTS header is set in web server or redirect infrastructure configuration.
Nginx:
Apache:
The always parameter ensures the header is included in all responses, including error responses, not just successful ones.
HSTS and SEO
HSTS has positive indirect SEO implications, it reinforces HTTPS consistency and eliminates HTTP connection overhead that affects performance signals.
HTTPS consistency: HSTS ensures that all browser connections to the domain are HTTPS, eliminating the possibility of content being accidentally served over HTTP. Consistent HTTPS across all connections prevents the accidental HTTP content indexation that can create duplicate content issues between HTTP and HTTPS versions.
Performance benefit: eliminating the HTTP-to-HTTPS redirect hop for returning visitors reduces page load time, a factor in Core Web Vitals and overall user experience signals that search engines use as ranking factors. The latency reduction from eliminating one redirect hop is modest but measurable.
Crawl budget: search engine crawlers that have encountered an HSTS header for a domain may update their crawl behaviour to request HTTPS directly, skipping the HTTP-to-HTTPS redirect. This reduces the crawl budget consumed by redirect hops on large sites with many pages.
Common HSTS mistakes
Enabling HSTS before HTTPS is fully working: the most dangerous mistake. If any HTTPS configuration issue exists when HSTS is enabled, an expired certificate, a missing certificate on a subdomain, a misconfigured TLS version, the affected URLs become inaccessible for browsers that store the HSTS policy. Always fully validate HTTPS before enabling HSTS.
Starting with a long max-age: beginning with a one-year max-age leaves no escape hatch if HTTPS problems are discovered after HSTS is enabled. Start with a short max-age and increase progressively after validation.
includeSubDomains without SSL on all subdomains: if any subdomain does not support HTTPS the includeSubDomains directive makes that subdomain inaccessible. Audit all subdomains for SSL coverage before adding includeSubDomains.
Premature preload list submission: submitting to the preload list before the HTTPS configuration is thoroughly tested and stable. Preloading is difficult to reverse, browsers already distributed with the preload list continue to enforce HSTS even after list removal.
HSTS on HTTP responses: the HSTS header must only be included in HTTPS responses, serving it over HTTP has no effect and indicates a misconfiguration. Browsers only process HSTS headers received over HTTPS.
Removing HSTS without zeroing max-age first: removing the HSTS header from the server without first setting max-age=0 to clear stored browser policies. Browsers that previously received the HSTS header continue to enforce HTTPS for the duration of the stored max-age, potentially months or years. Set max-age=0 and allow it to propagate before removing HSTS infrastructure.