w3c / vc-data-integrity

W3C Data Integrity Specification
https://w3c.github.io/vc-data-integrity/
Other
40 stars 18 forks source link

Context injection can lead to interference between proofs on a document, breaking verification of jcs-based proofs #225

Closed rflechtner closed 2 months ago

rflechtner commented 8 months ago

After discussing challenges that context injection currently poses for combining with @msporny & @dlongley in a different forum, we've agreed this should be brought to the attention of the broader VCWG community.

The problem

Context injection is the practice of adding proof type related context references to a document's @context property prior to proof issuance and/or verification and both required by this specification (https://w3c.github.io/vc-data-integrity/#context-injection) as well as routinely done by implementations of other proof types. While this practice works for proof schemes that secure the underlying data graph instead of its JSON-LD representation (such as rdfc-based cryptosuites), it creates problems for schemes that work by securing the JSON representation (the document) instead, including all kinds of jcs based cryptosuites. The reason for this discrepancy is that adding additional values to @context in this scenario does not alter the resulting document data graph because it only determines the mapping of proof properties and does not appear in the graph itself - but it does obviously change its JSON-LD representation. As a result, there are scenarios in which jcs-based proofs used in a proof set or proof chain become unverifiable.

Example case

Consider, for example, a scenario where Signer A and Signer B subsequently add proofs to a document to form a proof chain. Signer A begins by adding a proof of type DataIntegrityProof using the eddsa-jcs-2022 cryptosuite. As part of this, the URL https://w3id.org/security/data-integrity/v2 is added to the set of @context values prior to signing. Signer A then passes the modified document including the proof to Signer B, whose signer implementation is a little more dated and uses the Ed25519Signature2020 proof type. This now adds the URL https://w3id.org/security/suites/ed25519-2020/v1 to the set of @context values. The resulting document cannot be verified with the proof added by Signer A; removing the @context value added by Signer B on the other hand results in the latter proof not being verifiable, as the terms it uses become undefined.

Constraints & Solution(s)

I think it is imperative that such unexpected interference and the resulting brittleness of applications relying on this specification is prevented on the protocol level as far as possible, which calls for a solution to this issue before the current draft advances to a recommendation.

It is not immediately obvious though how this can be achieved if the solution is to realise the following design goals:

  1. Allow any combination of jcs- and rdfc-based proofs to secure a document as a proof set or proof chain.
  2. Allow adding proofs incrementally and in any order, where not all contexts to be injected are known before creating the first proof.
  3. Do not break existing implementations, i.e., continue to verify proofs that depend on context injection.
  4. Enable safe consumption of the secured document as both JSON and Linked Data.

My hope is to start a thread here that leads to an agreement on a way forward that realises these goals as good as possible. In order to kick things off, I'll follow up with a suggestion made by @dlongley & @msporny in our original thread.

rflechtner commented 8 months ago

In our original thread, @dlongley sketched out a possible solution that ticks boxes 1-3 by requiring jcs-based specifications to include the document context at the point of proof generation in the proof object, and using it to override the (possibly altered) document context at the point of verification. The idea, as far as I understood, thus is to replace the document's @context silently and implicitly during proof verification.

From what I can see, in order to make sure we hit requirement 4 as well, we will need additional checks in place. Simply verifying a document with the context replaced instead of the one to which the proof is attached would result in a situation where the @context values visible to the consumer of the secured document (e.g., a credential) are effectively unsecured and could be manipulated (e.g., by the credential holder), changing the semantics of the document in the process. This weakens the guarantees that the data graph as presented to a relying party is equivalent to the one originally signed. My suggestion here is that we additionally require that jcs-based proof schemes verify whether the context retained on the proof object is a subset of the context of the document to be verified. Because the @context property is defined as an ordered set, this means that:

  1. The document @context MUST contain all values contained in the proof @context in the same order.
  2. The document @contextMUST NOT have any values preceding the values contained in the proof @context but those MAY be followed by additional values not contained in the proof @context.

Because context injection adds additional values to the end of the set, these conditions should always be met for incremental proof generation, failing only for cases where proofs are created independently and then added to a document, thus hitting all design goals 1-4. @msporny & @dlongley is this accurately representing the solution you had in mind? And would you agree that parallel/independent proof generation is out of scope?

Wind4Greg commented 4 months ago

Hi all (@rflechtner, @dlongley, @msporny ), I tried to turn the above solution discussion into something concrete. Please take a look at PR https://github.com/w3c/vc-di-eddsa/pull/79 which applies this to EdDSA with JCS. Cheers Greg

msporny commented 2 months ago

PRs w3c/vc-di-eddsa#79, w3c/vc-di-eddsa#80, w3c/vc-di-ecdsa#61, and w3c/vc-di-ecdsa#62 have been raised to address this issue. This issue will be closed once those PRs have been merged.

msporny commented 2 months ago

PRs w3c/vc-di-eddsa#79, w3c/vc-di-eddsa#80, w3c/vc-di-ecdsa#61, and w3c/vc-di-ecdsa#62 have been merged, closing.