Skip to content

v4.0.0 — Security release

Choose a tag to compare

@codenlighten codenlighten released this 31 May 13:28
· 33 commits to main since this release
206c000

Security release fixing three critical, exploitable vulnerabilities in the GDAF Verifiable Credential path, removing a live private key, hardening crypto, and repairing the test runner. Full suite: 4172 passing, 0 failing.

🔴 Critical (GDAF credentials)

  • Signatures now cover the whole credential body. Canonicalization used the JSON.stringify replacer-array form, which dropped every nested object (credentialSubject{}) from the signed hash — claims could be rewritten without invalidating the proof. Replaced with a recursive, depth-complete key sort.
  • The signature is now actually checked. Verification read the always-truthy ECDSA#verify() instance instead of .verified, so every proof passed regardless of validity.
  • Signing key is bound to the issuer. Key was resolved from the attacker-controlled proof.verificationMethod and never compared to credential.issuer (issuer spoofing). trustedIssuers is now enforced.

🔑 Key removal

  • Deleted utilities/wallet.json (shipped a live mainnet WIF) and added a .gitignore guard. Rotate that key — treat as compromised.

🟡 Hardening

  • ECIES (electrum/BIE1): constant-time MAC comparison.
  • ECDSA#sigError: removed dead branch; rejects negative r/s (range [1, n-1]).
  • Dropped inaccurate vulnerability-free / security-hardened npm keywords.

🧪 Tests / tooling

  • Added .mocharc.json (recursive) + removed defunct test/mocha.opts — mocha 8 ignored mocha.opts, so ~40 test files never ran in CI.
  • Repaired test/crypto/security.js (0/8 → 12 passing); added test/gdaf/canonicalize.js (8 tests); fixed the 18 pre-existing failures.

⚠️ Breaking

The signed bytes changed (nested claims now covered), so credentials/presentations signed by ≤ 3.4.5 will not verify under 4.0.0. Re-issue them.

Full changelog: see CHANGELOG.md.