CVE-2026-52739
Rust vulnerability analysis and mitigation

Overview

CVE-2026-52739 is a denial-of-service vulnerability in the Zebra Zcash node implementation (zebrad) caused by an incorrect operation ordering in the non-finalized chain state handler. When a child block repeats a shielded transaction already present in its non-finalized parent, an internal assert_eq! fires before the duplicate-nullifier contextual validation can cleanly reject the block, causing the process to abort under Zebra's panic = "abort" release profile. All default configurations of zebrad up to and including v4.4.1 (and zebra-state up to and including v6.0.0) are affected, provided the node is processing blocks past the checkpoint height with NU5 or later activated. The vulnerability was reported by @haxatron via email disclosure, first published May 29, 2026, and carries a CVSS v3.1 base score of 5.9 (Medium) (GitHub Advisory, Zebra Advisory).

Technical details

The root cause is an incorrect behavior order (CWE-696) combined with a reachable assertion (CWE-617) in zebra-state/src/service/non_finalized_state/chain.rs at lines 1608–1628. The Chain::push function inserts the transaction hash into the tx_loc_by_hash index with an assert_eq!(prior_pair, None, "transactions must be unique within a single chain") check before it processes shielded data and runs the duplicate shielded-nullifier guard. When a child block contains a shielded V5 transaction that duplicates one from its non-finalized parent, the transaction hash is already present in tx_loc_by_hash, causing the assertion to fire and abort the process. The nullifier uniqueness check that would have cleanly rejected the block (step 3 in the push sequence) is never reached. Additionally, the block transaction verifier's best-chain nullifier query is gated on mempool transactions only (zebra-consensus/src/transaction.rs:521-526), and initial contextual validation only checks nullifiers in finalized state (zebra-state/src/service/check.rs:407-415), leaving the non-finalized state gap unguarded (GitHub Advisory, Zebra Advisory).

Impact

Successful exploitation causes an immediate, unrecoverable process abort of the zebrad node — the process must be manually restarted. There is no confidentiality or integrity impact; the vulnerability is purely a liveness (availability) issue. Repeated attacks can keep a targeted Zebra node offline for extended periods, effectively denying it participation in the Zcash network. Notably, this is not a consensus divergence: zcashd cleanly rejects the invalid child block, while Zebra aborts, meaning only Zebra nodes are affected (GitHub Advisory, Zebra Advisory).

Exploitability

Two attack models are documented. In Model A, the attacker mines two consecutive valid-work blocks where the child repeats a shielded transaction from the parent; at 10% hashrate this yields approximately 11.5 crash opportunities per day. In Model B (cheaper), the attacker broadcasts a shielded transaction into the mempool, waits for any honest miner to include it in block B1, then mines only the follow-up child block B2 repeating the same transaction; at 10% hashrate this yields approximately 14.4 opportunities per day. No public exploit code or in-the-wild exploitation has been reported. The CVE status is listed as "Reserved" and no EPSS score or CISA KEV catalog entry is currently available (GitHub Advisory, Zebra Advisory).

Exploitation steps

  1. Reconnaissance: Identify target Zebra nodes running zebrad v4.4.1 or earlier that are synced past the checkpoint height on a network with NU5 or later activated (all default configurations qualify).
  2. Prepare shielded transaction: Craft or obtain a valid shielded-only V5 transaction T (e.g., a Sapling or Orchard transaction) with valid proof and spend authorization.
  3. Model B — broadcast to mempool: Broadcast transaction T to the Zcash network mempool and wait for any honest miner to include it in a block B1. Monitor the chain for inclusion.
  4. Mine child block: Once T is confirmed in B1 (still in non-finalized state on the target node), mine a child block B2 that includes the same transaction T again. The child block must have valid proof-of-work.
  5. Propagate malicious block: Broadcast B2 to the network so that target Zebra nodes receive and attempt to process it via Chain::push.
  6. Trigger abort: When the target node processes B2, Chain::push inserts T's hash into tx_loc_by_hash and hits the assert_eq! before the nullifier check runs, causing an immediate process abort under the panic = "abort" release profile.
  7. Repeat: Restart the attack each time the node operator restarts zebrad to maintain a sustained denial of service (GitHub Advisory, Zebra Advisory).

Indicators of compromise

  • Process: Sudden, unclean termination of the zebrad process with no graceful shutdown; process exit code consistent with SIGABRT or abort signal rather than a normal exit.
  • Logs: Rust panic/abort messages in zebrad logs referencing "transactions must be unique within a single chain" or the assertion at zebra-state/src/service/non_finalized_state/chain.rs:1608–1628; log entries showing a block being pushed to the non-finalized chain immediately before the crash.
  • Network: Receipt of a child block whose transaction set contains a shielded V5 transaction hash already present in the parent block on the same non-finalized chain; repeated block announcements from the same peer(s) shortly before each crash event.
  • Operational: Repeated unexpected restarts of the zebrad service; monitoring alerts for process crashes correlated with specific block heights in the non-finalized state (GitHub Advisory).

Mitigation and workarounds

Upgrade to zebrad v4.5.0 and zebra-state v7.0.0, which replace the panicking assert_eq! with an Entry-based check that returns a ValidateContextError::DuplicateTransaction error instead of aborting the process. There is no configuration-level workaround — the vulnerable assertion is in the non-finalized state push path exercised by all block processing past the checkpoint height. Node operators should prioritize upgrading immediately, as all default configurations are affected (GitHub Advisory, Zebra Advisory).

Community reactions

The vulnerability was reported by security researcher @haxatron via email disclosure and coordinated by the Zcash Foundation team (mpguerra as coordinator, conradoplg as remediation developer). The advisory was first published internally on May 29, 2026, and publicly disclosed to the GitHub Advisory Database on July 2, 2026. No significant broader media coverage or social media discussion has been identified beyond the official advisory (GitHub Advisory, Zebra Advisory).

Additional resources


SourceThis report was generated using AI

Related Rust vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-52829HIGH7.5
  • Rust logoRust
  • zebra-network
NoYesAug 18, 2026
CVE-2026-52834HIGH7.3
  • Rust logoRust
  • jxl-grid
NoYesAug 19, 2026
GHSA-vjf8-9fx6-mv6xMEDIUM6.9
  • Rust logoRust
  • triton-vm
NoYesAug 18, 2026
GHSA-qwgh-2vcv-g2f7MEDIUM6.3
  • Rust logoRust
  • block_buffer
NoYesAug 19, 2026
CVE-2026-52739MEDIUM5.9
  • Rust logoRust
  • zebrad
NoYesAug 18, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management