Mar 31, 2026·6 min read·29 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.
containerd is an open-source container runtime. Prior to versions 1.7.36, 2.0.13, 2.2.9, 2.3.6, and 2.4.1, a crafted OCI index graph can force very high CPU/memory usage during PullImage (before container start), causing long ContainerCreating stalls and, at larger sizes, node/runtime instability. The vulnerability occurs because containerd's image-pull descriptor graph resolution handlers processed OCI image indices and manifests recursively without enforcing boundaries on traversal depth or breadth, and without maintaining a global visited registry to count duplicate references.
An unauthenticated path traversal vulnerability exists in the Khoj AI assistant platform via the static file serving endpoint `/home/{file_path:path}`. Due to improper path sanitization when handling user input with Python's pathlib module, a remote attacker can read arbitrary files from the server's filesystem.
An argument injection vulnerability (CWE-88) in CliInvoke and AlastairLundy.CliInvoke allows local attackers to execute arbitrary system commands. By injecting double-quote characters into target file paths or arguments, attackers can terminate operating-system-level quoted boundaries and introduce new commands when shell runners are utilized.
An OS command injection vulnerability exists in the PowerShell and Cmd shell wrappers of the CliInvoke .NET library (specifically the CliInvoke.Specializations package). Under vulnerable configurations, arguments and targets are passed as a single flat string to ProcessStartInfo.Arguments, permitting double-quote breakout and execution of arbitrary secondary commands with host process privileges.
A critical-severity input validation vulnerability in the Elixir multi-party payment library `mpp` allows unauthenticated remote attackers to exhaust the transaction fee payer's wallet balance. By submitting a crafted Ethereum transaction envelope with artificially inflated gas parameters, an attacker can force the server to co-sign and commit to pay exorbitant fees, leading to severe financial loss and Denial of Service.
A critical gas draining vulnerability exists in the ZenHive mpp (Multi-Payment Protocol) library prior to version v0.6.0. By omitting validation of EIP-2930 access lists in custom 0x76 transaction envelopes, the library allows malicious clients to pad transaction payloads with dummy addresses, draining the gas sponsor's hot wallet.