Subject: HSTS preload flaw

From: Rob Sayre <[email-masked]>
Date: Fri, 7 Feb 2020 17:03:18 -0800

Hi,

I reported a bug that found HSTS not present for .app, .dev and several
other TLDs in Safari on all operating systems, as well as Chrome, Firefox,
and Edge on iOS.

https://bugs.webkit.org/show_bug.cgi?id=202925 [perhaps still private]

Google made the issue public about a month ago without asking me:
https://bugs.chromium.org/p/chromium/issues/detail?id=1013612#c44

A commenter on the Chromium bug maintains that this issue is not a bug.
However, this issue was responsibly reported, and fixed in iOS 13.3 and
contemporaneous releases on other operating systems:

https://developer.apple.com/documentation/ios_ipados_release_notes/ios_ipados_13_3_release_notes

It wasn't exactly a clever exploit (I noticed a .app domain that shouldn't
have loaded over http), but perhaps there should be more careful monitoring
of HSTS preload lists. At least 600k domains were impacted.

thanks,
Rob

---

From: Austin Wright <[email-masked]>
Date: Sun, 9 Feb 2020 01:05:49 -0700

I don’t think you can call this a bug. As far as I know, this behavior is not standardized as any part of HTTP, but is described and centrally managed by Chromium project. That is, it’s a feature of Google Chrome and nobody else is under any obligation to implement it.

And even if it was, I don’t really see how you can say “At least 600k domains were impacted”. What would an attack look like? You have to have a user-agent willing to send a sensitive payload in plaintext, and a server with port 80 open to receive it.

Austin Wright.

> On Feb 7, 2020, at 18:03, Rob Sayre <[email-masked]> wrote:
> 
> Hi,
> 
> I reported a bug that found HSTS not present for .app, .dev and several other TLDs in Safari on all operating systems, as well as Chrome, Firefox, and Edge on iOS.
> 
> https://bugs.webkit.org/show_bug.cgi?id=202925 <https://bugs.webkit.org/show_bug.cgi?id=202925> [perhaps still private]
> 
> https://bugs.chromium.org/p/chromium/issues/detail?id=1013612#c44 <https://bugs.chromium.org/p/chromium/issues/detail?id=1013612#c44>
> 
> A commenter on the Chromium bug maintains that this issue is not a bug. However, this issue was responsibly reported, and fixed in iOS 13.3 and contemporaneous releases on other operating systems:
> 
> https://developer.apple.com/documentation/ios_ipados_release_notes/ios_ipados_13_3_release_notes <https://developer.apple.com/documentation/ios_ipados_release_notes/ios_ipados_13_3_release_notes>
> 
> It wasn't exactly a clever exploit (I noticed a .app domain that shouldn't have loaded over http), but perhaps there should be more careful monitoring of HSTS preload lists. At least 600k domains were impacted.
> 
> thanks,
> Rob
>

---

From: Rob Sayre <[email-masked]>
Date: Sun, 9 Feb 2020 01:30:46 -0800

On Sun, Feb 9, 2020 at 12:05 AM Austin Wright <[email-masked]> wrote:

> I don’t think you can call this a bug.
>

I think it's a bug, but reasonable people can disagree. An "unintentional
difference in behavior" is another way to describe this report.

> As far as I know, this behavior is not standardized as any part of HTTP,
> but is described and centrally managed by Chromium project. That is, it’s a
> feature of Google Chrome and nobody else is under any obligation to
> implement it.
>

HSTS is defined by RFC 6797. It's true that the preload list can vary
between versions of browsers, but in this case I found that the macOS
versions of browsers other than Safari had these TLDs preloaded, while the
iOS versions of these browsers did not. I understand why this happened, but
I think it would be a stretch to call it intentional. The discrepancy
existed for over a year, and no browser vendor seemed aware of it.

> And even if it was, I don’t really see how you can say “At least 600k
> domains were impacted”. What would an attack look like? You have to have a
> user-agent willing to send a sensitive payload in plaintext, and a server
> with port 80 open to receive it.
>

