If I already have done a 301 redirection from all the HTTP inner pages to HTTPS, why should I use HSTS as well?
Let's look at the scenario with a 301 redirect first. The victim sends a request to
http://example.com (as pointed out in comments, this could because of SSLStrip or because the user just entered
example.com in the URL bar and browsers default to HTTP). If there is no MitM attack they get a 301 response back, and is redirected to
https://example.com. But if there is a MitM, the attacker can just choose not to send the 301, but instead serve a (possibly modified) copy of the site over HTTP.
The weak point here is that an initial HTTP connection (without TLS) is made, and the attacker can modify that traffic. However, if you had used HSTS the browser would know (assuming that the victim had visited the site previously) that the page should always be served over HTTPS - no HTTP request would ever have been sent, and the browser would just send a request to
https://example.com. The attacker cannot MitM the TLS connection, so the attack is prevented.
(The fact that browsers cache 301 responses makes this a bit more complicated in practise. For more info on that, see bonsaiviking's great answer or this question. The short story is that the 301 being cached might help a bit, but not take you all the way that HSTS does.)
HTTP Strict Transport Security (HSTS) is designed for security. HTTP 301 Moved Permanently is used for URL redirection.
The 301 redirect is an important part of deploying an HTTPS website. As part of the HTTP protocol, it is supported by more browsers than HSTS. It serves as the primary means for upgrading a plaintext connection to HTTPS, updating search indexes, and avoiding link rot.
In many cases, these two methods have the same weakness: the initial request when the user types "example.com" in their browser is sent plaintext. If that initial request is made on a hostile network with an active man-in-the-middle (MITM), the response can be intercepted and the connection will not be upgraded to a secure one.
However, there are many reasons why HSTS is important and a big security improvement over a standard 301 redirect:
- HSTS covers the entire domain. A 301 redirect only covers a specific URI path. If a user is redirected for
example.com/, then a later request to
example.com/somepagewill still use HTTP initially, and must be redirected again. A site using HSTS requires only one request to cover the entire site.
- HSTS works even with an initial HTTPS connection. A 301 redirect only maps a plaintext URI to a HTTPS one, so visiting the HTTPS one directly confers no protection to subsequent visits.
- HSTS uses a separate cache with a separate timeout. The 301 cache is often tied to the browser's request cache, which is designed for performance. If you don't visit a page for a while, it will probably be cleared out of the cache to favor more-frequently-visited sites. There may even be a max-age for this cache that is a few weeks or months. A common fix for "site does not work" is telling the user "clear your cache." All of these would re-expose the user to the MITM threat. HSTS timeouts are usually on the order of months to years, and the cache is usually separate, so it cannot be easily or accidentally cleared.
- HSTS can be preloaded into a browser by the manufacturer. Google does this with their Chrome browser based on headers discovered during web crawling and submitted directly to their program. For preloaded sites, the browser will never need to visit via plaintext in the first place; it can always be assumed to be HTTPS-only.
First of all, some old browsers don't support HSTS, so you still need to redirect HTTP to HTTPS, set the
secure flag on all cookies, etc. Now, with that said...
In addition to the fine reasons listed above, since defeating SSLStrip-type attacks is one of the main purposes of HSTS, there's another attack that HSTS protects against but simple redirects do not.
Let's say a site is being visited entirely on HTTPS. The user is really careful, and only ever requests this site over HTTPS. No redirect needed. There's no HSTS, but there's not any links to the site over unsecured HTTP either, so all traffic with the site is encrypted.
However, suppose the site has a security vulnerability where it reflects a specific cookie (if present) into the page without proper escaping (cookie-based XSS, rare but hardly unheard-of). The attacker can't actually read (much less modify) the HTTPS traffic, but they really want to access the user's session on that HTTPS site. So, they wait for the user to visit some other site over HTTP, and modify the response from that site to include an invisible request (maybe a script src) to
http://securesite.com/ (your HTTPS-only site, but over HTTP instead). What happens next:
- If the site has an active HSTS policy in the browser, then the browser automatically re-writes the request as
https://securesite.com/and the attacker can't read or modify any traffic.
- If the attacker doesn't tamper but the site has no HSTS, then the request goes out, gets a 301 to
https://securesite.com/, and the request goes out again via HTTPS.
- However, any cookies for securesite.com but without the
secureflag on them will be included with that initial unsecure request. The attacker can read them even just via passive eavesdropping at that point. That's bad (and this is a reason why sensitive cookies must always have the
secureflag even if the site shouldn't ever be accessed over an insecure connection).
- However, any cookies for securesite.com but without the
- If all the cookies are
secure, though, that makes this attack pointless. The attacker will have to tamper again. They can forge or modify the response to the insecure request. In this particular case, the attacker would add a
Set-Cookieheader to the response, putting a cookie in the user's browser that will be sent on future requests to securesite.com, over either HTTP or HTTPS.
With the hypothesized cookie-based XSS vector (or anything else where a cookie-planting attack can do harm), the attacker has successfully attacked a site that the user was very careful to only access over HTTPS, just because it wasn't using HSTS and had a vulnerability that would be impossible to exploit without an unsecured connection.
The key thing to note is that the Same Origin Policy for cookies is more lax than the Same Origin Policy elsewhere. That is, there is not a single secure channel for cookies, they are the same origin:
Client ----Plain HTTP----> Server Client ---------HTTPS----> Server
Of course the Secure Flag can be set so a cookie value can be set to only transfer over HTTPS.
Set-Cookie: foo=bar; secure
Client --> HTTP (no cookies) --> Server Client --> HTTPS (Cookie: foo=bar) --> Server
However, there is no way for the server to know whether a cookie was set with the Secure Flag.
e.g. over plain HTTP
Client --> HTTPS (Cookie: foo=bar) --> Server
The server will be in this situation:
So although cookies set by the server over HTTPS are not sniffable, a MITM can inject their own values into a "secure" session. This is true even if you have no plain HTTP service:
Client ----Plain HTTP----> No service Client ---------HTTPS----> Server
...because a MITM can still generate a plain HTTP request to your domain and inject the cookie:
Client ----Plain HTTP----> MITM --> No service Client ---------HTTPS-------------> Server
This can lead to some attacks should your site have some vulnerabilities that might not otherwise be able to be exploited:
- Session fixation: How can non-secure or non-HTTP-only cookie affect security of an HSTS website?
- XSS cookie poisoning: Flash cookie and man-in-the-middle
As well as the above, ssltrip style attacks can be carried out without HSTS. sslstrip relies to a degree on the user not noticing their is no HTTPS.
Also see this answer.
HSTS uses a sandboxed client side 307 redirect, so it does not even hit the server until it's in explicit https mode. A 301 redirect on the other hand is server side, takes resources, time to complete, etc. Also, a 301 stacks up your [chained] redirect count, which is generally attributed to SEO dilution.
So HSTS is generally the better choice due to its client side + sandboxed nature. But, there is a "danger" to it with a very long TTL on cache. When an SSL expires or if you want to go back http mode users will be locked out. This is because the cached HSTS TTL is/will only look for https, but browsers will nogo sites with an expired cert. So don't ever let it expire or switch modes without setting HSTS cache time to 0 in the weeks (or months) before the change :) You don't have to worry about this with 301 since it's not the browser making the decision to redirect or not -- people won't get locked out if you make the change server side.
Since HSTS still requires a redirection the first time each user visits your website (unless we are so sure of no errors that irreversible preloading via registration can be dared), this is a trick question. There essentially is no difference between using the HSTS header and using a redirection header.
The only good solution I can think of is adding a record type or flag to each DNS zone record to specify "this domain supports HTTPS". Then there is no need for HSTS or redirection. The browser already knows that https is supoorted (from its DNS lookup), so it can (unless overruled by the user) rewrite the user's http to https before it even sends the first request to the remote server.