CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-8M29-FPQ5-89JJ
8.8

GHSA-8M29-FPQ5-89JJ: Consensus Divergence in Zebra via Improper Sighash Hash-Type Handling

Amit Schendel
Amit Schendel
Senior Security Researcher

Apr 18, 2026·7 min read·1 visit

PoC Available

Executive Summary (TL;DR)

A consensus-breaking bug in Zebra's transaction verification logic allows an attacker to craft transactions that cause chain splits, risking network partitions and double-spend attacks.

The Zebra Zcash node implementation contains a critical consensus flaw in its handling of transparent transaction Sighash hash types. A refactoring error at the Foreign Function Interface (FFI) boundary omitted necessary validation checks, potentially causing a consensus split between Zebra nodes and the reference zcashd implementation.

Vulnerability Overview

The Zebra project provides an independent, Rust-based node implementation for the Zcash network. This component relies on the zebra-script crate to verify the validity of transparent transactions, which utilize a Bitcoin-style scripting system. Transparent transactions require signature hashing (Sighash) flags to specify precisely which components of a transaction are covered by a given cryptographic signature.

A critical vulnerability exists in the way Zebra validates these Sighash flags during script execution. Zebra fails to properly enforce protocol-defined consensus rules regarding acceptable hash types, causing its validation logic to diverge from the reference C++ implementation, zcashd. This flaw allows specially crafted transactions to pass Zebra's validation checks while being rightfully rejected by the rest of the network.

Consensus divergence bugs represent the most severe category of vulnerabilities in decentralized network architectures. When different node implementations disagree on the validity of a transaction or block, the network partitions into isolated sub-networks. This specific validation failure provides attackers with a mechanism to artificially induce these chain splits.

Root Cause Analysis

The root cause traces directly back to a structural refactoring of the transparent transaction verification logic. Zebra maintainers transitioned the system to use a Foreign Function Interface (FFI) boundary, moving transaction parsing and pre-processing into Rust code. The actual script execution remained delegated to the original C++ Bitcoin Script verification code via a callback mechanism.

During this architectural transition, developers failed to port a critical consensus rule restricting transparent transaction signatures to known hash types. The Rust caller omitted the explicit strict validation logic required by the Zcash protocol specification. Consequently, the system feeds unvalidated Sighash bytes into the C++ execution engine, bypassing security checks intended to prevent malformed signatures from being processed.

The vulnerability manifests differently depending on the transaction version. For V5 transactions introduced in the NU5 network upgrade, zcashd strictly validates Sighash types during the parsing phase. Zebra entirely omitted this parsing-phase validation for V5 inputs. For older V4 transactions, Zebra implemented flawed logic that incorrectly canonicalized the hash type during Sighash computation instead of using the raw Sighash value required by consensus rules.

This discrepancy means transactions with invalid, unknown, or malformed Sighash bytes successfully bypass Zebra's pre-processing checks. When the C++ engine subsequently processes the script using the parameters provided by the Rust interface, it evaluates the script as valid, leading to the consensus failure.

Code Analysis and FFI Boundary

The vulnerability resides primarily in the bridging logic between zebra-script and the C++ verification engine. The Rust implementation extracts transaction components, serializes them, and prepares the execution context for the C++ verifier. The failure occurs in how the Rust code handles the sighash_type field prior to invoking the FFI call.

// Conceptual representation of the vulnerable logic
fn verify_transparent_inputs(tx: &Transaction) -> Result<(), Error> {
    for input in tx.inputs() {
        // Flaw 1: V4 Canonicalization error mutates raw input
        let sighash = if tx.version == 4 {
            canonicalize_hash_type(input.sighash_type)
        } else {
            input.sighash_type
        };
        
        // Flaw 2: Missing V5 validation
        // No strict check against known SIGHASH flags before FFI
        ffi::bitcoin_script_verify(..., sighash)?;
    }
    Ok(())
}

The conceptual vulnerable code block demonstrates the two simultaneous failures. First, for V4 transactions, the canonicalize_hash_type function actively mutates the input byte, altering the consensus state rather than verifying it. Second, for all inputs, the code completely lacks an explicit allowlist check against known protocol-compliant Sighash flags before passing execution across the FFI boundary.

// Conceptual representation of the patched logic
fn verify_transparent_inputs(tx: &Transaction) -> Result<(), Error> {
    for input in tx.inputs() {
        let sighash = input.sighash_type;
        
        // Fix: Strict validation of raw Sighash flags
        if !is_valid_sighash_type(sighash, tx.version) {
            return Err(Error::InvalidSighashType);
        }
        
        ffi::bitcoin_script_verify(..., sighash)?;
    }
    Ok(())
}

The remediation requires moving strict bounds checking directly into the Rust pre-processing phase. The patched logic removes the improper V4 canonicalization step and implements an explicit is_valid_sighash_type validation check. This ensures the Rust layer enforces consensus rules identical to zcashd before delegating to the C++ execution engine.

