HTTP Strict Transport Security (HSTS) is a mechanism that tells browsers to always use HTTPS when connecting to your domain. Without HSTS, a user's first request (for example, when entering example.com without https://) goes over HTTP and is vulnerable to man-in-the-middle attacks. HSTS closes this vulnerability window.
The problem HSTS solves
Attack scenario:
- The user enters
example.comin the address bar. - The browser makes an HTTP request by default.
- An attacker on the same network intercepts the traffic and modifies the response.
- The user may receive a phishing page or have their data intercepted.
With HSTS, the browser “remembers” that the domain requires HTTPS and converts HTTP requests to HTTPS before sending them. The first visit is still vulnerable, but all subsequent visits are protected.
You can check the HSTS and SSL configuration using the security headers analyzer and SSL Checker on rechecker.ru.
Strict-Transport-Security header syntax
Strict-Transport-Security: max-age=<seconds>; includeSubDomains; preload| Parameter | Description |
|---|---|
max-age | The time in seconds for which the browser remembers the policy. 31536000 (1 year) is recommended |
includeSubDomains | Apply the policy to all subdomains |
preload | A hint to include the domain in browsers' HSTS preload list |
Requirements before enabling HSTS
- Working HTTPS — the site must be correctly served over HTTPS on all pages.
- HTTP → HTTPS redirect — all HTTP requests must be redirected to HTTPS (301 or 302).
- Valid certificate — with no errors or expiration. Check it with SSL Checker.
If you enable HSTS when HTTPS is not working, users will not be able to bypass the browser's block. Removal from the preload list takes months.
Configuration in Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;The always parameter is needed to ensure the header is sent for 4xx/5xx status codes as well.
Configuration in Apache
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"The mod_headers module is required:
LoadModule headers_module modules/mod_headers.soConfiguration in Node.js (Express)
app.use((req, res, next) => {
if (req.secure) {
res.setHeader(
'Strict-Transport-Security',
'max-age=31536000; includeSubDomains; preload'
);
}
next();
});When using a reverse proxy (Nginx in front of Node), check the X-Forwarded-Proto header:
const isSecure = req.secure || req.get('X-Forwarded-Proto') === 'https';
if (isSecure) {
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
}Cloudflare
In the Cloudflare dashboard: SSL/TLS → Edge Certificates → enable “HSTS” and set max-age. Preload is enabled as a separate option.
HSTS Preload
Preload is a list of domains built into browsers. For these domains, HTTPS is required from the first visit, without a single HTTP request.
Steps:
- Make sure HSTS is configured with
max-ageof at least 31536000 andincludeSubDomains. - Add the
preloaddirective to the header. - Go to hstspreload.org and submit the domain.
- Wait for the domain to be added to the list (usually in the next Chrome release).
Important: removal from preload takes several months. Make sure HTTPS will work reliably.
Checking the configuration
curl -I https://example.comExpected header:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadOnline check: Security Headers shows all security headers, including HSTS.
includeSubDomains: when to use it
Enable includeSubDomains only if all subdomains (www, api, cdn, admin, etc.) are served over HTTPS. Otherwise, users will not be able to open a subdomain over HTTP.
Check the subdomains:
curl -I https://www.example.com
curl -I https://api.example.comCommon mistakes
- HSTS without working HTTPS — the site becomes unavailable if there are certificate problems.
- Short max-age — the browser will quickly “forget” the policy, weakening protection.
- includeSubDomains with problematic subdomains — for example, an old blog.example.com without HTTPS.
- Preload without thorough checks — removal is lengthy and complicated.
Relationship to other mechanisms
HSTS complements, but does not replace:
- HTTP → HTTPS redirects (needed for the first visit and older browsers).
- A valid SSL certificate (see SSL certificates: a complete guide).
- Other security headers (see HTTP security headers: web application protection).
Recommended configuration
For most sites:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadMake sure all subdomains support HTTPS, then add the domain to preload at hstspreload.org.