caddyserver / caddy

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
https://caddyserver.com
Apache License 2.0
56.07k stars 3.94k forks source link

Caddy serves wrong SSL cert for site that is not served on HTTPS port #1303

Closed mxlje closed 6 years ago

mxlje commented 7 years ago

1. What version of Caddy are you running (caddy -version)?

Caddy 0.9.3

2. What are you trying to do?

I want to have multiple virtual hosts, some https, some http only. I want the http only hosts to not respond to https requests with a wrong certificate.

3. What is your entire Caddyfile?

https://foo.example.com {
  tls self_signed
  root /html/foo
}

http://bar.example.com {
  tls off
  root /html/bar
}

4. How did you run Caddy (give the full command and describe the execution environment)?

I created the reproducible example from above on my Mac (10.11.6) but I am having this problem in production on Ubuntu 16.04.1 LTS so I don’t think it is OS related. The working directory contains the Caddyfile from above.

$ sudo caddy

5. What did you expect to see?

Caddy starts fine and serves both vhosts, one with https and the other with http. I expect Caddy to not respond at all when I try to access https://bar.example.com as that virtual hosts is explicitly configured as http, not https.

6. What did you see instead (give full error messages and/or log)?

When accessing https://bar.example.com (the host which is explicitly http), Caddy sends the cert for foo.example.com, which results in an SSL error. (I know that in this example it always results in an error because the cert is self signed, but in production this would serve a trusted cert from Let’s Encrypt).

When ignoring the warning, Caddy responds with No such site at :443. While this is technically correct, Caddy should not accept the connection in the first place.

In addition to the SSL error, this also leaks information about at least one other site (the one Caddy takes the certificate from) that is set up on the host.

7. How can someone who is starting from scratch reproduce this behavior as minimally as possible?

  1. Use the Caddyfile from step 3.
  2. Update the root directive so that Caddy finds some files to serve
  3. Edit your /etc/hosts to include the following
  4. Start Caddy as described in step 4.
# /etc/hosts
127.0.0.1 foo.example.com
127.0.0.1 bar.example.com

Thanks so much for any responses. I’m sorry if there is already an issue for this or if this is a known bug, I couldn’t find anything related to this.

wendigo commented 7 years ago

I don't think it's entirely and elegantly possible.

Check comments https://github.com/golang/go/blob/a9ce0f96e1f2ab69ce3319c5a97c1d01beb9472c/src/crypto/tls/common.go#L369, https://github.com/golang/go/blob/a9ce0f96e1f2ab69ce3319c5a97c1d01beb9472c/src/crypto/tls/common.go#L360 and https://github.com/golang/go/blob/a9ce0f96e1f2ab69ce3319c5a97c1d01beb9472c/src/crypto/tls/common.go#L352

wendigo commented 7 years ago

