CVE-2026-40070
Ruby vulnerability analysis and mitigation

Overview

CVE-2026-40070 is a cryptographic signature verification bypass vulnerability in the BSV Ruby SDK (bsv-sdk and bsv-wallet gems) that allows authenticated attackers to forge identity certificates. The flaw exists in BSV::Wallet::WalletClient#acquire_certificate, which persists certificate records to storage without verifying the certifier's signature over the certificate contents. It was identified on April 8, 2026, during a cross-SDK compliance review and publicly disclosed on April 9, 2026. Affected versions are bsv-sdk >= 0.3.1, < 0.8.2 and bsv-wallet >= 0.1.2, < 0.3.4. It carries a CVSS v3.1 base score of 8.1 (High) (GitHub Advisory).

Technical details

The root cause is CWE-347 (Improper Verification of Cryptographic Signature). The BRC-52 specification requires that a certificate's signature field be verified against the claimed certifier's public key over a canonical hash of (type, subject, serialNumber, revocationOutpoint, fields) before the certificate is trusted — a check the reference TypeScript SDK enforces in Certificate.verify(), but which the Ruby implementation omits entirely. Two code paths are vulnerable: in acquisition_protocol: 'direct', the acquire_via_direct method in lib/bsv/wallet_interface/wallet_client.rb constructs a certificate hash from all caller-supplied fields (including signature:) and writes it to storage verbatim with no cryptographic check; in acquisition_protocol: 'issuance', acquire_via_issuance POSTs to a certifier URL and persists whatever signature the HTTP response body contains, also without verification. Because downstream operations list_certificates and prove_certificate treat stored records as valid without re-verifying, any forgery that bypasses acquire_certificate is permanently trusted (GitHub Advisory, Fix PR #306).

Impact

Successful exploitation allows an authenticated attacker to forge identity certificates attributed to any arbitrary certifier identity key, containing arbitrary fields, and have them persisted as authentic in the wallet's certificate store. Applications relying on the wallet's certificate store as a source of truth for identity attributes — such as KYC assertions, role claims, or attestations — are subject to credential forgery, enabling impersonation of other identities or entities. Confidentiality is impacted because forged credentials presented via prove_certificate can assert false attributes about a subject; integrity is impacted because the wallet's credential store is polluted with attacker-controlled data. Availability is not affected (GitHub Advisory).

Exploitation steps

  1. Identify a target: Locate an application using bsv-sdk >= 0.3.1, < 0.8.2 or bsv-wallet >= 0.1.2, < 0.3.4 that exposes the acquire_certificate API to callers with at least low-privilege access.
  2. Choose an attack path: Select either the direct protocol (if you can call the API directly) or the issuance protocol (if you can control or MITM the certifier endpoint the client contacts).
  3. Forge a certificate via the direct path: Invoke acquire_certificate with acquisition_protocol: 'direct', supplying a claimed trusted certifier public key, arbitrary certificate fields (e.g., type: 'age-over-18', fields: { 'verified' => 'true' }), and a completely arbitrary signature: value (e.g., 'deadbeef' * 16). The SDK writes the record to storage verbatim without any cryptographic check.
  4. Alternatively, exploit the issuance path: Control or compromise a certifier endpoint targeted by the client's issuance flow, or perform a MITM attack on the plain HTTP POST. Return a crafted JSON response body containing an arbitrary signature value for any subject; the client will persist it without verification.
  5. Verify the forgery: Call list_certificates or prove_certificate with the claimed certifier's public key and certificate type. The forged record is returned as if it were a legitimately signed certificate from that certifier, enabling identity impersonation or false attribute assertion (GitHub Advisory).

Indicators of compromise

  • Application Logs: Unexpected calls to acquire_certificate with acquisition_protocol: 'direct' from untrusted or unusual callers; certificates stored with certifier public keys not belonging to any known, trusted certifier.
  • Certificate Store: Presence of certificate records whose signature field does not cryptographically verify against the claimed certifier's public key when checked out-of-band against the BRC-52 specification; certificates with implausible or repeated serial_number values (e.g., 'any-serial').
  • Network: Unexpected or anomalous HTTP POST requests to certifier issuance URLs, particularly over plain HTTP (non-TLS); responses from certifier endpoints containing unusual or malformed signature fields.
  • Behavioral: list_certificates or prove_certificate returning certificates for certifier keys not previously enrolled through a trusted issuance flow; applications granting elevated access or KYC-gated actions to identities that were not legitimately certified (GitHub Advisory).

Mitigation and workarounds

Upgrade to bsv-sdk >= 0.8.2 and/or bsv-wallet >= 0.3.4. Both patched releases introduce a new BSV::Wallet::CertificateSignature module that builds the BRC-52 canonical preimage and verifies the certifier's signature via ProtoWallet#verify_signature before any certificate is persisted; invalid certificates raise BSV::Wallet::CertificateSignature::InvalidError and are never written to storage. Note that bsv-wallet 0.3.4 also tightens its bsv-sdk dependency to >= 0.8.2, < 1.0 to enforce the known-good pairing. If immediate upgrade is not possible: restrict acquire_certificate access to fully trusted callers only; avoid using acquisition_protocol: 'issuance' against any certifier URL not fully trusted and require TLS for all such requests; and treat all records from list_certificates/prove_certificate as unverified, performing out-of-band BRC-52 signature verification before acting on them (GitHub Advisory, Fix PR #306).

Community reactions

The vulnerability was identified internally during a 2026-04-08 cross-SDK compliance review, with the project's Security Specialist characterizing it as "the most urgent fix in this review" that "should block the next release," and the Cryptography Specialist describing it as "a signature-verification bypass masquerading as an API finding — treat as P0 security." The fix received a unanimous 8-0 project team vote to prioritize. Social media activity was limited to automated CVE tracking posts on Bluesky and Mastodon (GitHub Issue #305).

Additional resources


SourceThis report was generated using AI

Related Ruby vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2016-1000305MEDIUM6.9
  • Ruby logoRuby
  • guard-livereload
NoYesJul 31, 2026
CVE-2026-45377MEDIUM6.5
  • Ruby logoRuby
  • decidim-core
NoYesJul 31, 2026
CVE-2026-45376MEDIUM5.5
  • Ruby logoRuby
  • decidim-admin
NoYesJul 31, 2026
CVE-2026-45086MEDIUM5.4
  • Ruby logoRuby
  • decidim-demographics
NoYesJul 31, 2026
CVE-2026-45330MEDIUM4.9
  • Ruby logoRuby
  • decidim-verifications
NoYesJul 31, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management