Every CVE Search/ Get API key

CVE-2026-40070

bsv-sdk and bsv-wallet persist unverified certifier signatures in acquire_certificate (direct and issuance paths)

8.1 HighFix available

BSV Ruby SDK is the Ruby SDK for the BSV blockchain. From 0.3.1 to before 0.8.2, BSV::Wallet::WalletClient#acquire_certificate persists certificate records to storage without verifying the certifier's signature over the certificate contents. In acquisition_protocol: 'direct', the caller supplies all certificate fields (including signature:) and the record is written to storage verbatim. In acquisition_protocol: 'issuance', the client POSTs to a certifier URL and writes whatever signature the response body contains, also without verification. An attacker who can reach either API (or who controls a certifier endpoint targeted by the issuance path) can forge identity certificates that subsequently appear authentic to list_certificates and prove_certificate.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
None

Exploit likelihood

0.14%Up 0.1 points since Apr 10, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.1

bsv-sdk and bsv-wallet persist unverified certifier signatures in acquire_certificate (direct and issuance paths)

BSV Ruby SDK is the Ruby SDK for the BSV blockchain. From 0.3.1 to before 0.8.2, BSV::Wallet::WalletClient#acquire_certificate persists certificate records to storage without verifying the certifier's signature over the certificate contents. In acquisition_protocol: 'direct', the caller supplies all certificate fields (including signature:) and the record is written to storage verbatim. In acquisition_protocol: 'issuance', the client POSTs to a certifier URL and writes whatever signature the response body contains, also without verification. An attacker who can reach either API (or who controls a certifier endpoint targeted by the issuance path) can forge identity certificates that subsequently appear authentic to list_certificates and prove_certificate.

Record
CVE-2026-40070
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-347
Updated
2026-11-02
EUVDEUVD-2026-20996 8.1

BSV Ruby SDK is the Ruby SDK for the BSV blockchain. From 0.3.1 to before 0.8.2, BSV::Wallet::WalletClient#acquire_certificate persists certificate records to storage without verifying the certifier's signature over the certificate contents. In acquisition_protocol: 'direct', the caller supplies all certificate fields (including signature:) and the record is written to storage verbatim. In acquisition_protocol: 'issuance', the client POSTs to a certifier URL and writes whatever signature the response body contains, also without verification. An attacker who can reach either API (or who controls a certifier endpoint targeted by the issuance path) can forge identity certificates that subsequently appear authentic to list_certificates and prove_certificate.

Record
EUVD-2026-20996
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-hc36-c89j-5f4j 8.1

bsv-sdk and bsv-wallet persist unverified certifier signatures in acquire_certificate (direct and issuance paths)

Unverified certifier signatures persisted by acquire_certificate

Affected packages

Both bsv-sdk and bsv-wallet are published from the sgbett/bsv-ruby-sdk repository. The vulnerable code lives in lib/bsv/wallet_interface/wallet_client.rb, which is physically shipped inside both gems (the bsv-wallet.gemspec files list bundles the entire lib/bsv/wallet_interface/ tree). Consumers of either gem are independently vulnerable; the two packages are versioned separately, so each has its own affected range.

| Package | Affected | Patched | | --- | --- | --- | | bsv-sdk | >= 0.3.1, < 0.8.2 | 0.8.2 | | bsv-wallet | >= 0.1.2, < 0.3.4 | 0.3.4 |

Summary

BSV::Wallet::WalletClient#acquire_certificate persists certificate records to storage without verifying the certifier's signature over the certificate contents. Both acquisition paths are affected:

  • acquisition_protocol: 'direct' — the caller supplies all certificate fields (including signature:) and the record is written to storage verbatim.
  • acquisition_protocol: 'issuance' — the client POSTs to a certifier URL and writes whatever signature the response body contains, also without verification.

An attacker who can reach either API (or who controls a certifier endpoint targeted by the issuance path) can forge identity certificates that subsequently appear authentic to list_certificates and prove_certificate.

Details

