AppSec Monkey
Hacking AcademyBlogWeb SecurityToolsAbout
Hacking Academy
NEWWe are launching a next generation e-learning platform for hackers!
HSTS (HTTP Strict Transport Security)
Teo Selenius
Follow @TeoSelenius
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: <options>
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
The user types in www.example.com
The user's browser sends an unencrypted HTTP request to http://www.example.com/
The webserver returns a redirect to https://www.example.com
The user's browser sends an encrypted HTTPS request to https://www.example.com/.
The webserver returns with the login page.
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
The attacker intercepts this unencrypted request and returns the login page from the real server. Crucially, the connection is still unencrypted.
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
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.
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
# 2 years
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
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:
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.
Are you ready to see how deep the rabbit hole goes?
ENTER HACKING ACADEMY
Video lessons by a professional application security engineer and trainer will take from from zero to hero.
Assisted labs make it easy to understand what's going on.
When you achieve the lab objective, you get a flag.
By submitting the flag on the Hacking Academy dashboard you will complete the module.
Create tools and exploits in the attacker's code editor directly in your browser.
Receive connect-backs and run hacking tools on your cloud Kali terminal also directly in your browser.
Each course module has notes with the vulnerable code and commands/code for you to exploit the vulnerability.
The labs have real bots with real browsers so you will need real client-side exploits to complete the labs!
hstswebsecurityheaders
Same Origin Policy (SOP)
CORS (Cross-Origin Resource Sharing)
mailgithubfacebookyoutubelinkedintwitter