Indeed, there is no infallible protection against a man-in-the-middle attack for the HTTP-01 challenge.
Someone who can intercept traffic between the Let's Encrypt validation nodes and your server CAN pass the challenge and get a cert issued. If they can pull off BGP trickery they may not necessarily even be in the middle in the normal sense.
This applies to the HTTP-01 challenge and for unsigned domains also the DNS-01 challenge.
It's worth noting that this problem is not unique to Lets Encrypt, the validation done by traditional CAs for DV certificates generally has this same problem; they typically offer HTTP, DNS and Email validation options, all of which are susceptible to a MITM attack.
What Let's Encrypt has done to mitigate the problem, is to run each validation from multiple test nodes in different data centers, requiring that all the test results agree in order to issue the certificate. (Which I suspect makes them less susceptible to this type of abuse than most of the traditional CAs.)
This at least reduces the scope of who might be in "the middle", as large parts of "the middle" will be different as viewed from the different test nodes.
This is all about the default behavior of automated domain-validation by Let's Encrypt (and CAs in general), but the domain owner has been given some additional control with the requirement that public CA's must check CAA
records.
In order to actually take control, the domain owner can take these steps:
- DNSSEC-sign the zone to ensure that the
CAA
data is not tampered with
(Also protects the challenge itself in the case of DNS-01)
- Add one or more
CAA
records to limit issuance of certificates
(Particularly CAA
records that do not only name the CA that is allowed to issue, but also which account with that CA that is allowed)
With a CAA
record looking something like this:
example.com. IN CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/12346789"
the problem is much reduced as an impostor cannot trivially initiate the challenge in the first place.
Pay special attention to the accounturi
parameter in the CAA
data, this is what makes the policy specific to the domain owner's account with the specified CA.
A CAA
record that only specifies the CA but not an account, while valid, would be of limited help as such a policy still allows any other customer of that CA to request having certificates issued.