BRC-52 requires a certificate's signature field to be verified against the claimed certifier's public key over a canonical hashing of (type, subject, serialNumber, revocationOutpoint, fields) before the certificate is trusted. The reference TypeScript SDK enforces this in Certificate.verify().

Direct path

The Ruby implementation's acquire_via_direct path (lib/bsv/wallet_interface/wallet_client.rb) constructs the certificate record directly from caller-supplied fields:

def acquire_via_direct(args)
  {
    type: args[:type],
    subject: @key_deriver.identity_key,
    serial_number: args[:serial_number],
    certifier: args[:certifier],
    revocation_outpoint: args[:revocation_outpoint],
    signature: args[:signature],
    fields: args[:fields],
    keyring: args[:keyring_for_subject]
  }
end

The returned record is then written to the storage adapter by acquire_certificate. No verification of args[:signature] against args[:certifier]'s public key occurs at any point in this path.

Issuance path

acquire_via_issuance POSTs to a certifier-supplied URL and parses the response body into a certificate record, which is then written to storage without verifying the returned signature. A hostile or compromised certifier endpoint — or anyone able to redirect/MITM the plain HTTP request — can therefore return an arbitrary signature value for any subject and have it stored as authentic. This is the same class of bypass as the direct path; it was tracked separately as finding F8.16 in the compliance review and is closed by the same fix.

Downstream impact

Downstream reads via list_certificates and selective-disclosure via prove_certificate treat stored records as valid without re-verifying, so any forgery that slips past acquire_certificate is trusted permanently.

Impact

Any caller that can invoke acquire_certificate — via either acquisition protocol — can forge a certificate attributed to an arbitrary certifier identity key, containing arbitrary fields, and have it persisted as authentic. Applications and downstream gems that rely on the wallet's certificate store as a source of truth for identity attributes (e.g. KYC assertions, role claims, attestations) are subject to credential forgery.

This is a credential-forgery primitive, not merely a spec divergence from BRC-52.

CVSS rationale

AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N → 8.1 (High)

  • AV:N — network-reachable in any wallet context…
Record
GHSA-hc36-c89j-5f4j
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-347
Updated
2026-11-02
NVD 8.1

BSV Ruby SDK is the Ruby SDK for the BSV blockchain. From 0.3.1 to before 0.8.2, BSV::Wallet::WalletClient#acquire_certificate persists certificate records to storage without verifying the certifier's signature over the certificate contents. In acquisition_protocol: 'direct', the caller supplies all certificate fields (including signature:) and the record is written to storage verbatim. In acquisition_protocol: 'issuance', the client POSTs to a certifier URL and writes whatever signature the response body contains, also without verification. An attacker who can reach either API (or who controls a certifier endpoint targeted by the issuance path) can forge identity certificates that subsequently appear authentic to list_certificates and prove_certificate.

Record
CVE-2026-40070
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-347
Updated
2026-11-02
OSV 8.1

bsv-sdk and bsv-wallet persist unverified certifier signatures in acquire_certificate (direct and issuance paths)

BSV Ruby SDK is the Ruby SDK for the BSV blockchain. From 0.3.1 to before 0.8.2, BSV::Wallet::WalletClient#acquire_certificate persists certificate records to storage without verifying the certifier's signature over the certificate contents. In acquisition_protocol: 'direct', the caller supplies all certificate fields (including signature:) and the record is written to storage verbatim. In acquisition_protocol: 'issuance', the client POSTs to a certifier URL and writes whatever signature the response body contains, also without verification. An attacker who can reach either API (or who controls a certifier endpoint targeted by the issuance path) can forge identity certificates that subsequently appear authentic to list_certificates and prove_certificate.

Record
CVE-2026-40070
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-347
Updated
2026-11-02
OSVGHSA-hc36-c89j-5f4j 8.1

bsv-sdk and bsv-wallet persist unverified certifier signatures in acquire_certificate (direct and issuance paths)

Unverified certifier signatures persisted by acquire_certificate

Affected packages

