From cb3ccc8aaaafc8cae72c4dd95ea0953b655464a9 Mon Sep 17 00:00:00 2001 From: rongquan1 <85145303+rongquan1@users.noreply.github.com> Date: Wed, 29 Jul 2026 15:15:04 +0800 Subject: [PATCH] fix(w3c-vc): validate credentialStatus format only at sign, not verify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _checkCredential ran assertCredentialStatuses in both 'sign' and 'verify' modes. Since 2.4.0's assertTransferableRecords strictly requires an integer chainId (via assertIntegerChainId), a malformed tokenNetwork.chainId now throws during verify — and _checkCredential(mode: 'verify') is reached by isSignedDocument() and the DataIntegrity verifiers. That made a credential-status field problem masquerade as "document is not signed" / a signature-integrity failure. Gate the credentialStatus field-format validation to 'sign' mode. At verify the status is the concern of the dedicated status verifier (verifyCredentialStatus), so a malformed chainId now surfaces as a DOCUMENT_STATUS problem instead of a signature one. Sign-time validation is unchanged (still rejects a bad chainId at creation). Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/w3c-vc/src/lib/helper/index.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/w3c-vc/src/lib/helper/index.ts b/packages/w3c-vc/src/lib/helper/index.ts index 45c3c6f..989b68b 100644 --- a/packages/w3c-vc/src/lib/helper/index.ts +++ b/packages/w3c-vc/src/lib/helper/index.ts @@ -321,8 +321,15 @@ export function _checkCredential( } } - // Validate credentialStatus field if present - assertCredentialStatuses(credential, mode); + // Validate the credentialStatus field FORMAT only when signing. At verify time the + // credential status is the concern of the dedicated status verifier (verifyCredentialStatus): + // a malformed status field (e.g. a non-integer tokenNetwork.chainId) must surface there as a + // status problem, NOT make the credential look unsigned or fail signature integrity. Note + // that _checkCredential(mode: 'verify') is reached by isSignedDocument() and the + // DataIntegrity verifiers, so throwing here would mis-attribute a status error to those. + if (mode === 'sign') { + assertCredentialStatuses(credential, mode); + } // Validate that certain fields, if present, are objects with a type property for (const prop of mustHaveType) {