CVE-2026-104437
Zebra before 4.4.0 Consensus Split via SIGHASH_SINGLE Missing-Output Handling
Zebra before 4.4.0 contains a consensus divergence vulnerability in V5 transparent signature verification, computing a ZIP-244 digest for SIGHASH_SINGLE inputs lacking corresponding outputs instead of failing. Attackers can craft V5 transactions with fewer outputs than inputs that Zebra accepts and templates via getblocktemplate, producing blocks zcashd rejects.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.3
Zebra before 4.4.0 Consensus Split via SIGHASH_SINGLE Missing-Output Handling
Zebra before 4.4.0 contains a consensus divergence vulnerability in V5 transparent signature verification, computing a ZIP-244 digest for SIGHASH_SINGLE inputs lacking corresponding outputs instead of failing. Attackers can craft V5 transactions with fewer outputs than inputs that Zebra accepts and templates via getblocktemplate, producing blocks zcashd rejects.
- Record
CVE-2026-104437- CVSS 4.0
- 8.3 High
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N - CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H - Weakness
- CWE-347
- Updated
- 2026-11-02
EUVDEUVD-2026-91447
8.3
Zebra before 4.4.0 contains a consensus divergence vulnerability in V5 transparent signature verification, computing a ZIP-244 digest for SIGHASH_SINGLE inputs lacking corresponding outputs instead of failing. Attackers can craft V5 transactions with fewer outputs than inputs that Zebra accepts and templates via getblocktemplate, producing blocks zcashd rejects.
- Record
EUVD-2026-91447- CVSS 4.0
- 8.3 High
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-cwfq-rfcr-8hmp
9.2
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: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. Zebraconverts the decoded hash type and asks its Rust sighash engine for a digest without adding the corresponding-output pre-check thatzcashdenforces first:zebra/zebra-script/src/lib.rs,zebra/zebra-chain/src/primitives/zcash_primitives.rs.Zebraforwards canonicalSIGHASH_SINGLEinto the Rust ZIP-244 implementation.- In that implementation, when
input.index() >= bundle.vout.len(), the code usestransparent_outputs_hash::<TxOut>(&[])instead of erroring:zcash_primitives/src/transaction/sighash_v5.rs,zcash_primitives/src/transaction/sighash_v5.rs.
Why this is exploitable:
- the malformed transaction only needs fewer transparent outputs than inputs;
- the attacker signs the digest that
Zebracomputes for the missing-output case; Zebrathen sees a valid transparent signature, whilezcashdnever reaches the same digest because it fails first.
Ordinary path viability:
zcashdordinary mempool admission is not the practical trigger path, because the same ZIP-244SignatureHash()checks fail there first:zcash/src/main.cpp,zcash/src/script/interpreter.cpp.…
- Record
GHSA-cwfq-rfcr-8hmp- CVSS 4.0
- 9.2 Critical
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 - Weakness
- CWE-354, CWE-573
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-wc6w-gfmg-rf5p
8.3
Zebra before 4.4.0 contains a consensus divergence vulnerability in V5 transparent signature...
Zebra before 4.4.0 contains a consensus divergence vulnerability in V5 transparent signature verification, computing a ZIP-244 digest for SIGHASH_SINGLE inputs lacking corresponding outputs instead of failing. Attackers can craft V5 transactions with fewer outputs than inputs that Zebra accepts and templates via getblocktemplate, producing blocks zcashd rejects.
- Record
GHSA-wc6w-gfmg-rf5p- CVSS 4.0
- 8.3 High
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H - Weakness
- CWE-347
- Updated
- 2026-11-02
NVD
8.3
Zebra before 4.4.0 contains a consensus divergence vulnerability in V5 transparent signature verification, computing a ZIP-244 digest for SIGHASH_SINGLE inputs lacking corresponding outputs instead of failing. Attackers can craft V5 transactions with fewer outputs than inputs that Zebra accepts and templates via getblocktemplate, producing blocks zcashd rejects.
- Record
CVE-2026-104437- CVSS 4.0
- 8.3 High
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H - Weakness
- CWE-347
- Updated
- 2026-11-02
OSV
8.3
Zebra before 4.4.0 Consensus Split via SIGHASH_SINGLE Missing-Output Handling
Zebra before 4.4.0 contains a consensus divergence vulnerability in V5 transparent signature verification, computing a ZIP-244 digest for SIGHASH_SINGLE inputs lacking corresponding outputs instead of failing. Attackers can craft V5 transactions with fewer outputs than inputs that Zebra accepts and templates via getblocktemplate, producing blocks zcashd rejects.
- Record
CVE-2026-104437- CVSS 4.0
- 8.3 High
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-347
- Updated
- 2026-11-02
OSVGHSA-cwfq-rfcr-8hmp
9.2
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: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. Zebraconverts the decoded hash type and asks its Rust sighash engine for a digest without adding the corresponding-output pre-check thatzcashdenforces first:zebra/zebra-script/src/lib.rs,zebra/zebra-chain/src/primitives/zcash_primitives.rs.Zebraforwards canonicalSIGHASH_SINGLEinto the Rust ZIP-244 implementation.- In that implementation, when
input.index() >= bundle.vout.len(), the code usestransparent_outputs_hash::<TxOut>(&[])instead of erroring:zcash_primitives/src/transaction/sighash_v5.rs,zcash_primitives/src/transaction/sighash_v5.rs.
Why this is exploitable:
- the malformed transaction only needs fewer transparent outputs than inputs;
- the attacker signs the digest that
Zebracomputes for the missing-output case; Zebrathen sees a valid transparent signature, whilezcashdnever reaches the same digest because it fails first.
Ordinary path viability:
zcashdordinary mempool admission is not the practical trigger path, because the same ZIP-244SignatureHash()checks fail there first:zcash/src/main.cpp,zcash/src/script/interpreter.cpp.…
- Record
GHSA-cwfq-rfcr-8hmp- CVSS 4.0
- 9.2 Critical
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 - Weakness
- CWE-354, CWE-573
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
zebradcrates.io |
before 4.4.0 | 4.4.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-104437 is a high vulnerability (CVSS 8.3) in Zcashfoundation Zebra, published May 7, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.25%, the 16th percentile. Fixed in zebrad 4.4.0.
References
github.com/ZcashFoundation/zebra/security/advisories/GHSA-cwfq-rfcr-8hmp
vulncheck.com/advisories/zebra-before-4.4.0-consensus-split-via-sighash-single-missing-output-handling
github.com/ZcashFoundation/zebra/releases/tag/v4.4.0
github.com/advisories/GHSA-cwfq-rfcr-8hmp
nvd.nist.gov/vuln/detail/CVE-2026-104437
github.com/advisories/GHSA-wc6w-gfmg-rf5p
github.com/CVEProject/cvelistV5/tree/main/cves/2026/104xxx/CVE-2026-104437.json
github.com/ZcashFoundation/zebra
Left out here: the rest of 2 source descriptions. The JSON record has them.