Both bsv-sdk and bsv-wallet are published from the sgbett/bsv-ruby-sdk repository. The vulnerable code lives in lib/bsv/wallet_interface/wallet_client.rb, which is physically shipped inside both gems (the bsv-wallet.gemspec files list bundles the entire lib/bsv/wallet_interface/ tree). Consumers of either gem are independently vulnerable; the two packages are versioned separately, so each has its own affected range.

| Package | Affected | Patched | | --- | --- | --- | | bsv-sdk | >= 0.3.1, < 0.8.2 | 0.8.2 | | bsv-wallet | >= 0.1.2, < 0.3.4 | 0.3.4 |

Summary

BSV::Wallet::WalletClient#acquire_certificate persists certificate records to storage without verifying the certifier's signature over the certificate contents. Both acquisition paths are affected:

  • acquisition_protocol: 'direct' — the caller supplies all certificate fields (including signature:) and the record is written to storage verbatim.
  • acquisition_protocol: 'issuance' — the client POSTs to a certifier URL and writes whatever signature the response body contains, also without verification.

An attacker who can reach either API (or who controls a certifier endpoint targeted by the issuance path) can forge identity certificates that subsequently appear authentic to list_certificates and prove_certificate.

Details

BRC-52 requires a certificate's signature field to be verified against the claimed certifier's public key over a canonical hashing of (type, subject, serialNumber, revocationOutpoint, fields) before the certificate is trusted. The reference TypeScript SDK enforces this in Certificate.verify().

Direct path

The Ruby implementation's acquire_via_direct path (lib/bsv/wallet_interface/wallet_client.rb) constructs the certificate record directly from caller-supplied fields:

def acquire_via_direct(args)
  {
    type: args[:type],
    subject: @key_deriver.identity_key,
    serial_number: args[:serial_number],
    certifier: args[:certifier],
    revocation_outpoint: args[:revocation_outpoint],
    signature: args[:signature],
    fields: args[:fields],
    keyring: args[:keyring_for_subject]
  }
end

The returned record is then written to the storage adapter by acquire_certificate. No verification of args[:signature] against args[:certifier]'s public key occurs at any point in this path.

Issuance path

acquire_via_issuance POSTs to a certifier-supplied URL and parses the response body into a certificate record, which is then written to storage without verifying the returned signature. A hostile or compromised certifier endpoint — or anyone able to redirect/MITM the plain HTTP request — can therefore return an arbitrary signature value for any subject and have it stored as authentic. This is the same class of bypass as the direct path; it was tracked separately as finding F8.16 in the compliance review and is closed by the same fix.

Downstream impact

Downstream reads via list_certificates and selective-disclosure via prove_certificate treat stored records as valid without re-verifying, so any forgery that slips past acquire_certificate is trusted permanently.

Impact

Any caller that can invoke acquire_certificate — via either acquisition protocol — can forge a certificate attributed to an arbitrary certifier identity key, containing arbitrary fields, and have it persisted as authentic. Applications and downstream gems that rely on the wallet's certificate store as a source of truth for identity attributes (e.g. KYC assertions, role claims, attestations) are subject to credential forgery.

This is a credential-forgery primitive, not merely a spec divergence from BRC-52.

CVSS rationale

AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N → 8.1 (High)

  • AV:N — network-reachable in any wallet context…
Record
GHSA-hc36-c89j-5f4j
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-347
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
bsv-sdk
RubyGems
0.3.1 up to 0.8.2
0.8.2
bsv-wallet
RubyGems
0.1.2 up to 0.3.4
0.3.4
bsv-sdk
RubyGems
0.3.1 up to 0.8.2, plus listed versions
0.3.20.4.00.5.00.6.00.6.1
Show 4 moreShow less
0.6.20.7.00.8.00.8.1
0.8.2
bsv-wallet
RubyGems
0.1.2 up to 0.3.4, plus listed versions
0.2.00.2.10.2.20.3.00.3.10.3.20.3.3
0.3.4

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-40070 is a high vulnerability (CVSS 8.1) in Sgbett Bsv-sdk, published April 9, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.14%, the 3rd percentile. Fixed in bsv-sdk 0.8.2.

References

Show 5 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open