Code change:
Clarify validation around no duplicate digests in the payload (directly or recursively) and no unused disclosures at the end of processing (to & )
SD-JWT validation processes should require that the validating party (Holder or Verifier) validate that the hash of each disclosure object appears in the Issuer JWT claims. If this validation is not performed, then the SD-JWT format is malleable, in the sense that arbitrary additional disclosure objects can be added beyond those that the issuer intended. This creates the opportunity for mischief, from bugs to covert channels. This is not a difficult property to enforce. The already has the validating party compute the lists of (1) hashes of disclosure objects and (2) disclosure hashes in the Issuer JWT. So the only additional step required is to check that (1) is a subset of (2).
That requirement that the hash of each disclosure must appear in the Issuer-singed JWT is in the current draft text - near the top of has "a Holder or a Verifier MUST ensure that ... all Disclosures are correct, i.e., their digests are referenced in the Issuer-signed JWT". Seems it could be made more explicit or clear? But it is there.
Ah, thanks, I had missed that. Even given that though: I would not call this property "correct". The only other place that property appears is in 11.2, so maybe it can just be dropped, and we can just say directly "All disclosures correspond to a hash value that appears in the Issuer JWT" Given recursive disclosure, though, even that's not really sufficient. A recursively disclosed claim does not in fact appear in the Issuer JWT -- you basically need to verify that it hash-chains into the Issuer JWT via a series of disclosures If we're going to eliminate recursive disclosure, I think the current text probably suffices (modulo "correct"). But if we're going to keep it, we need to elaborate the algorithm. Maybe it can be folded into the existing recursive algorithm as a termination condition. If you're adding the hashes inside disclosed values as you restore them, then if you get to the point where none of the claim hashes are in the set of disclosure hashes, then if the set of disclosure hashes is non-empty, the object is invalid.
Assuming here in this ticket at least that we are not going to eliminate recursive disclosure. The use of "correct" is indeed awkward and that whole bit of text could be improved. There's room for a lot of improvement there. I've always understood text like "referenced in the Issuer-signed JWT" as intending to mean included directly in that JWT but also included recursively. But being more explicit is probably worthwhile. I think it'd be sufficient to say somewhere something like "all disclosures must correspond to a hash value that appears (either directly or recursively) in the Issuer-signed JWT". That somewhere could be in place of the "all Disclosures are correct" text and/or a step in the validation steps near . To you earlier point - it's not a difficult property to enforce. Even with the recursion. A validating party needs to compute the lists of (1) hashes of the disclosure objects and has to look at (2) all disclosure hashes in the Issuer JWT (including by recursive inclusion). The only additional step is still just to check that (1) is a subset of (2). Which is basically just checking that there were no unused disclosures at the end of processing.
Agreed, if we can update the algorithm to reject if any hashes are left over, then that would fix this issue.
Great, I think we can update the the algorithm to reject if any disclosures are left over. It'd probably go near the check to ensure that no digest value is repeated in the whole of the SD-JWT - either in the payload directly or recursively in any disclosure (that check about duplicate digests needs a bit of improvement too). Also we should tidy up that text with "correct".
From the mailing list Hi Jacob, the intention was to cover the first case you listed. We should clarify this. -Daniel Am 20.10.23 um 15:02 schrieb Jacob Ward:
my 2 cents at/from URL
Also... um, wouldn't "More than one Disclosure have[ing] the same digest" imply a collision in the hash function? And therefore infeasible to actually happen. Agree that it should be clarified. Being precise with language around this stuff is tricky. But my understanding of the intent was to ensure that no digest value is repeated in the whole of the SD-JWT - either in the payload directly or recursively in any Disclosure. Because of the trickiness of language, I'm not sure if we disagree or not about the intent... CONFIDENTIALITY NOTICE: This email may contain confidential and privileged material for the sole use of the intended recipient(s). Any review, use, distribution or disclosure by others is strictly prohibited. If you have received this communication in error, please notify the sender immediately by e-mail and delete the message and any file attachments from your computer. Thank you.

Related discussion:
text: We would like to thank Alen Horvat, Anders Rundgren, Arjan Geluk, Christian Bormann, Christian Paquin, David Bakker, David Waite, <del> Fabian Hauck, Filip Skokan, Giuseppe De Marco, John Mattsson, Justin Richer, Kushal Das, Matthew Miller, Mike Jones, Mike Prorock, Nat Sakimura, Neil Madden, Oliver Terbu, Orie Steele, Paul Bastian, Peter Altmann, Pieter Kasselman, Richard Barnes, Ryosuke Abe, Sami Rosendahl, Shawn Butterfield, Simon Schulz, Tobias Looker, Takahiko Kawasaki, Torsten Lodderstedt, Vittorio Bertocci, and Yaron Sheffer for their contributions (some of which substantial) to this draft and to the initial set of implementations. </del> <ins> Fabian Hauck, Filip Skokan, Giuseppe De Marco, Jacob Ward, John Mattsson, Justin Richer, Kushal Das, Matthew Miller, Mike Jones, Mike Prorock, Nat Sakimura, Neil Madden, Oliver Terbu, Orie Steele, Paul Bastian, Peter Altmann, Pieter Kasselman, Richard Barnes, Ryosuke Abe, Sami Rosendahl, Shawn Butterfield, Simon Schulz, Tobias Looker, Takahiko Kawasaki, Torsten Lodderstedt, Vittorio Bertocci, and Yaron Sheffer for their contributions (some of which substantial) to this draft and to the initial set of implementations. </ins> The work on this draft was started at OAuth Security Workshop 2022 in Trondheim, Norway.