GHSA-JV4H-J224-23CC

Vulnerability from github – Published: 2026-05-07 20:54 – Updated: 2026-05-07 20:54
VLAI?
Summary
Zebra's Block Validator Undercounts Coinbase and P2SH Sigops
Details

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

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "crates.io",
        "name": "zebrad"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.4.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-44498"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-682"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-05-07T20:54:33Z",
    "nvd_published_at": null,
    "severity": "CRITICAL"
  },
  "details": "Zebra\u0027s 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.\n\nTwo distinct undercounts:\n\n#### A: Coinbase Hidden Legacy Sigops\n\n`zcashd`\u0027s `GetLegacySigOpCount()` includes the coinbase input\u0027s `scriptSig`. Zebra\u0027s `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.\n\n#### B: Aggregate P2SH Sigops.\n\n`zcashd`\u0027s `GetP2SHSigOpCount()` parses each P2SH input\u0027s 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 \u2014 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 \u00d7 15 sigops = 20010) would be accepted by Zebra and rejected by `zcashd`.\n\n### Patches\n\nFixed in this release:  https://github.com/ZcashFoundation/zebra/releases/tag/v4.4.0.\n\n### Workarounds\n\nNone. Operators relying on Zebra for consensus should upgrade.\n\n### Resources\n\n- `MAX_BLOCK_SIGOPS` constant inherited from Bitcoin via the Zcash protocol spec\u0027s \u00a77.6 catch-all \"Other rules inherited from Bitcoin\", tracked for explicit documentation in [zcash/zips#568](https://github.com/zcash/zips/issues/568).\n- `zcashd` `GetLegacySigOpCount`: \u003chttps://github.com/zcash/zcash/blob/v6.11.0/src/main.cpp#L826-L836\u003e\n- `zcashd` `GetP2SHSigOpCount`: \u003chttps://github.com/zcash/zcash/blob/v6.11.0/src/main.cpp#L840-L852\u003e\n- `zcashd` `ConnectBlock` aggregates per-tx sigops and compares against `MAX_BLOCK_SIGOPS`.",
  "id": "GHSA-jv4h-j224-23cc",
  "modified": "2026-05-07T20:54:33Z",
  "published": "2026-05-07T20:54:33Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/ZcashFoundation/zebra/security/advisories/GHSA-jv4h-j224-23cc"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/ZcashFoundation/zebra"
    },
    {
      "type": "WEB",
      "url": "https://github.com/ZcashFoundation/zebra/releases/tag/v4.4.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:H/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Zebra\u0027s Block Validator Undercounts Coinbase and P2SH Sigops"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…