Exploitation Methodology

Exploitation begins with an attacker constructing a transparent transaction that specifically targets the Sighash validation discrepancy. The attacker generates a transaction containing a signature flagged with an unknown or non-standard Sighash byte. This byte must be chosen such that it satisfies Zebra's missing or flawed validation logic while triggering an explicit rejection in the zcashd reference implementation.

The attacker then attempts to propagate this transaction to the Zcash network. Because standard zcashd nodes reject the transaction as invalid during initial parsing, it will not naturally propagate through the standard mempool layer. The attacker must directly peer with Zebra nodes or, more effectively, mine a block containing the malicious transaction and broadcast the completed block to the network.

Once the block is broadcast, the network partition occurs immediately upon processing. Zebra nodes parse the block, execute the flawed validation logic, and append the block to their local blockchain state. zcashd nodes parse the same block, identify the invalid Sighash flag, reject the block entirely, and ban the broadcasting peer.

This sequence cleanly isolates all Zebra nodes onto a distinct blockchain fork. An attacker leveraging this state can execute double-spend transactions by spending identical UTXOs on both the standard zcashd chain and the newly created Zebra fork, exploiting organizations that rely solely on Zebra's view of the network state.

Impact Assessment

A consensus bug represents a fundamental failure in a blockchain system, as it threatens the unified state of the decentralized ledger. The primary consequence of this vulnerability is a complete network partition. Zebra nodes will permanently diverge from the main Zcash chain until operators intervene, creating a fragmented ecosystem where nodes disagree on account balances and transaction histories.

The immediate risk falls on infrastructure providers, exchanges, block explorers, and merchants running Zebra nodes in isolation. These entities would silently transition to tracking a fraudulent ledger state. This opens financial service providers to direct monetary theft, as an attacker could deposit funds on the Zebra fork, exchange them for other assets, and simultaneously retain the original funds on the main zcashd chain.

The assigned CVSS 4.0 vector (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:H/SA:H) accurately models this threat. The attack vector is strictly network-based, requires no privileges or user interaction, and inflicts high integrity and availability impacts on both the vulnerable node and the subsequent downstream systems relying on that node's state.

The practical severity of this issue is partially mitigated by the current distribution of Zcash mining power. The overwhelming majority of Zcash miners operate the reference zcashd software. Consequently, the malicious fork initiated by Zebra nodes would lack sufficient hash rate to continue growing at the target block interval, likely causing the Zebra fork to stall shortly after the partition.

Remediation and Mitigation Strategies

Node operators must immediately update their binaries to the patched versions to maintain consensus with the Zcash network. Specifically, operators must upgrade zebrad to version 4.3.1 or later, and any custom integrations utilizing the zebra-script crate must bump their dependency to version 5.0.1 or later.

Due to the nature of consensus-level protocol rules, there are no viable configuration workarounds for this vulnerability. The flaw exists deep within the transaction parsing and execution logic. Modifying node configurations, adjusting network peers, or implementing external network filters cannot correct the internal validation logic of the binary.

Security teams managing critical blockchain infrastructure should implement robust monitoring to detect consensus divergence events in real-time. Operators should continuously cross-reference local block tips and chain heights between zebrad nodes and reference zcashd nodes. Any discrepancy in the accepted block hashes at the chain tip indicates a partition event requiring immediate automated isolation of the affected infrastructure.

Furthermore, organizations processing high-value transactions should design their architectures around heterogeneous node deployments. By requiring consensus across multiple independent implementations (zebrad and zcashd) before crediting user deposits, organizations can immunize their platforms against implementation-specific consensus bugs.

Official Patches

Zcash FoundationZebra Repository

Technical Appendix

CVSS Score
8.8/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:H/SA:H

Affected Systems

Zebra nodes (zebrad)Applications using zebra-script crateZcash Network (Secondary participant risk)

Affected Versions Detail

Product
Affected Versions
Fixed Version
zebrad
Zcash Foundation
< 4.3.14.3.1
zebra-script
Zcash Foundation
< 5.0.15.0.1
AttributeDetail
Vulnerability ClassConsensus Divergence / Improper Input Validation
Attack VectorNetwork
CVSS v4.0 Score8.8 - 9.2 (Critical)
ImpactChain Split, Network Partition, Potential Double Spend
Exploit StatusProof of Concept Exists
CISA KEVNot Listed

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
T1190Exploit Public-Facing Application
Initial Access
CWE-20
Improper Input Validation

The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.

Vulnerability Timeline

Patch Released in versions 4.3.1 and 5.0.1
2026-04-18
Security Advisory Published
2026-04-18

References & Sources

  • [1]GitHub Advisory: GHSA-8m29-fpq5-89jj
  • [2]Zcash Foundation Zebra Repository
  • [3]OSV Entry: GHSA-8m29-fpq5-89jj

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.