A discussion thread on this vulnerability was started in the W3C CCG. Here's a quick summary of it for background:
@SmithSamuelM and I have been discussing an issue that I wanted to bring to this group. It is a risk that Sam has described as the "anybody can ledgerize" problem: What is to prevent someone other than the owner of a DID from recording the initial version of a DID doc on a ledger, thus making public something that the owner intended to keep off ledger for the time being or permanently?
Even though this question is framed in terms of ledgers, it has direct application to non-ledger DID methods as well.
I believe that some DID methods allow anyone with write permission or willing to pay transaction fees to write a DID and its initial DID Doc to the shared source of truth. Since the DID doc just contains public keys, all the info in it might be known by someone other than the DID's owner -- another party in the list of controllers, for example, or even an adversary. Yes, the adversary possesses none of the private keys, and so cannot control the DID after registration--but the mere registration of someone else's data could, in and of itself, constitute mischief.
To guard against abuse, the correct behavior of a ledger is probably to require that the request to write the genesis version of the DID doc be signed by a key in the DID doc. Note that just signing the DID doc isn't enough, since the attacker could have captured the signature when he captured the DID doc content. Even better security would be to require that the DID value be derived from a key in the DID doc, and that the initial write request use that key as well. Perhaps this protection against abuse needs to be a rubric? Or perhaps it is more fundamental, and needs to be a requirement of all DID methods, period?
Now I'd like to reason about how this applies to peer DIDs. Here's how it could play out there: Alice's agent 1 creates a DID doc for a relationship with Bob, naming keys for agent 2 and agent 3 as also authorized. Then Alice's agent 2 (which may have been hacked without Alice realizing it) can take that DID doc and send it to Carol, using the agent 2 key to sign. The rogue agent thus "registers" the DID doc in a way and with a party that the DID owner did not intend. This is basically the "anybody can ledgerize" attack.
Originally, the peer DID spec required the peer DID value to be derived from "the public key". However, at IIW last spring, Christian Lundkvist convinced me that the did should derive from a hash of the genesis version of the DID Doc instead. Since that includes one or more public keys, it has much the same protections. But it doesn't have a protection against the abuse case I described in the preceding paragraph.
At first glance, there seemed to be 3 possible answers:
-
Start the DID Doc with one public key; this is "the public key" from which the DID value derives, granting authority to all others. Require that the other 3 keys be added in subsequent operation(s).
-
Allow the DID Doc to be created with multiple keys, but make one of the keys special (e.g., the first key, or the key tagged as "prime" or some such); this is the one that must authorize creation.
Technique 1 might seem better from the perspective of self-certification purity, but it has a different cybersecurity problem, which is that such a strategy requires that you operate without checks and balances, and without backups, for some period of time early in the lifespan of every DID. We therefore discarded it; we wanted to be able to say, even in the genesis state, that a given DID is guarded by M-of-N signature policies, for example.
Right now the peer DID spec takes a weakened form of approach 2. It simply requires that the genesis DID doc be associated with (not necessarily signed by) one of the keys in its genesis state. Besides direct signing, "associated with" could mean that the genesis DID doc is streamed over DIDComm channels that authencrypt with one of the keys in question.
There is option 3:
- We could require the genesis DID Doc to be signed by M-of-N agents if M-of-N agents are names as authorizers of subsequent edits.
This eliminates the "anybody can ledgerize" risk, but it may be unacceptably inconvenient. I might create several keys that I store in vaults, offline, and that I never want to pull out when I'm creating new relationships--yet I might want to name those keys in the genesis versions of my pairwise DID Docs.
@SmithSamuelM suggested my current preferred option, which is to use pre-rotation. Basically we start a peer DID with only 1 key, and then we immediately create a delta that adds the other keys, before we even share the DID Doc at all. This is easily done and satisfies the convenience and strong security requirements. Its only drawback is that we need to modify the connection protocol (Aries RFC 0023) so it's possible to send a delta along with the initial version of a DID Doc that's exchanged when building a connection.