GHSA-jv4h-j224-23cc
HIGHGHSA-jv4h-j224-23cc is a high-severity (CVSS 7.5) vulnerability in zebrad. O3 Security confirms whether GHSA-jv4h-j224-23cc is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.
Zebra's Block Validator Undercounts Coinbase and P2SH Sigops
Real-World Exposure
zebradReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects crates.io packages — download data is not available via public APIs for these ecosystems.
Description
Zebra's block validator undercounts transparent signature operations against the 20000-sigop block limit (MAX_BLOCK_SIGOPS), allowing it to accept blocks that zcashd rejects with bad-blk-sigops. A miner who produces such a block can split the network: Zebra nodes follow the offending chain while zcashd nodes do not.
Two distinct undercounts:
A: Coinbase Hidden Legacy Sigops
zcashd's GetLegacySigOpCount() includes the coinbase input's scriptSig. Zebra's Sigops impl skipped the coinbase input entirely, so up to ~98 sigops (the 100-byte coinbase script length cap, less the height prefix) could be hidden inside the coinbase scriptSig without being charged against the block limit.
B: Aggregate P2SH Sigops.
zcashd's GetP2SHSigOpCount() parses each P2SH input's redeem script with accurate=true and sums those sigops into the block-wide total via ConnectBlock. The check is per-block, not per-transaction, and the limit applies regardless of who mines the offending block — a miner just needs to include enough P2SH-spending transactions whose redeem scripts together exceed 20000 sigops. Zebra computed P2SH sigops only on the mempool-acceptance path (used for ZIP-317 weighting) and never accumulated them during block validation. A block whose aggregate redeem-script sigops exceed 20000 (e.g. 1334 P2SH spends × 15 sigops = 20010) would be accepted by Zebra and rejected by zcashd.
Patches
Fixed in this release: https://github.com/ZcashFoundation/zebra/releases/tag/v4.4.0.
Workarounds
None. Operators relying on Zebra for consensus should upgrade.
Resources
MAX_BLOCK_SIGOPSconstant inherited from Bitcoin via the Zcash protocol spec's §7.6 catch-all "Other rules inherited from Bitcoin", tracked for explicit documentation in zcash/zips#568.zcashdGetLegacySigOpCount: https://github.com/zcash/zcash/blob/v6.11.0/src/main.cpp#L826-L836zcashdGetP2SHSigOpCount: https://github.com/zcash/zcash/blob/v6.11.0/src/main.cpp#L840-L852zcashdConnectBlockaggregates per-tx sigops and compares againstMAX_BLOCK_SIGOPS.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🦀crates.io | zebrad | all versions | 4.4.0 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for zebrad. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.
Fix
Update zebrad to 4.4.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-jv4h-j224-23cc is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 pinpoints whether GHSA-jv4h-j224-23cc is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.
Tailored to GHSA-jv4h-j224-23cc. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-jv4h-j224-23cc in your dependencies?
O3 detects GHSA-jv4h-j224-23cc across crates.io dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.