my suggestion was merely to not have an ”accountkey=” parameter, but rather an:
accounturi=pubkey:<sha256 hash of account pubkey>
parameter.
In this way, we don’t change or break backwards compatibility.
There is a choice for the client to either use the account uri or the account
public key.
The advantage with my suggestion, is that the client can compute and populate
the DNS record long before the client even have touched the ACME server.
In this way, its more secure: The client can compute and populate the record
while being offline, meaning ultra security can be achieved.
This means harder for an attacker to subvert – if there is no communication to
subvert, they can’t subvert anything.
Since the accounturi parameter is mandatory, by using a new ”url scheme” called
pubkey, we can make sure the client has the choice, to either use the normal account
uri, the account uri supplied in the challenge object, or a offline-computed
pubkey:<sha256 of account public key>
This should match the security requirements for everyone, and also making sure
the 2 attacks that is mentioned, never happens.
Best regards, Sebastian Nielsen
Från: Aaron Gable <[email protected]>
Skickat: den 6 april 2026 20:41
Till: zandoodle <[email protected]>
Kopia: [email protected]
Ämne: [Acme] Re: Potential issues with dns-persist-01
On Sat, Apr 4, 2026 at 6:47 PM zandoodle <[email protected]
<mailto:[email protected]> > wrote:
1. An attacker sets up an ACME server and convinces the client to use it,
the client is then provided the attacker's ACME account on the CA's domain and
instructs the client to setup dns-persist-01 under the attacker's account.
2. An attacker sets up an ACME server and convinces the client to use it,
the client is then provided the attacker's ACME account for the attacker's
domain and instructs the client to setup dns-persist-01 under the attacker's
account. This requires that the certificate authority allows accounts to be
created under the attacker's domain e.g. creating the account under the domain
in the Host header field as done by Let's Encrypt.
A few notes here:
First, these two scenarios are essentially identical. In both of them, the
attacker is merely providing an attacker-controlled account URI to the victim
client, to get them to populate it in a DNS record. The only difference with
the second scenario is that the victim client operator would see that their
directory URL and account URL have the same domain name, and might be less
likely to notice that something weird is going on.
Second, the second of these scenarios doesn't actually work, at least not against
Let's Encrypt. Although we reflect the Host: header in API responses, we only respect
the canonical AccountURI for the purpose of CAA and dns-persist-01 accounturi=. A
client that populates a TXT record with `accounturi=malicious.ca/acme/acct/12335`
<http://malicious.ca/acme/acct/12335%60> would not be able to complete
validation.
Finally, the fundamental threat model here was already considered and mitigated
in RFC 8555. One can imagine a similarly-positioned malicious ACME proxy-esque
server which intercepts an HTTP-01 challenge and replaces the `token` with one
of its own. However, the attacker still can't get the victim client to
successfully complete validation because the necessary value presented by the
client to complete the challenge consists of two pieces of information: the
token (provided by the server) and the Key Authorization (computed directly by
the client). The victim client can't be fooled into computing a Key
Authorization for the malicious proxy's key.
So the solution here is to do the same. The dns-persist record should contain a
piece of information computed directly by the client, rather than merely
provided by the (potentially malicious) server. So I agree with Sebastian's
suggestion that the record format should support an `accountkey=` parameter.
Aaron