69

If I already have done a 301 redirection from all the HTTP inner pages to HTTPS, why should I use HSTS as well?

Anders
  • 64,406
  • 24
  • 178
  • 215
Franzech Domâs
  • 975
  • 1
  • 8
  • 10

6 Answers6

71

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.)

Anders
  • 64,406
  • 24
  • 178
  • 215
  • 14
    It would be worth mentioning that `sslstrip` helps exploit exactly these kind of attacks. – sandyp Jul 05 '16 at 23:23
  • Popular browsers (at least [Firefox](https://blog.mozilla.org/security/2012/11/01/preloading-hsts/) and Chrome) have been preloading lists of HSTS hosts since at least 2012, so having to visit the page first should only be necessary on new sites (and that one site which blocks all indexing). – l0b0 Jul 06 '16 at 06:50
  • 6
    @l0b0 You are only preloaded if you (a) set the preload flag, and (b) apply for it. A minority of HSTS sites are preloaded, so for most sites you need to visit it. – Anders Jul 06 '16 at 07:38
  • What distinguishes 301 from HSTS the most is precisely the preloading. With it, there's no need for an insecure first connection. Without it, both are equally vulnerable to sslstrip (HSTS needs a more "customized" sslstrip, but it's possible nonetheless). Cache deletion may be also a factor, though (perhaps 301 is forgotten but HSTS is not?). – Valmiky Arquissandas Jul 06 '16 at 13:12
  • 5
    @ValmikyArquissandas I disagree. A majority of HSTS sites does not use preloading, and they get a significant advantage anyway. Unlike HSTS posts, a 301 is not guaranteed to be cached for any extended time, it only covers a specific page and not a full domain, and it is lost if the user purges the cache. – Anders Jul 06 '16 at 13:15
  • To rephrase @SandeepY: the most simple MitM attack that can be performed is to pretend the website does not support HTTPS, and keep unencrypted session on – usr-local-ΕΨΗΕΛΩΝ Jul 07 '16 at 15:38
  • 1
    @Anders: you are obviously correct, and my answer is wrong. I don't know how I forgot that 301 acts on a single page only, and not over the domain - I must've mixed them up. – Valmiky Arquissandas Jul 08 '16 at 10:04
  • Preloading is a primitive operation. You must preload for a year or more, and "be aware that inclusion in the preload list cannot easily be undone," according to the registration tool. Therefore, if there is ANY chance of an error, it is prudent NOT to preload, at least for awhile. During that time your website is wide open for MiTM attacks by each first request by each visitor (to find the HSTS header). The problem is that redirection triggers a new full access. Since there is no DNS zone flag to say that https is supported, there is no good solution. HSTS fails. – David Spector Dec 27 '19 at 19:28
  • 1
    @DavidSpector You are wrong, as was pointed out to you in both your (incorrect) answer to this question and in your other question. – Joseph Sible-Reinstate Monica Dec 27 '19 at 21:01
48

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/somepage will 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.
bonsaiviking
  • 11,316
  • 1
  • 27
  • 50
  • 2
    A "separate cache" that still needs to be purged when the user request anonymity, so still a half backed solution – curiousguy Jun 20 '18 at 22:38
12

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 secure flag 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 secure flag even if the site shouldn't ever be accessed over an insecure connection).
  • 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-Cookie header 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.

schroeder
  • 123,438
  • 55
  • 284
  • 319
CBHacking
  • 40,303
  • 3
  • 74
  • 98
  • Regarding old browsers. It is controversial if a *site* does or doesn't need a 301. I guess that's rather ultimately *users* who are responsible to type `https:` prefix if they insist on using unsupported browser. It's a business decision if you want to sacrifice some security and comfort that user base. – kubanczyk Jul 06 '16 at 11:40
  • 5
    Wait, how and where is this controversial? **If you use HSTS, you *absolutely* need to include the 3xx redirect as well!** You can't even send an HSTS header over HTTP (at least, no conforming client will respect it, with good reason), nor can you preload HSTS if you respond over HTTP with anything but a redirect. Anywhere that this entire question is even slightly relevant, the use of the redirect is mandatory. – CBHacking Jul 06 '16 at 18:00
  • The redirect isn't really needed for new browsers, but recommended for simplicity and for browsers that do not support HSTS. All that's needed to enable HSTS is a single resource loaded over HTTPS that includes the header. It could be as simple as an absolute URL reference (e.g. ``). – SilverlightFox Jul 08 '16 at 10:57
  • @SilverlightFox: Doing that will still make the root page itself load over HTTP on that initial request, which may reveal some user content and also causes a bad user experience (possibly making the user think that the site is operating fully over HTTP). It will also make your site ineligible for the HSTS preload list (requirement #2 at https://hstspreload.appspot.com/) – CBHacking Jul 08 '16 at 20:11
7

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.

e.g.

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

Set-Cookie: foo=bar

Client --> HTTPS (Cookie: foo=bar) --> Server

The server will be in this situation:

Fry

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:

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.

SilverlightFox
  • 33,408
  • 6
  • 67
  • 178
-1

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.

dhaupin
  • 161
  • 1
  • 7
  • 2
    Browsers cache 301 responses, so you might look out users with those if you disable HTTPS: – Anders Jul 06 '16 at 16:51
  • It is true that HSTS itself is secure. But if the user is accessing with http, and the site is not preloaded, there is no way to discover the HSTS header without redirection from http to https. In other words, once an http request is made, MiTM is possible. The trick is to avoid making ANY http requests, unless the link in an old one, the website is for a household appliance, etc. One solution is to add a new feature to DNS zone records to say, "this domain supports https". – David Spector Dec 27 '19 at 19:44
  • @DavidSpector For the umpteenth time, "and the site is not preloaded" So preload then. – Joseph Sible-Reinstate Monica Dec 27 '19 at 21:31
  • @DavidSpector HSTS is a backup client-side enforcement mechanism. It's not a replacement for server-level mechanisms...it's an addition. If your server/app/site is set to enforce `https` mode always and everywhere, it will never serve a `http` request back to begin with. You can do this right at the nginx/apache level. A visitor could never get to a `http` page, an insecure session would never be generated, insecure cookies wouldn't be used, etc. Wouldn't matter when they see the HSTS header then, as one wouldn't be relying on it, per-say. – dhaupin Dec 31 '19 at 20:52
  • @JosephSible-ReinstateMonica it helps to add that flag for sure, but the preload list in browsers is still used. So if you have the flag, but your domain isn't on that list, it won't preload. You can submit your domain here: https://hstspreload.org/. I dunno if or how long it takes to get added :) – dhaupin Dec 31 '19 at 20:56
  • @dhaupin No, HSTS is the primary mechanism. Nothing the server does can actually enforce HTTPS, since sslstrip can just undo whatever it does unless the client know to use HTTPS from the beginning (which is exactly the point of HSTS). And nothing in my comment suggested that the header was enough; I meant adding it to the list too. – Joseph Sible-Reinstate Monica Dec 31 '19 at 21:23
  • @JosephSible-ReinstateMonica https://github.com/LeonardoNve/sslstrip2 -- apparently no `https` is safe, so what's the point of using any of it ;) Just kidding. The use cases are limited, and 99.9999% of users will benefit from both modes. – dhaupin Jan 01 '20 at 06:12
  • @dhaupin [That tool doesn't actually work](https://security.stackexchange.com/a/91096/127145). – Joseph Sible-Reinstate Monica Jan 01 '20 at 06:21
  • @JosephSible-ReinstateMonica Haha I hear ya. Neither do a bunch of others, but the point is HSTS wll be tampered with and injected upon at some point. I'm all about it, but HSTS is a weak proto supported by application modes (IMO), headers can be ignored/stripped, there are a billion vectors now in addition. I actually agree with threads above for a zone flag, but then again, that could be ignored/intercepted/stripped too. Happy new year man, we could go on for ages about this. – dhaupin Jan 01 '20 at 06:43
  • The point of preloading is that you become immune to all such tampering by doing that. – Joseph Sible-Reinstate Monica Jan 01 '20 at 06:44
  • @JosephSible-ReinstateMonica ......you forgot to mention, all such tampering of *browser* traffic. But that goes back to my comment about how you have to be accepted to the preload list. Do you think they are going to add every tiny site on the nets? You have to be a pretty big deal to get into that list, else they distro a 5+gb text file full of BS. I tried a few times to get onto that list for some rather large domains....years later, still not there. `preload` doesn't affect like 99.9999% of sites. You bring up good points though. – dhaupin Jan 01 '20 at 06:59
  • @dhaupin I suspect something was wrong with your TLS configuration then. They will let every tiny site in. – Joseph Sible-Reinstate Monica Jan 01 '20 at 07:02
  • Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/102751/discussion-between-dhaupin-and-joseph-sible-reinstate-monica). – dhaupin Jan 01 '20 at 07:08
-3

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.

  • This is incorrect. A 301 redirect only affects the specific URL that you hit it on, but HSTS affects the entire domain. And you're also making preloading sound much worse than it actually is. – Joseph Sible-Reinstate Monica Dec 27 '19 at 20:55
  • 1
    This is not a "trick question". You have not properly represented what happens in HSTS. Also, the question is from the server-side. You are proposing an entirely new protocol. – schroeder Dec 27 '19 at 22:04
  • HTTPS Everywhere (https://www.eff.org/https-everywhere) does what you want client-side. – schroeder Dec 27 '19 at 22:06