🛡️ GHSA-cwfq-rfcr-8hmp — zebrad

🔴 CVSS 9.5 — Critical ✅ No Known Exploit CWE-354 OSV
9.5
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Zebra's Transparent SIGHASH_SINGLE Handling Diverges from zcashd for Corresponding Outputs

# Zebra Transparent SIGHASH_SINGLE Corresponding-Output Handling Diverges From zcashd

Summary

For V5+ transparent spends, Zebra and zcashd disagree on the same consensus rule: SIGHASH_SINGLE must fail when the input index has no corresponding output. zcashd treats this as consensus-invalid under ZIP-244, while Zebra's transparent verification path computes a digest for the missing-output case instead of failing.

The result is a direct block-validity split. A malformed V5 transparent transaction can be accepted by Zebra, retained in Zebra's mempool, selected into Zebra getblocktemplate, mined into a block, and then rejected by zcashd.

Details

Validated code revisions used during analysis:

  • zcashd: 2c63e9aa08cb170b0feb374161bea94720c3e1f5
  • Zebra: a905fa19e3a91c7b4ead331e2709e6dec5db12cb

Scope note:

  • earlier triage material grouped pre-V5 and V5 behavior together;
  • re-execution on the pinned revisions did not reproduce the claimed pre-V5 / V4 reject-side behavior;
  • this advisory therefore covers the V5+ / ZIP-244 variant only.

zcashd side:

  • Transparent scripts in blocks are checked through TransactionSignatureChecker::CheckSig() and SignatureHash(): [zcash/src/script/interpreter.cpp](https://github.com/zcash/zcash/blob/2c63e9aa08cb170b0feb374161bea94720c3e1f5/src/script/interpreter.cpp#L1386-L1407).
  • In the ZIP-244 branch, SignatureHash() explicitly throws when SIGHASH_SINGLE or SIGHASH_SINGLE|ANYONECANPAY is used with nIn >= txTo.vout.size(): [zcash/src/script/interpreter.cpp](https://github.com/zcash/zcash/blob/2c63e9aa08cb170b0feb374161bea94720c3e1f5/src/script/interpreter.cpp#L1221-L1259).
  • CheckSig() catches that exception and returns false, causing the transparent script to fail.

Zebra side:

  • V5 transparent inputs route into the same FFI-based transparent script verifier used for block validation: [zebra/zebra-consensus/src/transaction.rs](https://github.com/ZcashFoundation/zebra/blob/a905fa19e3a91c7b4ead331e2709e6dec5db12cb/zebra-consensus/src/transaction.rs#L989-L1098).
  • Zebra converts the decoded hash type and asks its Rust sighash engine for a digest without adding the corresponding-output pre-check that zcashd enforces first: [zebra/zebra-script/src/lib.rs](https://github.com/ZcashFoundation/zebra/blob/a905fa19e3a91c7b4ead331e2709e6dec5db12cb/zebra-script/src/lib.rs#L160-L175), [zebra/zebra-chain/src/primitives/zcash_primitives.rs](https://github.com/ZcashFoundation/zebra/blob/a905fa19e3a91c7b4ead331e2709e6dec5db12cb/zebra-chain/src/primitives/zcash_primitives.rs#L307-L343).
  • Zebra forwards canonical SIGHASH_SINGLE into the Rust ZIP-244 implementation.
  • In that implementation, when input.index() >= bundle.vout.len(), the code uses transparent_outputs_hash::<TxOut>(&[]) instead of erroring: [zcash_primitives/src/transaction/sighash_v5.rs](https://github.com/zcash/librustzcash/blob/c3425f9c3c7f6deb20720bb78b18f35fbbed8edd/zcash_primitives/src/transaction/sighash_v5.rs#L101-L107), [zcash_primitives/src/transaction/sighash_v5.rs](https://github.com/zcash/librustzcash/blob/c3425f9c3c7f6deb20720bb78b18f35fbbed8edd/zcash_primitives/src/transaction/sighash_v5.rs#L131-L139).

Why this is exploitable:

  • the malformed transaction only needs fewer transparent outputs than inputs;
  • the attacker signs the digest that Zebra computes for the missing-output case;
  • Zebra then sees a valid transparent signature, while zcashd never reaches the same digest because it fails first.

Ordinary path viability:

  • zcashd ordinary mempool admission is not the practical trigger path, because the same ZIP-244 SignatureHash() checks fail there first: [zcash/src/main.cpp](https://github.com/zcash/zcash/blob/2c63e9aa08cb170b0feb374161bea94720c3e1f5/src/main.cpp#L1981-L1995), [zcash/src/script/interpreter.cpp](https://github.com/zcash/zcash/blob/2c63e9aa08cb170b0feb374161bea94720c3e1f5/src/script/interpreter.cpp#L1221-L1259).
  • Zebra ordinary mempool admission is viable because Zebra uses the same transparent verifier for mempool and block validation and does not have a separate "one output per input" standardness rule here: [zebra/zebra-consensus/src/transaction.rs](https://github.com/ZcashFoundation/zebra/blob/a905fa19e3a91c7b4ead331e2709e6dec5db12cb/zebra-consensus/src/transaction.rs#L414-L519), [zebra/zebrad/src/components/mempool/storage.rs](https://github.com/ZcashFoundation/zebra/blob/a905fa19e3a91c7b4ead331e2709e6dec5db12cb/zebrad/src/components/mempool/storage.rs#L255-L376).
  • Zebra is a block-template producer, so the realistic stock path is Zebra mempool -> Zebra getblocktemplate -> external miner: [zebra/zebra-rpc/src/methods/types/get_block_template/zip317.rs](https://github.com/ZcashFoundation/zebra/blob/a905fa19e3a91c7b4ead331e2709e6dec5db12cb/zebra-rpc/src/methods/types/get_block_temp

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. No user interaction is required. Rated impact: confidentiality none, integrity high, availability none.

Weakness class

GHSA-cwfq-rfcr-8hmp is classified as CWE-354: Improper Validation of Integrity Check Value. A checksum or integrity value is not verified properly, so tampered data passes as intact.

Affected software

GHSA-cwfq-rfcr-8hmp is recorded against 1 package.

  • zebrad

Timeline and source

Published on 7 May 2026 and last revised on 21 May 2026. No public exploit is currently recorded for this entry. Record sourced from OSV.

References

github.com (Web)
github.com (Package)
github.com (Web)

Details

Severity CRITICAL
CVSS Score 9.5
CVSS Vector CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:H/SA:N
CWE CWE-354
Public Exploit ✅ No
Source OSV
Published 2026-05-07
Updated 2026-08-20
Modified 2026-05-21
Fix URL N/A

Affected Packages

Software From version Fixed in
zebrad

Similar Threats

Exploit Protection

Are you running zebrad?

GHSA-cwfq-rfcr-8hmp carries CVSS 9.5 Critical rating. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.

Check My Site For GHSA-cwfq-rfcr-8hmp →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.

Browse related advisories

All advisoriesGitHub AdvisoryGitHub Advisory Undated