Severity by source
AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:L
Trigger is network-level chain fork (AV:N, AC:H); no authentication required; persistent RocksDB integrity corruption justifies I:H, degraded wallet sync A:L, no confidentiality impact.
Primary rating from Vendor (https://github.com/ZcashFoundation/zebra).
CVSS VectorVendor: https://github.com/ZcashFoundation/zebra
Lifecycle Timeline
1DescriptionCVE.org
Am I affected
You are affected if:
- You run
zebradup to and includingv4.4.1. - Your node participates in a network where chain forks occur (mainnet, testnet, or any network with multiple miners).
All default configurations are affected. The corruption persists across restarts because it is written to RocksDB.
Summary
When pop_tip removes the tip block during a chain fork, stale Sapling and Orchard note commitment subtree root data is retained in the in-memory non-finalized state. When the chain subsequently finalizes, this stale data is written to the persistent RocksDB state. The corrupted subtree root history affects z_getsubtreesbyindex (used by lightwalletd for wallet synchronization) and could affect future chain verification that depends on correct subtree roots.
Details
The non-finalized state provides two methods for removing blocks: pop_root (removes the oldest block during finalization) and pop_tip (removes the newest block during a fork revert). pop_root correctly cleans up note commitment subtree contributions. pop_tip does not: it removes the block but retains the block's subtree root contributions in the in-memory state.
When a chain fork occurs and pop_tip reverts the old tip, the winning fork's chain is extended. When that chain is later finalized, the stale subtree data from the reverted blocks is included in the RocksDB write batch and persisted to disk.
The pop_root/pop_tip asymmetry is specific to subtree root handling. Other state managed by pop_tip (nullifiers, UTXOs, anchors, block hashes) uses different cleanup patterns that are not affected.
Patches
zebra-state 7.0.0 and zebrad 4.5.0.
The fix adds subtree root cleanup to pop_tip matching the pattern already used by pop_root.
Workarounds
There is no configuration-level workaround. Chain forks are natural events on any Proof-of-Work network. Operators can mitigate the downstream impact by periodically verifying subtree root consistency using z_getsubtreesbyindex against a known-good reference.
Impact
Persistent corruption of Sapling and Orchard subtree root history in the RocksDB state database. The corruption survives node restarts. Downstream consumers that rely on z_getsubtreesbyindex for wallet synchronization (primarily lightwalletd and light wallets) receive incorrect subtree roots. This does not directly affect consensus validation of new blocks but can cause wallet synchronization failures or incorrect wallet state. Recovery requires rebuilding the state database from scratch.
Credit
Reported by @dingledropper via a private GitHub Security Advisory submission.
AnalysisAI
Persistent RocksDB state corruption in zebrad up to v4.4.1 arises from an asymmetric cleanup bug in the non-finalized chain fork handler: pop_tip omits the Sapling and Orchard note commitment subtree root cleanup that pop_root correctly performs, causing stale subtree root entries to survive in memory and be flushed to disk during subsequent chain finalization. The corrupted subtree root history survives node restarts and is served to downstream consumers of z_getsubtreesbyindex - primarily lightwalletd and light wallets - causing wallet synchronization failures or incorrect wallet state that requires a full database rebuild to recover. No public exploit is identified at time of analysis and this vulnerability is not listed in CISA KEV; the risk is passive silent corruption accumulating on all unpatched nodes during routine chain fork events rather than adversarial exploitation.
Technical ContextAI
Zebra is the Zcash Foundation's Rust implementation of a Zcash full node, comprising the zebrad binary and the zebra-state crate (CPE: pkg:rust/zebrad, pkg:rust/zebra-state). The non-finalized state manager exposes two block-removal methods: pop_root, which removes the oldest block during finalization and correctly cleans up note commitment subtree root contributions, and pop_tip, which removes the newest block during fork reversion but omits the equivalent subtree root cleanup. This asymmetry is the CWE-459 (Incomplete Cleanup) root cause. When a chain fork occurs, pop_tip reverts the old tip block while leaving its Sapling and Orchard subtree root entries in the in-memory non-finalized state; when the winning fork is subsequently finalized, those stale entries are included in the RocksDB write batch and persisted. Other state types managed by pop_tip - nullifiers, UTXOs, anchors, block hashes - use independent cleanup patterns that are not affected. The corrupted z_getsubtreesbyindex output is consumed by lightwalletd for wallet synchronization, making operators who serve light wallet infrastructure the highest-impact targets.
RemediationAI
Upgrade to zebrad 4.5.0 and zebra-state 7.0.0, which add subtree root cleanup to pop_tip matching the existing pop_root cleanup pattern; this is the only complete fix. The vendor advisory is at https://github.com/ZcashFoundation/zebra/security/advisories/GHSA-2gf8-q9rr-jq3h. There is no configuration-level workaround because chain forks cannot be disabled on Proof-of-Work networks. As an interim operational measure, operators can periodically verify subtree root consistency by querying z_getsubtreesbyindex against a known-good reference node - this detects existing corruption but does not prevent or repair it, and adds operational overhead. If corruption is already present on a node running v4.4.1 or earlier, upgrading alone is insufficient; the RocksDB state database must also be rebuilt from scratch after upgrading. Nodes that do not serve lightwalletd or light wallet clients still accumulate silent state corruption and should upgrade to prevent future impact.
Same weakness CWE-459 – Incomplete Cleanup
View allSame technique Information Disclosure
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-61168
GHSA-2gf8-q9rr-jq3h