They found that some implementations of ACME enable cross site scripting. In the http-01 domain validation method the CA server sends the requester a token and then the server should serve the token concatenated with an account public key hash in a file named after the token.
It turns out some implementations do this in a way that they don’t really care about the token, but always reflect whatever you request under the corresponding url (/.well-known/acme-challenge/token). In some setups this is combined with content sniffing, which enables cross site scripting (i.e. if you reflect html content it will be served as text/html).
There are a lot of ACME implementations, but maybe someone here is aware of an implementation that might have this behavior. Would be interesting, because then we could fix this at the source and stop it from proliferating.
thanks. This is really not a good idea. My own client sends a 404, if the token is wrong.
But: There are sometimes curious questions:
The key authorization file from the server did not match this challenge [U7Z05MbBan_sQRbagOsMUOrbrefGfGsWiYZqTbXdz_c.Mxd6puZz877ZrQ7u9cPPc2amincbkMvNFjbgIj9OlQU] != [U7Z05MbBan_sQRbagOsMUOrbrefGfGsWiYZqTbXdz_c.JQoYFoTtPDe2MIr4xFKqpRpt0eKti-HMnJ0BIl9eOjE]
The token is correct, the dot is correct. But the hash of the account key is wrong.
And: There were wrong ipv6 - settings, so ipv6 sends another content then ipv4.
Removing the ipv6 - AAAA record solved the problem.
So it looks that these hosters reflect /.well-known/acme-challenge/1234 with the content
1234.[Hash of the public account key]
With the consequence:
If Letsencrypt has this error validating a domain name, Letsencrypt could search all accounts to find the account with [Hash of the public account key] to find such a wrong reflection.
Being able to reflect the requested resource in the body is valuable when you are performing HTTP validation for a domain that is served by many web servers (and are not load-balanced through a single endpoint).
It saves having to deploy challenges to each server, rather each server just has to be preconfigured with the JWK Thumbprint.
acme.sh is one of the clients that documents such a solution: https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode (though it does restrict the character set of the reflected part to that of base64url so it’s probably not vulnerable in most cases).
FWIW, server-side content sniffing a security risk independently of ACME.
I am not sure if the sniffing middleware from the article responds to x-content-type-options: nosniff as browsers do, but maybe it’s a good implementation guideline for acme-challenges anyway.
@Neilpang, I think @_az is right that your implementation will not create this risk at all, but could you please verify that? Also, are you aware of whether any other implementations were deployed that were inspired by yours?