Subject: Re: [Acme] ACME vulnerabilities in SimpleHTTP due to common webservers' default virtual host semantics

From: Peter Wu <[email-masked]>
Date: Fri, 8 Jan 2016 18:27:09 +0100

Hi Niklas, Peter and others,

(First time poster here, grabbed this mail from the archives.
Explanation of the "vulnerability" is first given, followed by a
discussion.)

On Fri, Nov 13, 2015 at 04:35:00PM +0100, Niklas Keller wrote:
> This is a followup on "ACME vulnerabilities in SimpleHTTP and DVSNI due to
> common webservers' default virtual host semantics", since I don't have that
> mail in my archive (was not subscribed to the list back then), I can't
> respond directly to that thread. (Stupid mailing lists.)

With a sane mail client, you can set the In-Reply-To header to the
Message-Id which can be found by clicking the "Show header" link in
messages at https://mailarchive.ietf.org/arch/search/?email_list=acme

For future reference, the thread starts at
https://mailarchive.ietf.org/arch/msg/acme/B9vhPSMm9tcNoPrTE_LNhnt0d8U
(it is worth reading the full thread as it is not that large).

> Could someone explain the exact vulnerability? Since those challenge
> payloads are bound to a specific domain, I don't see the problem.
> Additionally, I don't see why it's a problem with HTTPS, why is it
> mitigated by switching to HTTP? HTTP via port 80 has just the same
> semantics for default hosts as HTTPS via 443 has.

This vulnerability (as I understand) works as follows:

 0. example.com and example.net are owned by two different entities,
    hosted on the same webserver (shared webhosting).
 1.  example.com happens to be the first site on the vhost
    with a valid certificate configured.
 2. example.net is another customer on the server which has not yet
    configured HTTPS. Due to a configuration error, requests to a
    non-existing vhost now end up at the first (default) vhost, namely
    example.com.
 3. Now example.com can obtain a certificate for example.net (which
    might not be authorized for that).

This is "mitigated" by switching to HTTP because webhosting providers
presumably make websites available over http while https is an
additional feature. Shared webhosters who serve sites over just https
*and* happen to have a misconfigured server such that plain http vhosts
are handled incorrectly are probably not common.

This vulnerability is purely a configuration issue. For example, nginx
can be configured with a catch-all SSL vhost:

    server {
        listen *:443 ssl default_server;
        ssl_certificate dummy.crt;
        ssl_certificate dummy.key;
        return "No vhost configured";
    }

Apache HTTPd can also be configured to address the problem:
https://httpd.apache.org/docs/2.4/vhosts/examples.html#default

Peter (Eckersley), you reported this concern with the premise that it is
a common configuration mistake that impacts many hosting providers. Do
you have scans backing up that concern? Websites that are managed by a
single entity (i.e. not shared hosting providers) with this
configuration "mistake' are not a problem.

The restriction in the specification has an unfortunate consequence:
sites which are only accessible over port 443/HTTPS (because other ports
are blocked / not forwarded in a NAT network) can no longer be
validated.
-- 
Kind regards,
Peter Wu
https://lekensteyn.nl

---

From: Peter Eckersley <[email-masked]>
Date: Fri, 8 Jan 2016 10:23:25 -0800

> configuration "mistake' are not a problem.

I haven't spent the time to conduct a thorough scan to get numbers, but
this type of configuration is very easy and natural to create, and manually
examining the https:// responses of a handful of Alexa top 100K domains
(starting in the middle of the list, not the top) showed a tremendous
diversity of strange behaviours for domains where https:// has not been
officially deployed.

If someone wants to do a scan to try to characterise all of those
behaviours, go for it!

> are blocked / not forwarded in a NAT network) can no longer be

That's not the case.  You can use the TLS-SNI-01 challenge type on those
systems.

The current language describing it in the spec is terrible and needs to
be rewritten, but it's quite simple: add an extra :443 vhost entry to
your server config, serving a self-signed cert created to pass the
challenge.

-- 
Peter Eckersley                            [email-masked]
Chief Computer Scientist          Tel  +1 415 436 9333 x131
Electronic Frontier Foundation    Fax  +1 415 436 9993

---

From: Niklas Keller <[email-masked]>
Date: Fri, 8 Jan 2016 20:42:57 +0100

> your server config, serving a self-signed cert created to pass the

Unfortunately, this requires a server configuration reload. http-01 is
still a lot easier, it doesn't require any configuration change. I think
it's best to allow http-01 over HTTPS on port 443 if port 80 is not
reachable. This should eliminate the vulnerability, but allow verifying
HTTPS-only sites with http-01.

Best Regards,
Niklas

---

From: Peter Eckersley <[email-masked]>
Date: Fri, 8 Jan 2016 11:56:39 -0800

> HTTPS-only sites with http-01.

That's pretty corner case-y behaviour for a very specialised use case
(server *must* have port 80 firewalled, and cannot possibly perform a
graceful server reload).  Are there other voices in favour of special
casing DV behaviour for that use case?

---

From: Peter Wu <[email-masked]>
Date: Sat, 9 Jan 2016 00:56:49 +0100

> If someone wants to do a scan to try to characterise all of those

I'll give it a go. Currently thinking of a scanning sites 1k-2k from the
Alexa list, testing port 80 (host: domain, host: ip, host:
surelyinvalid.example.com and no host header), port 443 (no SNI, and SNI
with + Host header like used for port 80). Then I'll try to store a pcap
so all responses can fully be analyzed.

Are there other things that should be checked as well?

> casing DV behaviour for that use case?

Trying port 443 after port 80 is unreachable is a workaround and
probably too specific. If a configuration issue like the default vhost
is a concern, then I would like to suggest validating the subject CN or
SANs of the returned certificate even if self-signed or expired.
(This modification, but also the existing http-01 validation, seems
vulnerable to a MitM attack where the attacker controlling the network
can cause false validations, but is not the topic of this mail.)

In my last mail, I meant to say "not possible with http-01". I am using
the simp_le ACME client with Let's Encrypt and encountered this
limitation when trying it at home. The following scenarios assume that a
webserver is already running a live website.

An advantage of the http-01 method over tls-sni-01 is that a webserver
can delegate the validation by proxying the request or by pointing to a
specific directory on the filesystem. Both approaches work with an
unprivileged ACME client.

The SNI method requires that an ACME client can modify the webserver
configuration (add a new vhost + cert) and reload it. It cannot be
delegated via proxying because the server needs to parse the Client
Hello first.

In short, http-01 operates on a level below TLS and is more flexible
than tls-sni-01 and allows delegation of certificate validation.
-- 
Kind regards,
Peter Wu
https://lekensteyn.nl

---

From: Peter Eckersley <[email-masked]>
Date: Fri, 8 Jan 2016 16:13:30 -0800

> Are there other things that should be checked as well?

Sites in the top 2K almost all have significant engineering resources
available.  I'd recommend checking things down around the 100K mark as
well, you'll get more representative diversity there.

---

From: Jakub Warmuz <[email-masked]>
Date: Sat, 9 Jan 2016 13:59:44 +0000

On 8 January 2016 at 23:56, Peter Wu <[email-masked]> wrote:
> It cannot be

You could run a load balancer that proxies all requests to
*.acme.invalid to a Let's Encrypt client. There is (quite old)
tutorial on how to achieve that with HAProxy at
https://coolaj86.com/articles/lets-encrypt-with-haproxy/.

-- 
Yours virtually,
Jakub Warmuz