Press "Enter" to skip to content

HSTS (HTTP Strict Transport Security)

To enable HSTS with the API, send a PATCH request with the value object that includes your HSTS settings.

HTTP Strict Transport Security (HSTS)

HSTS protects HTTPS web servers from downgrade attacks. These attacks redirect web browsers from an HTTPS web server to an attacker-controlled server, allowing bad actors to compromise user data and cookies.

  • Transform HTTP links to HTTPS links
  • Prevent users from bypassing SSL browser warnings

Before enabling HSTS, review the requirements .

For more background information on HSTS, see the introductory blog post External link icon

​​ Availability

​​ Requirements

  • Have enabled HTTPS before HSTS so browsers can accept your HSTS settings
  • Keep HTTPS enabled so visitors can access your site

​​ Enable HSTS

To enable HSTS with the API, send a PATCH request with the value object that includes your HSTS settings.

​​ Disable HSTS

  1. Log in to the Cloudflare dashboard and select your account.
  2. Select your website.
  3. Go to SSL/TLS >Edge Certificates.
  4. For HTTP Strict Transport Security (HSTS), select Enable HSTS.
  5. Set the Max Age Header to 0 (Disable).
  6. If you previously enabled the No-Sniff header and want to remove it, set it to Off.
  7. Select Save.

HSTS (HTTP Strict Transport Security)

Learn why HTTPS is not enough to protect your website from network attacks and how the HSTS header comes in to solve the problem. Let’s begin!

What is HSTS?

HTTP Strict Transport Security is an opt-in browser security feature that prevents browsers from making any unencrypted connections to a domain.

By unencrypted connections I mean using http instead of https (or ws instead of wss for WebSockets).

You can enable the protection for your website with the Strict-Transport-Security header like so:

Strict-Transport-Security: > 

There are 3 options, max-age , includeSubdomains and preload . We’ll get to those in a minute, but first, let me explain why it is so important that you implement HSTS in your web application.

Why is HSTS important?

The HSTS header prevents network attacks against your web application. If you are not using it, here is how your application might work:

Scenario 1: No HSTS, No Attacker

  1. The user types in www.example.com
  1. The user’s browser sends an unencrypted HTTP request to http://www.example.com/
  1. The webserver returns a redirect to https://www.example.com
  1. The user’s browser sends an encrypted HTTPS request to https://www.example.com/.
  1. The webserver returns with the login page.
  1. The user enters their username and password, which the browser safely sends to the webserver across a secure TLS connection.

But what if there is an attacker on the network? HTTPS doesn’t help. Let me show you what I mean.

Scenario 2: No HSTS, Attacker on the network

  1. The user types in www.example.com
  1. The user’s browser sends an unencrypted HTTP request to http://www.example.com/
  1. The attacker intercepts this unencrypted request and returns the login page from the real server. Crucially, the connection is still unencrypted.
  1. The user gives their username and password straight to the attacker over the unencrypted connection.

Oops. That’s not good.

Now let’s see what happens when the HSTS header protects the web application.

Scenario 3: HSTS

  1. The user types in www.example.com
  1. The website uses HSTS, so the user’s browser right away sends an encrypted HTTPS request to https://www.example.com/. The attacker doesn’t get a chance.
  1. The webserver returns with the login page.
  1. The user enters their username and password, which the browser safely sends across a secure TLS connection.

See how HSTS prevented the attack? But now you may be asking.

What if the user is visiting the website for the first time?

An excellent question! If the user is visiting the website for the first time, the user’s browser hasn’t had the chance to see the HSTS header yet.

In this case, the attack is still possible because the attacker takes over the connection before the actual web server gets a chance to tell the user’s browser to use HSTS.

Luckily, there is a solution, and I promise you’ll know everything about it by the end of this article. It has to do with the third option, preload , but let’s look at the other two options first!

The max-age parameter

The first parameter in the HSTS header is max-age . It is the amount in seconds for how long you want browsers to remember the header once they see it.

For example, the following header would enable HSTS for one minute for the domain that sends it. The browser would then, for 60 seconds, refuse to make any unencrypted connections to the domain.

Strict-Transport-Security: max-age=60 

Such a short time is generally not very useful. It’s more common to see values for a year or two years like so:

# 1 year Strict-Transport-Security: max-age=31536000 
# 2 years Strict-Transport-Security: max-age=63072000 

Browsers will refresh the time every time they see the header.

☝️ Note

When implementing HSTS in a production environment, it’s good to start with a small max-age and then slowly ramp it up to a year or two years. This way, you can quickly recover if something breaks.

Canceling HSTS

The second use-case for the max-age parameter is to cancel HSTS if you want to get rid of it. By returning max-age of zero, browsers will remove the protection once they see the header.

# Cancel HSTS Strict-Transport-Security: max-age=0 

The includeSubdomains parameter

The second parameter is includeSubdomains . By default, the HSTS header will only affect the domain that serves it. That is, if https://www.example.com sends it, then only www.example.com will be protected, foo.www.example.com will not.

To include subdomains, add includeSubdomains like so:

# Store for 2 years, apply also to subdomains Strict-Transport-Security: max-age=6307200; includeSubdomains 

☝️ Note

The includeSubdomains directive is a requirement for preloading, which we’ll look at next.

HSTS preloading

The third parameter, preload , facilitates HSTS preloading.

As I mentioned earlier, preloading is a mechanism that you can use to protect your website with the HSTS header even when the user is visiting the website for the first time.

It works so that you tell Google to protect your website, and they will see that all of the major browsers will change their source code to preload the HSTS header for your domain.

No joke! You can see the JSON file right here. If you look carefully, you will find appsecmonkey there!

 "name": "appsecmonkey.com", "policy": "bulk-1-year", "mode": "force-https", "include_subdomains": true >, 

There are a couple of prerequisites for enabling preloading for your domain, though.

First and foremost, you have to serve an HSTS header with the preload directive. Additionally, the max-age has to be >= a year, and you have to add includeSubdomains .

# Store for two years, also apply to subdomains, enable preloading Strict-Transport-Security: max-age=63072000; includeSubDomains; preload 

Also, your domain must return a valid TLS certificate on the HTTPS port (443) and redirect to HTTPS on port 80 (if port 80 is enabled).

When you meet these requirements, go to https://hstspreload.org/ and submit your domain like so:

Conclusion

HTTPS is not enough to protect the users of your web application from network attacks. And as long as there are unencrypted websites on the Internet, browser vendors cannot merely disable unencrypted connections altogether.

Luckily there is an opt-in mechanism for websites that don’t want any unencrypted connections. And that is the HSTS header.

When implementing HSTS in production, it’s best to start with a slow max-age and slowly ramp it up.

Finally, it’s possible (and highly recommended) to preload your HSTS header into the major web browser’s source code by submitting your domain to hstspreload.org. But think it through before you do so; canceling is a slow and painful process.

Comments are closed, but trackbacks and pingbacks are open.