Skip to content

Unattributed pushed-transaction verification failures allow sustained batch-verification poisoning of block processing

Moderate
mpguerra published GHSA-g7c4-2w6c-cr3r Jul 17, 2026

Package

cargo zebrad (Rust)

Affected versions

6.0.0

Patched versions

6.1.0

Description

Unattributed pushed-transaction verification failures allow sustained batch-verification poisoning of block processing

Field Value
Severity Moderate
CVSS 3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L (5.3)
CWE CWE-770 (Allocation of Resources Without Limits or Throttling) / CWE-405 (Asymmetric Resource Consumption)
Affected versions v6.0.0-rc.0 and v6.0.0 (the attribution behaviour was introduced with the GHSA-m9xx-8rcj-vmgp changes)
Patched versions 6.1.0
Reporter credit Partner disclosure (@ebfull and @ValarDragon )
Fix PR #10995

Am I affected?

You are affected if you run an affected version with default peer-to-peer networking. The condition is reachable by any peer that can connect and push transactions; no authentication or special privileges are required, and the default configuration is affected. The impact is degraded block-processing performance (the reporter measures roughly a sevenfold slowdown under full Orchard load) sustained for as long as the attack continues, because the sending peer is never penalised. There is no crash, no consensus divergence, and no state corruption.

Summary

When a directly-pushed mempool transaction fails verification, Zebra does not record the sending peer's address on the failure, so the peer is never misbehavior-scored and never banned, even though the address was available. Because Orchard proof verification runs through a process-global batch verifier that is shared between mempool transaction verification and block verification, a peer can repeatedly push transactions carrying invalid Orchard proofs at no cost. Each invalid proof that enters a shared batch causes the batch to fail, forcing Zebra to re-verify every proof in that batch individually (the slow path), including honest proofs from block processing that were batched alongside. The result is a sustained, unattributed degradation of block verification driven by cheap unauthenticated peer traffic.

Details

Verified on v6.0.0 (identical on v6.0.0-rc.0).

Attribution gap. download_if_needed_and_verify receives the sending peer as source: Option<SocketAddr> (zebrad/src/components/mempool/downloads.rs:326) and uses it for the per-peer admission cap. In the gossip match, the downloaded-by-id branch retains the network-supplied advertiser, but the directly-pushed branch discards the source:

Gossip::Tx(tx) => {
    metrics::counter!("mempool.pushed.transactions.total", ...).increment(1);
    (tx, None)                       // downloads.rs:432
}

The verification error is then wrapped as Invalid { error, advertiser_addr } (downloads.rs:457), so for a pushed transaction advertiser_addr is None. Misbehavior scoring is applied only when the error carries an address, so a directly-pushed invalid transaction is rejected and cached but the sending peer is never scored and never banned. The GHSA-m9xx-8rcj-vmgp change restored the source for admission accounting but not for this verification-failure scoring path.

Shared batch verifier. Orchard (halo2) proofs are verified through per-era process-global verifiers (zebra-consensus/src/primitives/halo2.rs:259 onward), each built as a Fallback over a batch verifier (halo2.rs:239-240). Mempool transaction verification and block transaction verification both route Orchard proofs through the same per-era verifier. When a batch fails, the Fallback re-runs every item in that batch individually (halo2.rs:196-198). Batch verification amortises cost across proofs; individual verification does not, so one invalid proof forces every proof batched with it onto the slow path.

Amplification. Because the pushing peer is never banned, an attacker can sustain a stream of transactions bearing invalid Orchard proofs from a single unauthenticated connection. Those invalid proofs enter the shared batch, cause repeated batch failures, and drive the fallback-to-individual path for honest block-processing proofs that share the batch, degrading block verification for the duration of the attack. The reporter measures roughly a sevenfold block-processing slowdown under full Orchard load.

Patches

6.1.0. The primary fix is to attribute pushed-transaction verification failures to the sending peer, by threading the source already in scope into the pushed branch (downloads.rs:429-434) so the Invalid error carries the peer and the existing misbehavior scoring bans it. Scoring must be limited to unambiguous invalidity (such as an invalid proof) so that transactions failing for non-malicious reasons do not cause bans. A defense-in-depth question to consider alongside the fix is whether invalid items can be isolated from the shared batch, or whether mempool and block verification should share a batch at all, since a single well-timed invalid proof can still force one batch onto the slow path even once scoring bans the source.

Workarounds

There is no configuration-only workaround; the affected path is standard mempool transaction handling. Restricting inbound peer connections limits exposure. Upgrading once a patch is available is the durable fix.

Impact

Availability only. Cheap, unauthenticated, default-config peer traffic can degrade block-processing performance and sustain that degradation, because the sending peer is never penalised. The reporter's worst-case measurement is around 20 seconds of block-processing time, characterised as CPU exhaustion that improves with more cores, i.e. block-processing degradation rather than whole-node unresponsiveness. The impact reaches the consensus-critical block-verification path via the shared proof-verification batch, rather than being confined to the mempool. There is no crash, no consensus divergence, no invalid-block acceptance, and no state corruption. The distinguishing feature versus the O(N^2) block finding is that this has no proof-of-work gate and is sustainable for free (the peer is never banned), which is why it is Medium rather than Low; the reason it is not High is that the measured impact is core-scalable block-processing degradation, not whole-node denial. One caveat on small-core nodes: with less scheduling headroom, the degradation can approach effective unresponsiveness for the duration even though the mechanism is CPU-bound. The remaining severity input is how cheaply an attacker can get an invalid-proof transaction to the shared batch, pending confirmation.

Credit

Reported by a partner via coordinated disclosure (attribution to be confirmed), including the attribution-gap root cause and the shared-batch cross-contamination mechanism with a measured block-processing slowdown.

References

  • zebrad/src/components/mempool/downloads.rs:326,359,419-434,457 (source parameter, per-peer cap, gossip match, the discarded attribution, the wrapped error)
  • zebrad/src/components/mempool.rs:644-657 (misbehavior scoring gated on advertiser_addr)
  • zebra-consensus/src/primitives/halo2.rs:196-198,239-240,259+ (Fallback re-verify-individually, batch construction, shared per-era verifiers)
  • Related: GHSA-m9xx-8rcj-vmgp (admission-accounting half of the same attribution gap)
  • CWE-770, CWE-405

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
Low

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

CVE ID

No known CVE

Weaknesses

Asymmetric Resource Consumption (Amplification)

The product does not properly control situations in which an adversary can cause the product to consume or produce excessive resources without requiring the adversary to invest equivalent work or otherwise prove authorization, i.e., the adversary's influence is asymmetric. Learn more on MITRE.

Allocation of Resources Without Limits or Throttling

The product allocates a reusable resource or group of resources on behalf of an actor without imposing any intended restrictions on the size or number of resources that can be allocated. Learn more on MITRE.

Credits