GHSA-443g-gwgp-49x4

Suggest an improvement
Source
https://github.com/advisories/GHSA-443g-gwgp-49x4
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-443g-gwgp-49x4/GHSA-443g-gwgp-49x4.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-443g-gwgp-49x4
Published
2026-07-02T19:34:21Z
Modified
2026-07-02T19:45:33Z
Severity
  • 3.7 (Low) CVSS_V3 - CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L CVSS Calculator
Summary
zebrad vulnerable to getblocks/getheaders locator CPU amplification via uncapped vector length
Details

Am I affected

You are affected if:

  1. You run zebrad up to and including v4.4.1.
  2. Your node accepts inbound P2P connections.

Summary

The read_getblocks and read_getheaders codec paths accepted block locator vectors up to approximately 65,535 entries (the generic TrustedPreallocate ceiling derived from MAX_PROTOCOL_MESSAGE_LEN), rather than the protocol-specification limit of 101 entries (matching zcashd's MAX_LOCATOR_SZ). Each entry in the locator vector triggers a per-hash chain lookup (HashMap::contains_key + RocksDB::contains_hash) in find_chain_intersection on a tokio blocking-pool thread.

A single maximally-sized getblocks message occupies one blocking-pool thread for approximately 10–65ms. Under sustained load from multiple peers, this can degrade state-read performance for block validation, RPC, and mempool lookups.

Details

The read_headers codec path already implements the correct pattern: it reads the CompactSize count, validates against MAX_HEADERS_PER_MESSAGE = 160 before deserialization, and rejects oversized messages. The read_getblocks and read_getheaders paths were missing this pre-deserialization count check and instead relied on the generic block::Hash::max_allocation() bound, which allows (MAX_PROTOCOL_MESSAGE_LEN - 1) / 32 = 65,535 hashes.

A legitimate block locator is logarithmic in chain length (approximately 30 hashes for the current ~3M-block Zcash chain). Zebra's own send-side cap is MAX_FIND_BLOCK_HASHES_RESULTS = 500.

The practical impact requires significant attacker bandwidth (approximately 2 MiB per request) and multiple Sybil peers to meaningfully degrade the blocking pool, which limits real-world exploitability.

Patches

Patched in Zebra 4.4.2. The fix caps block::Hash::max_allocation() at MAX_BLOCK_LOCATOR_LENGTH = 101, matching zcashd's MAX_LOCATOR_SZ. This causes the deserializer to reject oversized locators before any allocation or iteration occurs.

Workarounds

No specific workaround is needed. Existing backpressure mechanisms (load shedding, sequential per-peer message processing, connection limits) constrain the practical impact.

Impact

Under sustained load from multiple Sybil peers, oversized locator vectors can occupy blocking-pool threads and degrade state-read performance. The effect is bounded by connection limits and requires significant attacker bandwidth.

Credit

Vulnerability identified by @dingledropper, who submitted the fix in PR #10570. Downstream CPU/blocking-pool impact analysis contributed by @ouicate.

Database specific
{
    "cwe_ids":  [
        "CWE-770"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-07-02T19:34:21Z",
    "nvd_published_at":  null,
    "severity":  "LOW"
}
References

Affected packages

crates.io / zebrad

Package

Affected ranges

Type
SEMVER
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
4.5.0

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-443g-gwgp-49x4/GHSA-443g-gwgp-49x4.json"

crates.io / zebra-chain

Package

Name
zebra-chain
View open source insights on deps.dev
Purl
pkg:cargo/zebra-chain

Affected ranges

Type
SEMVER
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
8.0.0

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-443g-gwgp-49x4/GHSA-443g-gwgp-49x4.json"