Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

protect against "anyone can ledgerize" attack #112

Closed
dhh1128 opened this issue Sep 17, 2019 · 6 comments
Closed

protect against "anyone can ledgerize" attack #112

dhh1128 opened this issue Sep 17, 2019 · 6 comments

Comments

@dhh1128
Copy link
Collaborator

dhh1128 commented Sep 17, 2019

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:

  1. 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).

  2. 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:

  1. 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.

@SmithSamuelM
Copy link

SmithSamuelM commented Sep 18, 2019 via email

@SmithSamuelM
Copy link

SmithSamuelM commented Sep 18, 2019 via email

@dhh1128
Copy link
Collaborator Author

dhh1128 commented Sep 18, 2019

Sam: I think it's uncontroversial that we want the self-certifying property you've described so well, that our current method doesn't quite get there (because it allows for multiple keys in the genesis state), and would best be improved by using pre-rotation.

My only question is: how do we use pre-rotation while still preserving the characteristic that support for key rotation with peer DIDs is optional (layer 3), and without modifying the DID Exchange protocol (which allows a DID doc to be exchanged at the inception of a relationship, but does not allow deltas to accompany it).

If you have any ideas about answers to either of these questions, I'd be interested to hear them.

@SmithSamuelM
Copy link

SmithSamuelM commented Sep 18, 2019 via email

@SmithSamuelM
Copy link

SmithSamuelM commented Sep 19, 2019 via email

@dhh1128
Copy link
Collaborator Author

dhh1128 commented Jul 15, 2020

Closing this issue because we've moved the repo and we've determined to reframe peer DIDs in terms of KERI. This will naturally cause us to resolve the concern here. Therefore, work on this issue can take place in the context of decentralized-identity/peer-did-method-spec#4.

@dhh1128 dhh1128 closed this as completed Jul 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants