Mar 31, 2026·6 min read·3 visits
Zebra nodes prior to version 4.3.0 improperly cache Zcash V5 transactions using only the non-authorizing `txid`. A malicious miner can exploit this to bypass signature verification, causing a hard fork from the main Zcash network.
A logic error in the Zebra transaction verification cache for Zcash V5 transactions leads to improper signature validation. By exploiting the discrepancy between the mined transaction ID and the full authorization root, a malicious miner can force vulnerable Zebra nodes to accept invalid blocks, resulting in a network consensus split.
The Zcash Network Upgrade 5 (NU5) introduced V5 transactions, which strictly separate effect-specifying data from cryptographic authorization data. Zebra, an independent Zcash node implementation, utilizes the zebra-consensus crate to validate these transactions against the network's consensus rules.
To improve block validation performance, Zebra implements a verification cache for unmined transactions residing in the mempool. This mechanism is designed to skip redundant cryptographic checks for transactions that the node has already verified.
The caching mechanism incorrectly relied solely on the txid (mined ID) as the lookup key. The txid commits to the transaction's effects but explicitly excludes the authorization data, such as signatures and zero-knowledge proofs.
This discrepancy created a vulnerability where an attacker could substitute valid authorization data with invalid data within a mined block. Vulnerable nodes process the block, encounter a cache hit based on the txid, and accept the invalid block without executing the requisite cryptographic verification.
The vulnerability originates from a misalignment between the ZIP-244 specification and Zebra's implementation of the find_verified_unmined_tx function. ZIP-244 defines two distinct transaction identifiers for V5 transactions: the txid and the wtxid (Auth Root). The txid provides a non-malleable hash of the transaction inputs and outputs, whereas the wtxid encompasses the authorization data.
The find_verified_unmined_tx function in zebra-consensus/src/transaction.rs determines if a newly received transaction matches a previously verified transaction in the mempool. Prior to version 4.3.0, the function queried the cache using the tx_mined_id (the txid).
When a node receives a new block, it iterates through the block's transactions and queries this cache. A cache hit instructs the consensus engine that the transaction is known-good, allowing the node to bypass the computationally expensive check_v5_auth() routine.
Because the txid does not commit to the signatures, an attacker can construct a transaction with identical inputs and outputs but structurally invalid signatures. The vulnerable cache logic observes the matching txid, incorrectly infers that the entire transaction is valid, and entirely omits the authorization check for that transaction within the block context.
The vulnerable code path resided in zebra-consensus/src/transaction.rs. The cache lookup directly utilized req.tx_mined_id() to retrieve verified transactions. If a transaction with the same mined ID existed in the cache, the function returned success, bypassing further authorization checks.
Commit 2429f97f75e80194c1964d79115cdc563d043307 resolves the issue by enforcing a strict equality check on the full transaction identifier. The lookup key was changed from req.tx_mined_id() to req.tx_id(), ensuring the authorization digest is included in the comparison.
// Vulnerable implementation
let tx_id = req.tx_mined_id();
let verified_tx = cache.get(&tx_id);
// Bypasses auth check if verified_tx is Some
// Patched implementation
let tx_id = req.tx_id();
let verified_tx = cache.get(&tx_id);
if verified_tx.transaction.id != tx_id {
return None; // Fall back to full verification
}The patch introduces a fallback mechanism. If the full tx_id does not match, the node discards the cache result and mandates a complete evaluation via check_v5_auth(). This guarantees that transactions with mutated authorization data undergo strict signature verification.
Exploiting this vulnerability requires the attacker to possess mining capabilities, as the malformed transaction must be included in a newly minted block. The attack vector is strictly network-based and relies on asynchronous mempool synchronization.
The attack proceeds in two stages. First, the attacker performs mempool poisoning by broadcasting a strictly valid Zcash V5 transaction. This transaction propagates across the network, and target Zebra nodes verify its signatures and insert it into their mempool caches, keyed by the txid.
Second, the attacker mines a block containing a modified version of the broadcasted transaction. The attacker strips the valid signatures and zero-knowledge proofs, replacing them with arbitrary or malformed data. Because the inputs and outputs remain unchanged, the txid of this modified transaction matches the txid of the valid transaction stored in the mempool.
When vulnerable Zebra nodes receive this crafted block, the cache logic triggers a false positive. The nodes skip the check_v5_auth() validation step, accept the block, and append it to their local blockchain. Patched nodes and zcashd nodes reject the block, resulting in a permanent consensus divergence.
The primary consequence of successful exploitation is a network-wide consensus split. Vulnerable Zebra nodes accept the attacker's invalid block and begin building on a parallel, invalid chain. They completely diverge from the main Zcash network composed of zcashd instances and patched Zebra nodes.
This divergence partitions the peer-to-peer network graph. Nodes operating on the invalid chain broadcast blocks and transactions that the main network rejects, creating a localized denial-of-service condition for the affected infrastructure. Transaction finality guarantees are voided for users connected to the vulnerable nodes.
Financial and operational risks manifest if downstream services rely on vulnerable Zebra nodes. An exchange or merchant operating a vulnerable node might recognize transactions as finalized on the invalid chain, exposing them to double-spend attacks or theft of funds once the consensus split is realized.
The assigned CVSS v4.0 score of 8.4 reflects the high impact on integrity and availability. While the attack complexity is low, the requirement for the attacker to successfully mine a block elevates the prerequisite privileges, gating widespread opportunistic exploitation.
The definitive remediation is upgrading to zebrad version 4.3.0, which incorporates zebra-consensus crate version 5.0.1. This release contains the deterministic fix that enforces full transaction identifier validation during cache lookups.
Node operators unable to immediately upgrade must monitor their node logs for indicators of a consensus split. Frequent occurrences of check_v5_auth() failures or elevated block rejection rates suggest that the node is receiving invalid blocks from peers operating on a forked chain.
The 4.3.0 release addresses additional consensus-critical bugs that require immediate attention. Commit aabb8b402fcd95bc15dea1def1d9777a67a030c4 resolves CWE-682, a calculation error where the Founders' Reward was not subtracted from the block subsidy, leading to inflated block rewards.
Furthermore, the upgrade enforces ZIP-235 requirements via commit 60a7124ad1f07a6475d73f76eee423c554453189. This change mandates the redirection of 60% of miner fees to the Non-Sourceable Minting (NSM) pool. Node operators running prior versions will eventually fall out of consensus due to these strict protocol enforcement changes regardless of targeted exploitation.
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:H/VA:H/SC:N/SI:H/SA:H| Product | Affected Versions | Fixed Version |
|---|---|---|
zebrad Zcash Foundation | < 4.3.0 | 4.3.0 |
zebra-consensus Zcash Foundation | < 5.0.1 | 5.0.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-347 |
| Attack Vector | Network |
| Privileges Required | High |
| CVSS v4.0 Base | 8.4 |
| Impact | High Integrity, High Availability |
| Exploit Status | Proof-of-Concept |
The software does not properly verify the cryptographic signature of data, allowing an attacker to spoof the data or bypass authentication.