The key state for the did:webs DID provided in a did:webs didDoc is verifiable against the keri.cesr file because the keri.cesr file includes the key event log (KEL) for the AID portion of the did:webs DID.
An attacker may create their own AID and associate it with the same DNS domain name as some other did:webs DID (but differ in the AID portion). They could use this to give the false impression that they represent the entity that is supposedly the controller of the domain name common to both DIDs.
did:webs by itself does not prevent such an attack. The attack is not attacking the control of a given did:webs did but is attacking the control of the domain name common to both did:webs dids. A given did:webs DID is controlled by the key state associated with its AID not its doman. A related attack is when the didDoc includes service endpoints or other information that is not part of key state or is not anchored to key state. This attack will be discussed below.
The root-of-trust for any did:webs DID is the AID in the DID. There are many ways to impersonate the controller of a given domain name or web host. This is the primary vulnerability in did:web that did:webs fixes because spoofing control of a did:webs DID (unlike a did:web DID) requires compromising the keys that control the AID in the did:webs DID.
A did:webs didDoc that does not have the correct did:webs DID for a given key state will not resolve given a compliant (trustable) DID resolver because the resolver verifies the key state w.r.t to the AID in the associated did:webs DID against the KEL provided in the keri.cesr file. The keri.cesr file provides a hash chained signed proof of key state. Control of the full did:webs DID which includes the AID is thus protected. One can't spoof control of the full DID without compromising the private keys in the KEL.
To elaborate, anyone can create their own AID and then create a KEL and then create a keri.cesr file from that KEL and then create a did:webs DID with the AID for any domain name they choose. A didDoc that provides the key state from by that keri.cesr will resolve. The did:webs resolver in that case is only verifying that the key state provided in the did:doc is consistent with the key state in the keri.cesr which will prove the key state for that AID (at a given point in the KEL). This does not in any way prove that the domain name is controlled by the controller of that AID. That requires a different type of proof.
The only way for a user to know that a given AID is under the control of a given entity is via a out-of-band exchange of information that binds the AID to that entity. This includes binding that AID to the entity that truly controls a given DNS domain name. This could be done in many ways. Given that we are assuming that the dns/ca system itself is insecure. We can not merely trust that the appearance of a did:webs DID (with its AID in tow) on a web host of the did:webs' domain name makes a secure binding between the controller of the associated AID and the controller of the associated domain name.
For example, in GLEIF's case, the binding between GLEIF as a legal entity and its root AID is secured by multiple attestations under domain names or other identifiers that either GLEIF controls or are controlled by trusted entities that control GLEIF to that AID. (see the vLEI ecosystem governance framework). This set of multiple links provides a multi-factor out-of-band mechanism for binding GLEIF as a legal entity to its root AID.
As mentioned above, a related attack is to spoof other information, besides key-state, by providing that other information in a didDoc for a given did:webs DID. Any information not provided in or anchored in the KEL of an AID is not directly verifiable against the keri.cesr file so some attacker could place that information in a did:webs didDoc and purport that that information is valid.
There are several ways to protect against such attacks.
-
Provide a "strict" mode for did:webs resolution that only includes KEL anchored data in the did:webs didDoc. A compliant resolver in strict mode never includes anything but KEL anchored data. Primarily this is key-state, witness AIDs which embed witness key-state, and config traits. Please note that other information anchored via a seal is not directly observable and hence verifiable by the resolver merely with only key events from a KEL in the keri.cesr. That information, however, could be provided via attachments to the KEL which attachments are also included in the keri.cesr file.
-
expand the resolution to normatively look for anchor seals and attachments that expose the contents of the seal hashes when those attachments are included in the keri.cesr file. Then in strict mode a resolver can include the seal anchored information in the rendered didDoc. This information is thereby verifiable.
-
expand the resolution parametrization to normatively allow for the inclusion in the parameters of exposed anchor seal contents that are dynamically (at resolution time) merged with the keri.cesr file to include such anchored content in the rendered did:doc
-
Protect unanchored information such as service endpoints using BADA-RUN on the service endpoints. There are several ways to approach this.
- The simplest is to let the "buyer beware", that the unanchored information must be separately verifiable by the user. BADA-RUN enables the user to verify the service endpoint given the keystate provided by the didDoc because the replies to BADA-RUN requests must be signed with the latest key state at time of the BADA-RUN update.
- A more complicated approach (for the resolver) is for the resolver to perform BADA-RUN verification on any unanchored data and only render that data in the didDoc if the BADA-RUN verifies. This makes it easy on the user but complicates the resolver.
- The controller of the AID must attach a signature to any information that is to be included in the did:doc but is not anchored to the KEL. Essentially the did:doc becomes the equivalent of a BADA-RUN reply. This would only work for resolutions of the latest key state and not earlier key states as earlier key states may have been compromised so signed but unanchored data is not verifiable anymore one the key state changes.
To summarize, there is a rampant misunderstanding that merely signing a document makes the contents securely attributable to some entity when that signature verifies. Signatures attributed to persistent identifiers (which support changes to their controlling key state) are invalid once the key state changes. The signed data must also be bound to the key state of the identifer at the time the signature was created. This, indeed, is one of the major, if not the major security vulnerability in the DNS/CA system. Domain names are persistent identifiers whose controlling key state may be changed by the issuance of a new Cert from some CA (usually any CA). There is no way in the existing DNS/CA system to bind signed data to the actual key state at the time of signing in a verifiable way. Recall that the main reason to change key state (rotate) is to protect from key compromise. Thus any stale signatures from state keys must be assumed to be compromised signatures unless the signed data is anchored to the key state in such a way that later key compromise is prevented from making new anchors.
Consequently, without key state anchoring, only the latest key state should ever be used for verification and because it is possible to miss-issue verifiable certs from multiple CAs there is no cryptographically verifiable way to establish the one and only one latest key state. Certificate Transparency will tell a verifier that are multiple valid key states but not which one is the truly valid one.
In the did:webs case, the underlying KEL in the keri.cesr file provides cryptographically verifiable proof of the key state at the time any data is anchored to the KEL. Because the events in the KEL are signed with a post-quantum protected forward and backward chaining mechanism related to key state (pre-rotation), then any anchored data is also verifiably bound to the key state at the time of its anchoring event. It is effectively signed by virtue of its anchor. Recall that signing a cryptographic strength digest of data is equivalent to signing the data directly. Signatures on the anchored data are, at best redundant and at worst may be misleading because they are weaker than the anchors (by virtue of being unbound to key state at the time of signing) and therefore should be ignored.