If I read source code properly when error is returned from GetCertificate TLS Alert will be send over the wire (I'm not really sure how browsers handle this)

wendigo commented 7 years ago

Ok, so the certCache[""] (https://github.com/mholt/caddy/blob/master/caddytls/certificates.go#L234 aka default certificate for unmatched SNI challenge) was added by @mholt in https://github.com/mholt/caddy/commit/d05f8929. I think it can be removed and then browser will receive TLS alert resulting in:

This site can’t provide a secure connection

bar.example.com sent an invalid response.
Try running Network Diagnostics.
ERR_SSL_PROTOCOL_ERROR

but I don't fully understand rationale behind adding default cert.

mholt commented 7 years ago

@mxlje

Caddy starts fine and serves both vhosts, one with https and the other with http. I expect Caddy to not respond at all when I try to access https://bar.example.com as that virtual hosts is explicitly configured as http, not https.

That's how the Web works. Port 443 is open. The only TLS cert you have is for a different domain, and like other web servers, Caddy will serve that up as the "default" certificate. You can't close 443 to just one hostname, it's either open or it's not.

wendigo commented 7 years ago

@mholt I agree but instead of serving invalid certificate (not matching hostname) we can issue TLS alert (by returning error) in GetConfig which will result in:

http://i.imgur.com/znLrRmb.jpg

wendigo commented 7 years ago
t=221131 [st=1]        SSL_HANDSHAKE_ERROR
                       --> error_lib = 16
                       --> error_reason = 1080
                       --> file = "../../third_party/boringssl/src/ssl/tls_record.c"
                       --> line = 463
                       --> net_error = -107 (ERR_SSL_PROTOCOL_ERROR)
                       --> ssl_error = 1
mholt commented 7 years ago

You're right, we could do that. However, the current behavior allows the client to choose whether it wants to continue making the connection, rather than the server forcing it one way or the other. A client may just want encryption even if it's not the right hostname (can be a bad idea, but if all you need is content integrity, then it works). Or a client can choose to be strict about it (like browsers typically do). I believe nginx follows this logic as well, and it seems reasonable to give the client that choice (unless I am missing something).

mholt commented 7 years ago

In talking with others about this, this situation is similar to the "no such site" error that Caddy gives when you try to access a site (over HTTP) that it does not serve, but still has port 80 open and so it still responds to the request. Caddy has been mimicking the behavior of other web servers (nginx) by serving a default certificate, but maybe we should not respond with any certificate instead.

We could go either way on this. Leave it up to the client (what we do now), or have tighter requirements of the server operator (what is being proposed).

If we do change Caddy to send a TLS alert rather than a default certificate, any TLS errors a browser shows will be more likely due to an actual attack rather than the server just trying to be helpful.

wendigo commented 7 years ago

I would never say to non-technical person "you just have to click Advanced and then 'Proceed to unsafe location'" as it's just teaching risky and generally bad behaviour :) I understand need for generating self-signed certificates (by developers) which is ok but presenting bad certificate to "mortals" is unjustified imo.

Maybe this kind of behaviour can be configurable? Like:

tls {
 certificate_fallback yes;
}
mholt commented 7 years ago

Okay, so we switch the default behavior to a TLS alert, but with the option to present a default certificate that can be enabled from the Caddyfile. All in favor?

(One problem with this: the presence of the tls directive will enable TLS unless tls off is used... we'd need to figure out how to handle this before continuing.)

wendigo commented 7 years ago
tls off {
   certificate_fallback [yes/no]
}

?

or

tls off without_fallback
estark37 commented 7 years ago

A note about Chrome: when Chrome encounters a certificate name mismatch error for example.com, with a certificate that is valid for www.example.com, it'll redirect the user to www.example.com (and vice versa). Changing to a TLS alert would stop this heuristic from working for Caddy servers. Nevertheless, I think a TLS alert is the right way to go: as @mholt said, certificate errors should signal attacks, not server misconfigurations.

Chrome's www redirect heuristic only kicks in for a small percentage of name mismatch errors, so I don't expect this would cause a huge increase in the number of errors that users see.

(Plus, maybe there's some way we can adapt the heuristic so that we do the redirect to www.example.com if connecting to example.com results in the TLS alert.)

mxlje commented 7 years ago

@wendigo thanks for digging into the code with a few explanations and thank you @mholt for stepping in and starting a discussion about this.

@mholt:

Okay, so we switch the default behavior to a TLS alert, but with the option to present a default certificate that can be enabled from the Caddyfile. All in favor?

I’m in favor of this. Asking for https on a domain when there is no valid certificate available for that name should result in a TLS error.

@estark37:

A note about Chrome: when Chrome encounters a certificate name mismatch error for example.com, with a certificate that is valid for www.example.com, it'll redirect the user to www.example.com (and vice versa). Changing to a TLS alert would stop this heuristic from working for Caddy servers.

Good point. But: This would only work in the case where I have https://www.example.com and http://example.com. As soon as I add in a third virtual host like https://foo.com, there is the possibility (depending on the order in the Caddyfile maybe?) of serving the foo.com cert for requests to https://example.com, which then Chrome wouldn’t redirect anyways, no?

Also users can implement the redirect to www explicitly, with ssl:

example.com {
  redir https://www.example.com{uri}
}

This will default to getting a certificate for example.com so the handshake works without errors and the user will be redirected to the www subdomain.

I would be happy to help with the implementation in any way I can.

wendigo commented 7 years ago

@mholt I think that "certificate fallback" should be added globally (per server, not per vhost). WDYT?

estark37 commented 7 years ago

Good point. But: This would only work in the case where I have https://www.example.com and http://example.com. As soon as I add in a third virtual host like https://foo.com, there is the possibility (depending on the order in the Caddyfile maybe?) of serving the foo.com cert for requests to https://example.com, which then Chrome wouldn’t redirect anyways, no?

Right, the redirect is only to www.example.com if the requested hostname was example.com and the cert is valid for www.example.com, or vice versa. It doesn't apply for any other types of name mismatches. I agree that the right way for servers to handle this is to explicitly redirect to www.example.com.

mholt commented 7 years ago

Thanks for your input @estark37! Happy new year.

I'm going to hold out on any changes in Caddy for now, until Go 1.8 lands. The crypto/tls package is getting a few boosts that could be useful in handling this issue more effectively.

mholt commented 7 years ago

Recent commits now bring Caddy up to date with Go 1.8 (mostly) and we can now revisit this issue. See #1466 - once this is merged I think we can revisit how to handle the GetCertificate issue (even though that PR now raises a similar question for getting a TLS config to handle the TLS handshake!).

tinwasp commented 7 years ago

I have noticed a similar and likely related issue: the way things currently are, my caddy server volunteers free information to anyone accessing it through its (current, dynamic) ip by presenting a certificate for one of its subdomains. I'd rather have anyone scanning random ip addresses work a bit harder for that information.

mholt commented 7 years ago

@tinwasp Thanks for your feedback -- I'm looking at changing this. May not happen this month, but it's on our list (the issue is open)!

mholt commented 6 years ago

Going to wait and see how Go handles the linked issue before we take action on this.

mholt commented 6 years ago

FYI: I'm currently in the process of doing some upgrades to Caddy's TLS package.

Once these changes land, I expect that:

if all goes well.

Zenexer commented 6 years ago

@mholt This appears to be an information disclosure vulnerability, as it allows enumeration of all SSL/TLS certificates. It doesn't appear to be patched in latest stable. It may be worth revisiting this issue to ensure that it's resolved.

ghoeffner commented 6 years ago

Yeah, whenever you have multiple domains setup in caddy and you access https://:443 you will get a different certificate every time. This exposes all websites on the host that have SSL enabled

tobya commented 6 years ago

@ghoeffner would you mind opening an seperate issue for the problem you described?

Zenexer commented 5 years ago

@tobya Just to clarify, @ghoeffner and I are reporting the same issue. I noticed the problem on his web server.

tobya commented 5 years ago

Thanks @Zenexer . I was trying to get a seperate issue opened specifically about the https://:443 issue that we can look at resolving. It is mixed up with an older issue here so by reporting it as a seperate issue it can get dealt with.

I'm happy for you to open it.

mholt commented 5 years ago

@Zenexer I am not convinced that certificates are private -- in fact, they are literally public keys. And DNS records point to the server, and that combined with CT logs makes trying to hide certificates kind of futile, even if they were supposed to be secret. This isn't any different from a client trying different SNI values to see what responds -- stopping that enumeration attack can only really be done by whitelisting, blacklisting, or rate limiting clients... or just making the secret server private. /shrug

Also worth a look: https://lanrat.com/certgraph/

yoda commented 5 years ago

Hosting on domain.com With a,b,c,d sub domains

watch --interval 2 "echo | openssl s_client -servername x.domain.com -connect a.domain.com:443 2>/dev/null | openssl x509 -inform pem -noout -text"

This will randomly select from a, b, c, d certs. Surely despite them being able to be enumerated or known from other means this is not correct?

Zenexer commented 5 years ago

@mholt The private part here is the association between certificates. Yes, I'm aware it's possible to derive similar information with sufficient scanning; however, there are technologies that make this difficult, if not impossible (when use correctly), such as Cloudflare. I was able to exploit this to determine the identity of a website operator; I would not have been able to determine their identity had this vulnerability not existed. CT logs were insufficient for this purpose, and there weren't adequate associations logged in services such as CertGraph and Censys at the time.

tl;dr Yes, it's a vulnerability, and yes, it's been successfully exploited. CT logs and CertGraph were unable to provide the same information.

orenyomtov commented 5 years ago

This is indeed an information leak type security vulnerability. Any idea on how to mitigate against this?

ghoeffner commented 5 years ago

This is indeed an information leak type security vulnerability. Any idea on how to mitigate against this?

There is a hacky workaround where you define a section for https://IP. However, I would really consider this a workaround.

orenyomtov commented 5 years ago

@ghoeffner Could you please elaborate on how to deploy this hacky workaround?

Also, if someone can point me in the right direction of creating a pull-request to solve this vulnerability long-term I might take it on.

ghoeffner commented 5 years ago
:443 {
    root /srv/www/_default_/public_html

    # Self-signed cert to not expose hostname
    tls self_signed
}
Zenexer commented 5 years ago

This has been assigned CVE-2018-19148. @mholt, I know you disagree that this is a vulnerability, but at least two organizations and several security researchers have come to the conclusion that it should be treated as a vulnerability. Even though the information it reveals should generally be considered public anyway, the ease of exploitation means that it’s much easier to get this information than it should be. Additionally, it can be used to establish definitive relationships between endpoints, proving that several hostnames are controlled by the same entity. Also, there are circumstances in which hostnames and certificates may not be public, such as on a corporate intranet.

This vulnerability is still present in the latest version (v0.11.0), despite indication to the contrary.

tobya commented 5 years ago

@Zenexer There is a trivial workaround for this, see @ghoeffner above. Perhaps we should add that to documentation until such time as we have a viable fix.

If there are ideas on how this could be fixed in the codebase in an acceptable manner we would be delighted to discuss a PR.

Zenexer commented 5 years ago

@tobya Although I noticed the vulnerability, it was @ghoeffner's web server; I've never actually used Caddy myself, and I'm not particularly experienced with Go. I figured it would be irresponsible not to report the issue, but I'm afraid I won't be much help when it comes to patching it. I'll take a quick look, but I doubt I'll be able to make heads or tails of the relevant code.

Zenexer commented 5 years ago

On second thought, after reviewing various information about Caddy and talking to another researcher, I'm a bit peeved at your attitude toward this issue:

  1. The official binaries are non-free: you charge quite a bit for their use in production. You should be able to afford to patch this on your own. Caddy is, first and foremost, a commercial product.
  2. I'm under no obligation to report vulnerabilities in the first place, never mind fix it for you for free.
  3. Caddy's main selling point is that it requires little-to-no configuration and is secure by default. If people have to implement configuration workarounds to ensure security, that's not secure by default.
  4. You've been aware of this issue for nearly two years. You've been reminded of it numerous times and have made no concerted effort to fix it. The issue was closed and marked as fixed, even though the alleged fix had no impact on the issue.

Sorry, but you're on your own from here.

ghoeffner commented 5 years ago

@mholt @tobya We are releasing an extensive blogpost about this vulnerability on SecurityTrails tomorrow. In case you want to read it and add a statement, let me know and will will make sure you have the chance to. Thanks to @Zenexer for helping with the research.

tobya commented 5 years ago

@ghoeffner You can email me at tobyallen@gmail.com not sure I will be able to give you a statement though.

@Zenexer Caddy is first and foremost an opensource product. All development is done in the open. The only thing that is commercial is the precompiled binaries. All source is on github.

elcore commented 5 years ago

This is my personal opinion:

The official binaries are non-free: you charge quite a bit for their use in production. You should be able to afford to patch this on your own. Caddy is, first and foremost, a commercial product.

This has nothing to do with this issue! Caddy itself is an open source project. The official binaries for commercial use require a commercial license, nevertheless you can build the binaries yourself, free of charge.

I'm under no obligation to report vulnerabilities in the first place, never mind fix it for you for free.

Of course, you are under no obligation to report vulnerabilities or fix them, @tobya kindly asked you to provide a PR.

Caddy's main selling point is that it requires little-to-no configuration and is secure by default. If people have to implement configuration workarounds to ensure security, that's not secure by default.

It is a workaround, that's why we (the community) are open to discussions......., and open to PRs.......

You've been aware of this issue for nearly two years. You've been reminded of it numerous times and have made no concerted effort to fix it. The issue was closed and marked as fixed, even though the alleged fix had no impact on the issue.

I cannot answer this question, the issue was closed and marked as fixed, as the linked PR was probably supposed to fix it.

Zenexer commented 5 years ago

I'm not interested in a debate, but I'm mostly annoyed that this was dismissed as not being a vulnerability in software that advertises its superior out-of-the-box security. I consider that both reckless and ignorant, and it speaks volumes about the security experience and awareness of anyone involved in that decision. The fact that it hasn't been fixed in nearly two years is astonishing.

I'm also much less keen on contributing to projects that have any significant revenue stream; if you're going to monetize your project, that's fine, but I'd rather spend my time contributing to projects for which I'm paid or that have no means of hiring programmers. I'm certainly not going to fault anyone for profiting from their own work, but I have higher expectations for such projects to be able to patch things on their own.

Just to be clear, the upcoming publication isn't retaliatory--I wasn't even aware that it was being written. However, once I was informed about it, I figured it was best to file for a CVE ID, and I requested that @ghoeffner provide a heads-up that a publication was on the way so it wouldn't come as a complete surprise. Normally that would've happened via a private channel, but the cat's already out of the bag on this one (and has been for two years).

mholt commented 5 years ago

This is not a statement and I do not give you permission to quote me anywhere else.

Forgive my firmness, and don't be offended -- I really mean no offense, but I'm also going to be direct.

I do not deny that the reported behavior is, in fact, accurate. And I am, believe it or not, open to "fixing" it. But do you have any good ideas how to do so?

No good solutions to this problem have been proposed. Instead, you've been spending your time and energy complaining in this thread to an open source developer who is underpaid, overworked, and doesn't have time for you; filing CVEs for information leaks that are available through Internet scans anyway; and writing blog posts for marketing purposes that are rife with false claims.

You're not helping the project, you're hurting it. I expect better from the community. I expect better from "professionals" and fellow researchers. And, like, you, "I'm a bit peeved."

The longer this thread goes unattended, the deeper and deeper it gets in false claims and misunderstandings. Allow me to volunteer time out of my work day to set the record straight. Last time I had to do something like this, I was fending off angry mobs while I was preparing a submission to the 2017 NIPS conference -- the deadline which was later that afternoon. Or was it when I announced commercial licenses so we could support business use of Caddy? Needless to say, I'm not thrilled to be doing this again.

@Zenexer

I figured it would be irresponsible not to report the issue,

The way you reported this is inappropriate. The original issue was fixed and closed two years ago after reasonable discussion and lots of effort from multiple individuals from different perspectives of the Internet. The original issue reported that a single hostname would be exposed when the SNI did not match a certificate. (This is what nginx does as well, which @ghoeffner conveniently advocates switching to in his writeup.) You may think you're being responsible, but you've only created confusion. @tobya was right, this should have been a separate issue from the beginning.

there are technologies that make this difficult, if not impossible (when use correctly), such as Cloudflare

And Caddy has a ratelimit plugin as well: https://caddyserver.com/docs/http.ratelimit - that can make enumeration difficult or impossible.

@ghoeffner

Yeah, whenever you have multiple domains setup in caddy and you access https://:443 you will get a different certificate every time. This exposes all websites on the host that have SSL enabled

Only with enough probing and as time goes to infinity -- there's no guarantee that all of them will be exposed except with enough time.

@Zenexer

Yes, I'm aware it's possible to derive similar information with sufficient scanning ... I would not have been able to determine their identity had this vulnerability not existed.

This is a contradiction. And this has yet to be verified.

there weren't adequate associations logged in services such as CertGraph and Censys at the time. ... CT logs and CertGraph were unable to provide the same information.

Can you be more specific?

@ghoeffner

This workaround:

:443 {
    root /srv/www/_default_/public_html

    # Self-signed cert to not expose hostname
    tls self_signed
}

Unfortunately, this does not resolve the issue. You now have the leakage problem but in reverse: if Caddy responds with a self-signed certificate, then it does not serve that hostname. The point is, Caddy can only serve certificates for hosts which it actually serves. And it is no different from the current leakage in that scanning for a long time is necessary to obtain an accurate, complete list of hostnames. You might as well use DNS or CT logs and some heuristics to get the information you need faster.

@Zenexer

Even though the information it reveals should generally be considered public anyway, the ease of exploitation means that it’s much easier to get this information than it should be. Additionally, it can be used to establish definitive relationships between endpoints, proving that several hostnames are controlled by the same entity.

All of this -- and more -- can be learned from DNS.

Also, there are circumstances in which hostnames and certificates may not be public, such as on a corporate intranet.

Then they must not obtain public certificates for them, which require being added to public CT logs, which attackers do use: https://dl.acm.org/citation.cfm?id=3278562 - operations should also not serve the secret names on a public network interface or expose public DNS resolvers/records, all of which are required to obtain publicly-trusted certificates. This is an orthogonal issue to the one at hand, and not a good basis for your argument, I'm sorry to say.

I've never actually used Caddy myself

You should try it! You might actually like it. And then you'd have a better understanding of what we're talking about, too.

I'll take a quick look, but I doubt I'll be able to make heads or tails of the relevant code.

Hm.

On second thought, after reviewing various information about Caddy and talking to another researcher, I'm a bit peeved at your attitude toward this issue

And I am at yours, too.

The official binaries are non-free: you charge quite a bit for their use in production. You should be able to afford to patch this on your own. Caddy is, first and foremost, a commercial product.

You're getting off-topic. $20/mo is not "quite a bit" -- have you seen nginx's prices? It's $2,500 / year / instance, or almost 10x MORE than Caddy's price. Perhaps our business error was making prices too low, but whatever the case, it is not financially sustainable as-is, which is why my contributions to the project have decreased. It's still open source, so the community can continue contributing to it if they feel so passionately about it. Or they can sit back and be "peeved" at what's wrong with it.

Caddy is an open source project and I'm not going to apologize for our offering to support businesses, which, for those who have purchased, we do quite well.

I'm under no obligation to report vulnerabilities in the first place, never mind fix it for you for free.

And I'm under no obligation to work for free for you, either.

Caddy's main selling point is that it requires little-to-no configuration and is secure by default. If people have to implement configuration workarounds to ensure security, that's not secure by default.

You're taking "security" to an unreasonable extreme. This is the Internet. There are information leaks. Do you know how to fix them? Great, then propose an actual, workable solution.

You've been aware of this issue for nearly two years. You've been reminded of it numerous times and have made no concerted effort to fix it. The issue was closed and marked as fixed, even though the alleged fix had no impact on the issue.

You're wrong. The issue you reported is only about 8-10 months old (introduced in #2037: https://github.com/mholt/caddy/commit/6e2de19d9fc29f8dec059c5345819a68a13832f2#diff-178ab7d13385d45b8abb244fda5a215fR169) The original issue that was reported 2 years ago was closed (twice) and fixed back then. You have not invested enough time or effort in this issue and your claims are false and misleading. You admitted yourself you know nothing of the code base or the web server.

@mholt @tobya We are releasing an extensive blogpost about this vulnerability on SecurityTrails tomorrow. In case you want to read it and add a statement, let me know and will will make sure you have the chance to. Thanks to @Zenexer for helping with the research.

I advise you do not release that, unless you want to admit your ignorance on the topic's complex history. You may attract pleasing responses from the popular crowd, but only a few of us core contributors and those of us familiar with the project's history understand the full implications and complexities here.

However, I did find it interesting that certain sites were using Caddy -- most of which I had no idea. Thank you for that. I was not aware that government entities or universities used Caddy in production. That kind of knowledge can actually change my perception about how I approach the project.

I'm not interested in a debate, but I'm mostly annoyed that this was dismissed as not being a vulnerability in software that advertises its superior out-of-the-box security.

Name just ONE other comparable web server with automatic HTTPS that's on by default.

The fact that it hasn't been fixed in nearly two years is astonishing.

Again, you're wrong. Look closer. Dig deeper.

I'm also much less keen on contributing to projects that have any significant revenue stream

I'm flattered that you think I make a lot of money this way, working on open source projects. But can you keep this from getting personal please?

Just to be clear, the upcoming publication isn't retaliatory--I wasn't even aware that it was being written.

Uh huh.

(and has been for two years).

Stop saying that, because again, you are wrong.

Now, let me explain a little bit some efforts made to resolve this newer issue at hand.

Over the last few weeks I have spent numerous hours reviewing code: the pull requests, the commits, the comments -- and the related discussion -- all in an effort to find a satisfactory solution that intersects everyone's interests:

All of these are requested -- even demanded -- to work perfectly. As I see it, though, no web server perfectly prevents enumeration, even: nginx serves up a default certificate. And nobody has suggested anything better, either.

Even if Caddy raises a TLS alert instead of responding with a certificate, that's still an information leak because you can easily know that Caddy doesn't serve that hostname. You have to make Caddy act the same whether it serves a host or not. I frankly don't know how to do that.

And before you say that enumerating hosts in this way is "harder", remember that you still need to enumerate towards infinity to guarantee an accurate list of hosts served by a Caddy instance with the current leak, since the certificates do NOT necessarily round-robin. Plus the search space can be greatly reduced -- probably by orders of magnitude -- through some simple heuristics or through referencing other public resources.

You might as well say that you can brute-force RSA keys with enough time, too -- except that RSA (private) keys are not public. And for hosts, there's DNS records, DNS resolvers and lookups, CT logs, network packets, and other public information that can be used to correlate a server with a hostname. The ease of it only depends on the capabilities of the attacker, not actual, rigorous security guarantees.

So. Do you want a solution that actually fixes the problem? If so, let's hear it. I have spent many volunteer hours trying to satisfactorily resolve this, but have not been able to do so. Please open a pull request if you know how to actually solve the problem, rather than just inverting the logic of the enumeration. If you want to discuss the issue further, please open a NEW issue, as this one was past its prime over a year ago, before the new problem ever existed.

Caddy's goal is not to fix a broken Internet, it's to make HTTPS the norm. For now.