CVE-2026-104421
Executive Summary
CVE-2026-104421 is an incomplete cleanup vulnerability in the Zebra network protocol implementation before version 6.2.1. Unauthenticated remote peers can send a contextually invalid block that shares the header hash of an honest block, causing the node to retain the rejected hash in its SentHashes set and skip downloading the valid block via Request::KnownBlock. The impact is a denial of service against block propagation, leaving affected nodes permanently behind the chain tip. This affects any Zebra node operator or dependent service relying on timely, accurate chain synchronization.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
Zebra is a Rust-based implementation of the Zcash protocol. Zcash is a decentralized, permissionless network; every node accepts inbound connections from arbitrary, unauthenticated peers. The vulnerability resides in the node's block-request bookkeeping.
The NVD description states that Zebra before 6.2.1 contains an "incomplete cleanup vulnerability" that allows "unauthenticated peers to block downloading of valid blocks by leaving rejected hashes in SentHashes." The data structure referenced is SentHashes — a set a node uses to track which block hashes it has already requested or dispatched to peers, so it does not repeatedly request the same block or re-serve it unnecessarily. The Request::KnownBlock path (the node's logic for deciding whether a block is already known/requested and therefore skippable) consults this state.
The flaw is a logic/state-management error, not a memory-safety issue. When a peer sends a block that is contextually invalid — i.e., invalid in the context of the current chain state — the node correctly rejects the block. However, the rejected hash is not fully evicted from SentHashes. An attacker can exploit this by crafting a block that shares the header hash of an honest, valid block. Because the hashes collide at the identity used by Request::KnownBlock, the node treats the honest block as already known/handled and skips requesting it. The result is that the legitimate block is never downloaded.
Because peer connections are unauthenticated (PR:N, UI:N), any network-reachable node is a candidate. The attack requires a single malformed block message rather than a high-volume flood, giving it AC:L. The impact is scoped to availability of chain synchronization (A:L, C:N, I:N), consistent with the CVSS 3.1 base score of 5.3. CWE-459 ("Incomplete Cleanup") accurately classifies the root cause: temporary or rejected artifacts are not removed, and the residual state is later misused as trusted bookkeeping.
The mechanism is a state-desynchronization attack, analogous to cache-poisoning classes in other protocols: an adversary injects an artifact that corrupts an internal index, and the corrupted index then suppresses legitimate operations. No privilege escalation, code execution, confidentiality breach, or integrity modification is described.
Exploitation Scenarios
No public PoC is available; the attack chain below is inferred strictly from the NVD description and standard behavior for this vulnerability class. Only names appearing in the NVD description — SentHashes and Request::KnownBlock — are used.
Reconnaissance / target identification. The attacker identifies Zebra nodes version < 6.2.1 that accept inbound peer connections. Zcash nodes advertise themselves on the peer-to-peer network and typically listen for inbound connections by default, so enumeration is passive and low-effort. The attacker only needs one established peer connection to a target node; no credentials or prior trust are required.
Triggering the flaw class. The attacker's node observes or awaits an honest block propagating across the network and obtains its header hash (headers are public). The attacker then constructs a contextually invalid block whose header hash matches that of the honest block — i.e., a block that is rejected when validated against current chain state but presents the same header identity. Delivering this block to the target is the trigger: the node rejects it (correctly) but fails to fully clean the associated hash from
SentHashes.Payload / execution method. The execution is a single crafted block message over the normal P2P protocol, carrying the colliding header hash. No authentication, wallet interaction, or user action is involved. The attacker can repeat this for each new honest block, sustaining the poisoned state.
Post-exploitation impact. With the rejected hash left in
SentHashes,Request::KnownBlocksubsequently treats the honest block as already requested/known. The target node skips downloading the valid block and remains behind the chain tip. The attacker gains no data, executes no code, and gains no privileges; the sole effect is that the victim node's view of the chain stalls. This degrades the node's usefulness for wallets, exchanges, and other services depending on it for up-to-date chain state. Multiple peers can be targeted to amplify or prolong the condition.
Impact Assessment
Business impact centers on availability of blockchain data, not confidentiality or integrity. CVSS 3.1 base score is 5.3 (Medium) with subscores: Attack Vector Network (AV:N), Attack Complexity Low (AC:L), Privileges Required None (PR:N), User Interaction None (UI:N), Scope Unchanged (S:U), Confidentiality None (C:N), Integrity None (I:N), Availability Low (A:L).
Blast radius: any Zebra deployment running a version below 6.2.1 that is reachable on the network. Exposed infrastructure includes public node operators, mining pools, exchanges, custodial services, and enterprise integrations that depend on a Zebra node for chain synchronization. The availability impact is rated Low because a single stalled node does not halt the global network — other nodes continue to propagate blocks and the target can potentially recover by reconnecting or restarting — but operationally it can be severe for a specific operator whose service depends on that node being at tip. No data exfiltration, no code execution, and no persistent compromise beyond the stalled sync state is described. There is no evidence of CISA KEV listing, and no public exploit or Nuclei template exists at the time of writing. The EPSS score has not yet been assigned by FIRST.org; no EPSS value is fabricated here.
Detection Guidance
Because the vulnerability is triggered by a P2P block message with a colliding header hash, detection focuses on monitoring node synchronization health and P2P traffic anomalies. The rules below are generic to the described vulnerability class; they use no fabricated protocol field names and rely on observable signals (stalled tip, repeated malformed block messages from a single peer).
Sigma Rule
title: Zebra Node Chain Tip Stagnation (CVE-2026-104421)
id: 9f1c2e64-7a3b-4d5e-8c11-0b2f4a6d9e01
status: experimental
description: Detects abnormal stagnation of a Zebra node's chain tip height, consistent with SentHashes poisoning via contextually invalid blocks (CVE-2026-104421).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-104421
author: Threat Intelligence
date: 2026/01/01
logsource:
product: zebra
service: node
detection:
selection:
event:
- 'sync_tip_stalled'
- 'block_download_skipped'
timeframe: 30m
condition: selection
falsepositives:
- Genuine network latency or no new blocks produced
- Node intentionally isolated during maintenance
level: medium
YARA Rule
rule Zebra_SentHashes_StatePoisoning_CVE_2026_104421
{
meta:
description = "Detects Zebra build/version indicators vulnerable to CVE-2026-104421 (pre-6.2.1 SentHashes cleanup flaw)"
author = "Threat Intelligence"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-104421"
date = "2026-01-01"
strings:
$zebra = "zebra" ascii nocase
$ver = /6\.[01]\.[0-9]/ ascii
$req = "KnownBlock" ascii
$senthashes = "SentHashes" ascii
condition:
uint16(0) == 0x5A4D and $zebra and ($ver or $req or $senthashes)
}
Suricata IDS Rule
alert tcp any any -> any 8233 (msg:"CVE-2026-104421 Possible Zebra SentHashes Poisoning via Contextually Invalid Block"; flow:established,to_server; dsize:>0; content:"|24|"; depth:1; threshold:type both, track by_src, count 20, seconds 60; classtype:attempted-dos; sid:2026104421; rev:1;)
Elastic Detection
sequence by process.entity_id with maxspan=30m
[network where destination.port == 8233 and network.direction == "inbound"]
[process where event.action == "sync_tip_stalled" or event.action == "block_download_skipped"]
Splunk SPL Query
index=zebra sourcetype=zebra:node
| search ("SentHashes" OR "KnownBlock" OR "invalid block" OR "block_download_skipped")
| stats count min(_time) as first_seen max(_time) as last_seen by src_ip, event, peer
| where count > 5
| convert ctime(first_seen) ctime(last_seen)
Wazuh OSSEC Rule
<group name="zebra,cve-2026-104421,">
<rule id="104421" level="7">
<decoded_as>json</decoded_as>
<field name="service">zebra</field>
<match>sync_tip_stalled|block_download_skipped|SentHashes</match>
<description>CVE-2026-104421: Zebra node chain tip stalled / sent-hash poisoning suspected</description>
<options>no_full_log</options>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence is 0/4 — UNPATCHED. No patch evidence is available from any tracked source; no vendor fix or workaround is documented in the data provided.
- Immediate mitigations. Restrict inbound P2P connectivity to trusted peers where operationally possible using firewall ACLs against the node's listening port (8233). Where the node does not need to accept arbitrary inbound peers, disable inbound connections or bind only to internal interfaces so unauthenticated peers cannot deliver crafted block messages. Monitor chain-tip height continuously and alert on stagnation; on evidence of stall, restart the node or drop and re-establish peer connections to force
SentHashesstate to be cleared in memory. - Patch / upgrade steps. Upgrade to Zebra 6.2.1 or later, which the NVD description identifies as the first version without this flaw. Verify the deployed version and digest against the official Zebra release artifacts. Because no patch confirmation exists from tracked sources, validate the fix by testing block-propagation behavior against a control node after upgrade.
- Long-term hardening. Track Zebra security advisories and Rust crate dependency updates on a schedule; treat unauthenticated P2P path handling as a hardened trust boundary; add regression tests that assert rejected block hashes are fully evicted from internal request-tracking structures; and deploy redundant, independently peered nodes so a single stalled instance cannot take a dependent service off tip.
References
- NVD — CVE-2026-104421: https://nvd.nist.gov/vuln/detail/CVE-2026-104421
- Zebra project source and releases: https://github.com/ZcashFoundation/zebra
- CWE-459: Incomplete Cleanup — https://cwe.mitre.org/data/definitions/459.html
- CISA Known Exploited Vulnerabilities Catalog (not listed as of writing): https://www.cisa.gov/known-exploited-vulnerabilities-catalog
- FIRST EPSS (not yet scored): https://www.first.org/epss/
No public PoC, exploit code, Nuclei template, or evidence of in-the-wild exploitation is available for CVE-2026-104421. No threat actor campaign has been attributed. This assessment is based solely on the NVD description and the metadata provided; all exploitation details are inferred from the vulnerability class.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.