GHSA-cwfq-rfcr-8hmp - Zebra's Transparent SIGHASH_SINGLE Handling Diverges from zcashd for Correspondi
GHSA-cwfq-rfcr-8hmp - Zebra's Transparent SIGHASH_SINGLE Handling Diverges from zcashd for Correspondi
GHSA-cwfq-rfcr-8hmp CRITICAL rust/zebrad
CVE:
`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:2c63e9aa08cb170b0feb374161bea94720c3e1f5Zebra: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()andSignatureHash():zcash/src/script/interpreter.cpp. - In the ZIP-244 branch,
SignatureHash()explicitly throws whenSIGHASH_SINGLEorSIGHASH_SINGLE|ANYONECANPAYis used withnIn >= txTo.vout.size():zcash/src/script/interpreter.cpp. CheckSig()catches that exception and returnsfalse, 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/zeb
📌 来源: GitHub-Advisory | 📅 2026-05-07