Force HSTS using .htaccess

HSTS (HTTP Strict Transport Security) protects users from cookie hijacking and protocol downgrade attacks by forcing browsers to request HTTPS pages from your domain. HSTS is similar to a 301 redirect from HTTP to HTTPS but at the browser level.

There may be a specific HSTS configuration appropriate for your website. The following are less secure options and preload-ineligible as first-time traffic to your site will be able to use insecure HTTP:

Header Set Strict-Transport-Security: max-age=10886400;
Header Set Strict-Transport-Security: max-age=10886400; includeSubDomains

A breakdown of the header:

Strict-Transport-SecurityForces HSTS on the domain
max-ageHow long the header should be active in seconds
includeSubDomainsIncludes subdomains
preloadAuthorizes preload listing if eligible (covered below)

Below we’ll cover adding the most secure HSTS configuration using the .htaccess file and submitting your domain to the Chrome preload list maintained by Google.

Warning:Once enabled, HSTS disallows the user from overriding an invalid or self-signed certificate message. Your website will be inaccessible without a valid SSL.

Enable HSTS for Preloading

  1. Using SSH or cPanel File Editor, edit your .htaccess file.
  2. Add the following line to your .htaccess file:
    Header set Strict-Transport-Security "max-age=10886400; includeSubDomains; preload"

    Note: The expiry must be at least 18 weeks (10886400 seconds).

  3. To submit your domain for preloading, visit HSTSpreload.org.
  4. Type your domain and Check HSTS preload status and eligibility.
  5. The background will turn green or red depending on the results.
  6. Fix the errors and/or submit your domain for preloading.

After submitting your domain for HSTS preloading, it can take 2-6 months for your domain to be accepted and then listed in the latest browser versions. You can read more about the preload process at hstspreload.org and browsers supporting HSTS at CanIUse.com.

InMotion Hosting Contributor
InMotion Hosting Contributor Content Writer

InMotion Hosting contributors are highly knowledgeable individuals who create relevant content on new trends and troubleshooting techniques to help you achieve your online goals!

More Articles by InMotion Hosting

2 thoughts on “Force HSTS using .htaccess

  1. What else does one need to do in addition to this and the instructions to force https in order to be eligible for preload?

    With the following lines included in my .htaccess file (after purging the entire cache):
    #BEGIN force SSL on entire site
    RewriteEngine On
    RewriteCond %{HTTPS} !on
    RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
    RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    #END force SSL on entire site

    Header set Strict-Transport-Security “max-age=10886400; includeSubDomains; preload”

    I got the following errors at Hstspreload.org.–

    Error: No includeSubDomains directive
    The header must contain the `includeSubDomains` directive.
    Error: No preload directive
    The header must contain the `preload` directive.
    Error: No redirect from HTTP
    `https://—-` does not redirect to `https://—-`.
    My .htaccess file contain

    1. Hello, and thanks for getting in touch with us!

      For your privacy, I removed your site’s URL from your post. Before I did, though, I checked the site myself and ran some scans.

      According to a scan that I ran using:
      https://securityheaders.com/

      These are the results for Strict-Transport-Security
      “Strict-Transport-Security max-age=31536000”

      It looks like the results I’m seeing from the scan do not match the code you posted.

      If you’re using caching, like with an NGINX server or some other form of site caching, be sure to clear your cache! Try doing a full cache purge on the site.

      It’s quite likely that the changes you made to the site’s code just have not propagated due to caching.

      Lastly, it’s generally advisable to keep the max-age at least a year (max-age=31536000) but you may have specific reasons for using the configuration you posted, so I’m only pointing that out as a general principle.

      Hopefully checking the caching clears things up!

Was this article helpful? Join the conversation!