Skip to main content
mySites.guru
4+ live

Joomla extension security alerts (28 Aug) ZOO: unauth RCESourcerer 16.0.0Fabrik 4.7.2JCE 2.9.99.10

Joomla

Strict-Transport-Security (HSTS)

Strict-Transport-Security (HSTS)

Strict-Transport-Security tells the browser to only ever use HTTPS for your site, closing the gap an attacker can exploit during that first request.

How common is this?

  • 72% of the Joomla sites we have this data for fail this check. Platform: Joomla.

Measured across the sites we audit, on each site's most recent snapshot.

What this check and mySites.guru tool looks at on your site

mySites.guru requests a page from your Joomla extension site directly, then reads back the raw HTTP response headers to see whether Strict-Transport-Security is present, and whether the value it carries actually does anything useful. We check against a page your server answers itself, such as a 404, rather than only the homepage, because a plugin-added header often covers one and not the other. This is one of four header checks covered in checking your website’s security headers with mySites.guru.

The gap the redirect alone leaves open

Most sites redirect http:// to https:// and consider the job done. That redirect is real protection, but it has a gap: the very first request, the one that triggers the redirect, still goes out over plain HTTP. An attacker sitting on the same network, a coffee shop Wi-Fi, a compromised router, a rogue access point, can intercept that first request before the redirect ever completes and quietly serve their own version of the page instead, or strip the encryption entirely for the rest of the session. This is a real, well-documented attack, not a theoretical one.

HSTS closes that gap. Once a browser has received the header from your site, it remembers your instruction for the duration of max-age and simply refuses to make an HTTP request to your domain again during that window, upgrading it to HTTPS internally before anything leaves the device. There’s no redirect to intercept, because the browser never sends the insecure request in the first place. It only takes effect after the first successful HTTPS visit, which is the one gap even HSTS can’t close on its own, and it’s what the preload mechanism exists to solve for sites that need protection from the very first visit.

It’s worth understanding the flip side of that same guarantee before you set it. Because the browser is enforcing HTTPS on your behalf and refusing to fall back, a certificate that expires, a misconfigured renewal, or TLS breaking for any other reason doesn’t degrade gracefully to plain HTTP the way it would without HSTS in place. The browser simply refuses to load the site at all, showing a hard error a visitor can’t click past, for as long as the cached max-age lasts. HSTS is protecting you from exactly the failure mode it also makes worse if your own certificate management slips, which is the strongest argument for getting automatic renewal solid before setting a long max-age.

The header value we recommend, and the one we don’t

A sensible, widely recommended value is:

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

max-age=31536000 sets the enforcement window to a year, and includeSubDomains extends the same rule to every subdomain of your site, which matters because an attacker doesn’t need to compromise your main domain if staging.yoursite.com is left exposed. We deliberately don’t recommend adding preload by default. It’s a legitimate and stronger option, but submitting a domain adds it to a hard-coded list inside every major browser, and removing it again, should you ever need a subdomain to run over plain HTTP, takes months to propagate back out.

How to fix it

The most common way to set this is in your web server config or an .htaccess file, applied at server level so it covers every request, not just the ones PHP handles:

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" env=HTTPS

The env=HTTPS condition matters: it stops the header being sent on a plain HTTP response, which would be a contradiction Joomla itself wouldn’t have caused, but a misconfigured server could.

On nginx, add this inside the HTTPS server block for https://yoursite.com/administrator and your front end:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
  1. Confirm HTTPS actually works reliably across the whole site first, including every subdomain you plan to cover with includeSubDomains. HSTS enforces HTTPS whether or not it’s ready.
  2. Add the header at server level, not through a Joomla extension, so it applies to every response, including static assets and 404 pages.
  3. Start with a short max-age, such as a few hours, and confirm the site still works correctly over HTTPS everywhere.
  4. Once you’re confident, raise max-age to a year and add includeSubDomains.
  5. Only consider preload once the header has been stable in production for a while and you’re certain no subdomain will ever need to serve plain HTTP.

A long max-age is hard to undo

Once a browser has cached a year-long HSTS instruction from your site, it will refuse plain HTTP for that entire year, no matter what you change server-side afterwards. If you might need HTTP again on any subdomain, sort that out before you set max-age to a year and add includeSubDomains, not after.

What mySites.guru does about it

Getting HSTS wrong in either direction has real consequences, so this isn’t something we apply automatically. mySites.guru checks for a valid Strict-Transport-Security header on every snapshot, twice a day, and shows you exactly what your site is currently sending, alongside the other response headers we check: Content-Security-Policy, X-Frame-Options and X-Content-Type-Options. Where your certificates come from and how their renewal is handled sits outside what any of those checks can see, so pairing HSTS with a reliable certificate-monitoring habit is worth doing separately.

Strict-Transport-Security (HSTS)

mySites.guru checks every connected site for this automatically and flags it the moment it appears. These run twice a day on every connected site.

Further Reading

Frequently Asked Questions

What does the Strict-Transport-Security header actually do?
It tells the browser to remember, for however long the max-age you set lasts, that your site should only ever be reached over HTTPS. Once a browser has seen the header once, it rewrites any future http:// request to https:// itself, before the request ever leaves the device.
Should I add the preload directive to my HSTS header?
Not without understanding what it does first. Submitting your domain for preload bakes it into a list shipped inside the browsers themselves, which means HTTPS is enforced even on the very first visit, but reversing it if you ever need plain HTTP again is slow and difficult. Get includeSubDomains working reliably before considering it.
Why does a long max-age matter for HSTS?
The max-age is how long the browser keeps enforcing HTTPS for your domain after the last time it saw the header. A short value gives an attacker on an unencrypted network a fresh window to intercept the next plain HTTP request every time it expires. A year is the usual recommendation, but a year is also how long you're committed to keeping HTTPS working properly once you set it.