HTTP Strict Transport Security (HSTS) is a security mechanism that instructs browsers to only communicate with your website over HTTPS. Once a browser receives the HSTS header from your server, it will automatically convert any HTTP requests to HTTPS for the duration specified in the header, even if the user explicitly types http:// in the address bar or clicks on an old HTTP link.
This might sound like a minor convenience feature, but it solves a real and dangerous problem. Let's walk through exactly why HSTS exists, how it works in practice, and what you need to know as a WordPress site owner.
How SSL Stripping Attacks Work Without HSTS
Imagine a visitor opens their laptop at a coffee shop and types yoursite.com into the browser. Without HSTS, the browser first sends a plain HTTP request to your server. Your server then responds with a 301 redirect to https://yoursite.com. That initial HTTP request, however, is completely unencrypted. It travels over the coffee shop's WiFi network as plain text.
An attacker sitting on the same network can intercept that first unencrypted request using a technique called SSL stripping. The attacker acts as a proxy: they maintain an HTTPS connection to your real server but serve a plain HTTP version to the victim. From the visitor's perspective, the site looks normal (most people don't check for the padlock icon). Meanwhile, the attacker can read everything: login credentials, form submissions, session cookies, credit card details.
This is not a theoretical attack. Tools like sslstrip have been publicly available since 2009, and SSL stripping remains one of the most practical attacks on public WiFi networks. HSTS exists specifically to close this gap.
How HSTS Protects Your WordPress Site
When your server sends the following response header:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadThe browser stores this instruction internally. For the next 31,536,000 seconds (one year), it will never attempt an HTTP connection to your domain. If anything tries to load a resource via HTTP, the browser rewrites it to HTTPS locally before the request even leaves the device. There is no unencrypted request for an attacker to intercept.
This protection works on the browser level, which is the key advantage. No redirect is needed. No unencrypted request is ever sent. The browser simply refuses to use HTTP for your domain.
HSTS Header Directives Explained
The HSTS header accepts three directives, and each one serves a specific purpose:
max-age: The time in seconds that the browser should remember to enforce HTTPS. Common values are86400(1 day, useful for initial testing),2592000(30 days, a reasonable starting point), and31536000(1 year, the recommended production value). If you set this to zero, the browser will immediately stop enforcing HSTS for your domain.includeSubDomains: Extends the HSTS policy to all subdomains. This meanscdn.yoursite.com,mail.yoursite.com, and any other subdomain will also be forced to HTTPS. Be careful with this directive: if any subdomain doesn't support HTTPS, it will become unreachable once this is active.preload: A signal that you want your domain added to browser preload lists. More on this below.
The First Visit Problem and HSTS Preload Lists
HSTS has one fundamental limitation: the browser needs to receive the header at least once before it can enforce anything. On the very first visit, before the browser has ever seen your HSTS header, the initial HTTP request is still vulnerable to interception. This is known as the "first visit problem" or "bootstrap problem."
The HSTS preload list solves this. It is a list of domains that is hardcoded into the browser itself (Chrome, Firefox, Safari, and Edge all share the same list). If your domain is on the preload list, the browser enforces HTTPS from the very first connection, even if the user has never visited your site before.
To get your domain on the preload list, you need to meet all of the following requirements:
- Serve a valid HTTPS certificate on your root domain
- Redirect all HTTP traffic to HTTPS on the same host
- Serve the HSTS header on the root domain with
max-ageof at least31536000(one year) - Include the
includeSubDomainsdirective - Include the
preloaddirective - All subdomains must support HTTPS
You can submit your domain at hstspreload.org. Keep in mind that getting onto the list takes weeks or months (it ships with browser updates), and getting removed is equally slow. Make sure your HTTPS setup is solid before submitting.
Common max-age Values and Recommended Rollout Strategy
It's tempting to jump straight to a one-year max-age, but a gradual rollout is safer, especially for sites with multiple subdomains or complex setups:
max-age=300(5 minutes): Use this during initial testing. If something goes wrong, visitors will only be locked into HTTPS for five minutes.max-age=86400(1 day): A good next step once you've confirmed HTTPS works correctly.max-age=2592000(30 days): Move here after a week or two of stable operation.max-age=31536000(1 year): The recommended production value. This is also the minimum required for the preload list.
Setting Up HSTS on a WordPress Site
WordPress itself doesn't send the HSTS header by default. You have several options for adding it:
The most reliable approach is to add the header at the server level. In Apache, add this to your .htaccess file or virtual host configuration:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"For Nginx, add this inside your server block:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;If you don't have access to server configuration (common on shared hosting), you can add the header via PHP in your theme's functions.php or through a must-use plugin:
add_action('send_headers', function() {
header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');
});The server-level approach is preferred because it applies to all responses, including static files and error pages, not just PHP-generated pages.
Several WordPress security plugins also offer HSTS configuration through their settings panels, which can be convenient if you prefer a GUI-based approach.
Common Pitfalls with HSTS on WordPress
Before enabling HSTS, double-check a few things:
- Mixed content: Make sure all resources (images, scripts, stylesheets, fonts) are loaded over HTTPS. HSTS forces the main connection to HTTPS, but if your content still references HTTP URLs, browsers will block those resources.
- SSL certificate renewal: Once HSTS is active, an expired certificate will make your site completely unreachable (instead of showing a bypassable warning). Set up automatic certificate renewal with Let's Encrypt or your certificate provider.
- Subdomain readiness: If you use
includeSubDomains, every single subdomain needs a valid HTTPS certificate. A staging subdomain on HTTP will stop working. - CDN configuration: If you use a CDN like Cloudflare, make sure HSTS is configured consistently. Cloudflare offers its own HSTS settings that may override your server headers.
What InspectWP Checks
InspectWP analyzes whether your WordPress site sends the Strict-Transport-Security response header. The report evaluates the max-age value, checks for the includeSubDomains directive, and flags the header as missing if it's not present. A proper HSTS header with a long max-age value (at least 6 months or one year) and the includeSubDomains directive is recommended for every WordPress site that runs on HTTPS, which in today's web should be all of them.