600k is a conservative estimate based on the number of domains that seemed
to be registered under these TLDs. Any browser without these TLDs preloaded
would first attempt to connect via HTTP if supplied with an http:// URL or
a schemeless URL (like "foo.dev").  At that point, any server could provide
a response. You might think "surely there will be a scary warning", but
this actually was not the case in all browsers, especially on mobile
phones. Safari did say "Not Secure" in the address bar, but other browsers
just showed an "(i)" info icon instead of a lock, so a user would have to
notice the absence of a lock.

thanks,
Rob

---

From: Austin Wright <[email-masked]>
Date: Sun, 9 Feb 2020 16:47:46 -0700

> On Feb 9, 2020, at 02:30, Rob Sayre <[email-masked]> wrote:
> 
> On Sun, Feb 9, 2020 at 12:05 AM Austin Wright <[email-masked] <mailto:[email-masked]>> wrote:
> I think it's a bug, but reasonable people can disagree. An "unintentional difference in behavior" is another way to describe this report.

A difference in behavior is fair to point out, and I’d even agree people might assume all user agents will have the same HSTS behavior; but I think the best we can do is point out that HSTS is optional to implement; so if a user agent is missing this feature, that should be reported as a feature request, not as a bug.

If encrypted connections are important to you as a server operator, it seems the only foolproof way to avoid plaintext communication is don’t listen on port 80.

>  
> As far as I know, this behavior is not standardized as any part of HTTP, but is described and centrally managed by Chromium project. That is, it’s a feature of Google Chrome and nobody else is under any obligation to implement it.
> 
> HSTS is defined by RFC 6797. It's true that the preload list can vary between versions of browsers, but in this case I found that the macOS versions of browsers other than Safari had these TLDs preloaded, while the iOS versions of these browsers did not. I understand why this happened, but I think it would be a stretch to call it intentional. The discrepancy existed for over a year, and no browser vendor seemed aware of it.

The preload list isn’t a part of RFC 6797, which is itself optional to implement.

> 600k is a conservative estimate based on the number of domains that seemed to be registered under these TLDs. Any browser without these TLDs preloaded would first attempt to connect via HTTP if supplied with an http:// URL or a schemeless URL (like "foo.dev <http://foo.dev/>").  At that point, any server could provide a response. You might think "surely there will be a scary warning", but this actually was not the case in all browsers, especially on mobile phones. Safari did say "Not Secure" in the address bar, but other browsers just showed an "(i)" info icon instead of a lock, so a user would have to notice the absence of a lock.

Note that even TLS will indicate which domain you’re connecting to. If server operators make diligent use of HttpOnly and Secure for cookies, the only information at risk is the path component of the URI you’re connecting to, your user-agent details, and maybe a payload (if you can figure out a way to get an HTML form to POST to an http: endpoint without a warning).

But I agree I’d like to see better privacy designed into first-time connections. I know the HTTP WG is working on a new DNS record specifying connection requirements. Unfortunately it seems this new scheme would also be optional, and probably not widely implemented for some time.

Personally, I would like to see a new “web:” scheme that mandates usage of SRV, or the proposed HTTP service record, whatever it ends up being named… this new URI scheme would effectively require that clients understand the security requirements before connecting. People pointed out this would be a barrier to adoption; but for some applications, this is entirely the point.

Cheers,

Austin.

---

From: Rob Sayre <[email-masked]>
Date: Sun, 9 Feb 2020 16:46:37 -0800

Hi,

> The preload list isn’t a part of RFC 6797, which is itself optional to

