Advisory Database
  • Advisories
  • Dependency Scanning
  1. npm
  2. ›
  3. @sd-jwt/decode
  4. ›
  5. CVE-2026-62374

CVE-2026-62374: SD JWT JS: Tampered disclosures silently dropped instead of rejected

November 2, 2026

When one Disclosure in an SD-JWT presentation is tampered so its digest no longer matches the Issuer-signed _sd array, @sd-jwt/decode 0.19.0 does not reject the presentation. It silently drops the unmatched Disclosure and returns a reduced claim set, reporting success. The Issuer signature is untouched and valid.

This is a downgrade/omission primitive. A malicious or curious holder can present a tampered Disclosure and have the relying party receive fewer claims than the credential carries, with no error surfaced. Where the relying party does not enforce key binding, an in-transit (on-path) attacker can achieve the same by mangling one Disclosure’s bytes; where key binding is enforced, on-path tampering instead breaks the holder’s KB-JWT sd_hash binding (so it is rejected), and the downgrade is then exercisable by the key-bound holder — confirmed end-to-end with KB required.

Two distinct tampering inputs converge on the same silent-drop sink:

  1. Genuinely non-decodable Disclosure (broken base64url -> bytes that are not valid UTF-8, e.g. an injected 0xF2 lead byte). RFC 9901 §7.1 step 3 / §4.2.1 require rejection. @sd-jwt/decode instead lossy-decodes it: the TextDecoder/Buffer path substitutes U+FFFD (REPLACEMENT CHARACTER) for the invalid byte and recovers a syntactically valid disclosure (the salt gains a U+FFFD, claim family_name = "Smith"). The recovered Disclosure then hashes to a digest absent from the signed _sd array, so it is silently skipped.
  2. Tampered-but-still-valid-JSON Disclosure (digest no longer matches _sd): same end state — the unmatched Disclosure is silently skipped.

Two RFC 9901 MUSTs compound:

  • §7.1 step 5 (primary): “If any Disclosure was not referenced by digest value in the Issuer-signed JWT (directly or recursively via other Disclosures), the SD-JWT MUST be rejected.” — instead silently dropped.
  • §7.1 step 3 / §4.2.1 (secondary): a non-base64url-JSON Disclosure MUST be rejected — the lenient lossy decode skips this check.

Confirmed end-to-end through SDJwtInstance.verify() with a real ES256 issuer key, and again with key binding REQUIRED (a valid holder ES256 KB-JWT over aud+nonce+sd_hash).

References

  • github.com/advisories/GHSA-f9j6-8p6x-r9j6
  • github.com/openwallet-foundation/sd-jwt-js/commit/3d8a72a0a279d67439db038c9c2b52621568b866
  • github.com/openwallet-foundation/sd-jwt-js/pull/380
  • github.com/openwallet-foundation/sd-jwt-js/security/advisories/GHSA-f9j6-8p6x-r9j6
  • nvd.nist.gov/vuln/detail/CVE-2026-62374

Code Behaviors & Features

Detect and mitigate CVE-2026-62374 with GitLab Dependency Scanning

Secure your software supply chain by verifying that all open source dependencies used in your projects contain no disclosed vulnerabilities. Dependency Scanning using SBOM also detects vulnerabilities from proprietary advisories that this site does not include. Learn more about Dependency Scanning using SBOM →

Affected versions

All versions up to 0.19.0

Solution

Unfortunately, there is no solution available yet.

Impact 6.5 MEDIUM

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N

Learn more about CVSS

Weakness

  • CWE-176: Improper Handling of Unicode Encoding

Source file

npm/@sd-jwt/decode/CVE-2026-62374.yml

Spotted a mistake? Edit the file on GitLab.

  • Site Repo
  • About GitLab
  • Terms
  • Privacy Statement
  • Contact

Page generated Tue, 03 Nov 2026 12:16:11 +0000.