Well, the contents of the list itself are not part of the RFC, so it is
possible to spec-lawyer one's way into saying this isn't a bug (and maybe
that's reasonable).

This topic is covered in RFC 6797, though. See "12.3.  HSTS Pre-Loaded
List" https://tools.ietf.org/html/rfc6797#section-12.3

That section discusses "the bootstrap MITM vulnerability" at hand here. A
second problem with these TLDs is that they were marketed with their
presence in the HSTS pre-load list as a benefit, but not even the owner of
these TLDs got this HSTS pre-load implemented in all of their products.

> would first attempt to connect via HTTP if supplied with an http:// URL
> or a schemeless URL (like "foo.dev").  At that point, any server could
> provide a response. You might think "surely there will be a scary warning",
> but this actually was not the case in all browsers, especially on mobile
> Note that even TLS will indicate which domain you’re connecting to. If
> server operators make diligent use of HttpOnly and Secure for cookies, the
> only information at risk is the path component of the URI you’re connecting
> to, your user-agent details, and maybe a payload (if you can figure out a
> way to get an HTML form to POST to an http: endpoint without a warning).
>

I don't agree with this analysis. There are several ways to escalate this
attack once you get the user to load a single HTTP page without realizing
they've been mislead. If they're using an app, they probably won't get any
indication there's a problem. Ultimately, I'm glad this behavior was
improved in iOS, macOS, tvOS, watchOS, and for many apps running on them.
As in the top post, I hope we can start automating HSTS list checks using
continuous integration or telemetry.

thanks,
Rob

---

From: Eric Mill <[email-masked]>
Date: Sun, 9 Feb 2020 22:19:50 -0500

On Sun, Feb 9, 2020 at 6:51 PM Austin Wright <[email-masked]> wrote:

> If encrypted connections are important to you as a server operator, it
> seems the only foolproof way to avoid plaintext communication is don’t
> listen on port 80.
>

Without getting into the overall issue, I just want to note for readers of
the thread - server operators can't avoid plaintext communication by
clients by not listening on port 80. Clients can attempt to initiate a
connection to a hostname over port 80 whether or not the "real" server is
listening on port 80, and that connection can be interfered with by a
malicious network actor. That's why HSTS exists - to provide some kind of
signal to the client that they should never bother even trying to make that
connection.

---

From: Austin William Wright <[email-masked]>
Date: Sun, 9 Feb 2020 23:28:42 -0700

On Feb 9, 2020, at 20:19, Eric Mill <[email-masked]> wrote:
> 
> On Sun, Feb 9, 2020 at 6:51 PM Austin Wright <[email-masked] <mailto:[email-masked]>> wrote:
> Without getting into the overall issue, I just want to note for readers of the thread - server operators can't avoid plaintext communication by clients by not listening on port 80. Clients can attempt to initiate a connection to a hostname over port 80 whether or not the "real" server is listening on port 80, and that connection can be interfered with by a malicious network actor. That's why HSTS exists - to provide some kind of signal to the client that they should never bother even trying to make that connection.
>  

This is correct, thanks for the correction. I should have noted this. Also, note how HSTS applies to all connections to a hostname, regardless of port number.

In an active (MITM) attack, the server operator doesn’t even have to be online, of course; the attacker will receive all connections to the intended host.

My comment is with regards to passive attacks where a server operator wants to avoid inadvertently accepting plaintext data: A Permanent Redirect would still allow the headers to be sent to the server (and the request body, if the client doesn’t follow 100-continue).

It seems to me if an attacker can get a victim to compose a sensitive request, but direct that request to an attacker-controlled scheme and port, why not an attacker-controlled host too, or any host not on an HSTS Preload list?

Austin.

---

From: Rob Sayre <[email-masked]>
Date: Sun, 9 Feb 2020 22:58:08 -0800

On Sun, Feb 9, 2020 at 10:28 PM Austin William Wright <[email-masked]> wrote:

>
> It seems to me if an attacker can get a victim to compose a sensitive
> request, but direct that request to an attacker-controlled scheme and port,
> why not an attacker-controlled host too, or any host not on an HSTS Preload
> list?
>

That's a fair question. Intercepting a single unencrypted innocuous request
is a viable way to get the victim to compose requests to
attacker-controlled servers over TLS. These hosts might not be legitimate,
but users won't always notice a discrepancy in domain names. Here is a toy
attack:

Serve a search engine UI, but pop up an "Accept Cookies" UI that is
seemingly intended to comply with privacy regulations. In response to a
click on any choice presented, redirect to an attack-controlled domain
(that might be served over TLS, with a misleading domain name).

thanks,
Rob