← Back to Research
Research · July 16, 2026

How a single crafted gossipsub PRUNE backoff value panics rust-libp2p nodes via an Instant overflow (CVE-2026-34219)

Simon Morley·6 min read

rust-libp2p's gossipsub implementation stores a peer-supplied PRUNE control-message backoff duration and, during a later heartbeat cycle, adds a further "slack" duration to that stored value using unchecked Instant + Duration arithmetic; a single crafted PRUNE carrying a backoff value near u64::MAX overflows that addition and panics the process — crashing any affected node with one unauthenticated message.

Why this matters

Gossipsub is the pubsub protocol libp2p-based peer-to-peer networks use to propagate messages between mesh peers, so a gossipsub-layer crash takes the whole node offline, not just one subsystem. Per the GitHub Security Advisory: "Any application exposing an affected libp2p-gossipsub listener can be crashed by a network-reachable peer that sends crafted PRUNE backoff values," and this requires "no authentication beyond protocol peer establishment" — an ordinary gossipsub peering is enough.

This is not a volumetric attack: it is a single malformed control message, not a flood. A connection-rate or request-rate limit — the usual first line of defence against P2P DoS — does nothing here, because the cost to the attacker is one message, not a sustained rate. The only documented remedy is the vendor's arithmetic fix (below). The issue was originally reported to the rust-libp2p maintainers by the Ethereum Foundation's security team, per the advisory.

How the attack works

  • Entry point. An established gossipsub session with the target — any peer that has negotiated the meshsub/gossipsub protocol over a libp2p connection.
  • Preconditions. Network reachability and an ordinary libp2p connection with gossipsub negotiated. No further authentication or privileged peer status is required.
  • Processing path. The attacker sends a gossipsub RPC carrying a ControlPrune message for a topic, with the backoff field set to a value near u64::MAX. The target stores this as a future Instant in its per-peer backoff-tracking state. An earlier advisory, CVE-2026-33040 (GHSA-gc42-3jg7-rxr2, fixed in libp2p-gossipsub 0.49.3), had already added checked arithmetic at this insertion step. CVE-2026-34219 documents a second, distinct overflow path that survived that fix: "a near-maximum backoff can still be stored successfully, and the crash happens later in the heartbeat path when slack is added to that stored Instant using unchecked arithmetic."
  • Resource/trust boundary crossed. Peer-supplied duration data flows into internal heartbeat-timer arithmetic without a bounds check at the point it is actually consumed — even though the earlier insertion-time path had already been hardened.
  • Resulting behaviour. The addition overflows and the process panics with, per the advisory, overflow when adding duration to instant — an immediate, remote, unauthenticated crash. NVD maps the underlying weaknesses as CWE-190 (Integer Overflow or Wraparound) and CWE-617 (Reachable Assertion). This is a process crash (availability impact), not memory corruption or code execution.

Affected systems

  • Ecosystem: libp2p (the shared peer-to-peer networking stack), specifically its Rust implementation.
  • Implementation: rust-libp2p, crate libp2p-gossipsub.
  • Component: gossipsub ControlPrune backoff handling in the heartbeat routine.
  • Affected versions: libp2p-gossipsub < 0.49.4 (CVE-2026-34219 / GHSA-xqmp-fxgv-xvq5) — fixed in 0.49.4. The earlier, distinct insertion-time overflow (CVE-2026-33040 / GHSA-gc42-3jg7-rxr2) affected < 0.49.3 and was fixed in 0.49.3; that fix did not close the heartbeat-time path CVE-2026-34219 addresses.
  • Scope. Availability only — a remote panic/crash of the process. Neither advisory documents a consensus-safety break, a funds-impact path, or an authentication bypass. The advisories describe impact against the libp2p-gossipsub Rust crate itself; NullRabbit has not separately confirmed this against any specific downstream blockchain client that embeds rust-libp2p, and this brief makes no claim about any chain beyond libp2p as a shared library.

Evidence

  • Publicly documented. CVE-2026-34219 / GHSA-xqmp-fxgv-xvq5 ("Gossipsub PRUNE Backoff Heartbeat Instant Overflow", published 2026-03-31): mechanism, affected/fixed versions, and severity as summarised above. GHSA's own severity label is High (CVSS v4.0 8.2); NVD's CVSS v3.1 vector for the same finding scores it 5.9 Medium (AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H) — the difference is the two CVSS versions weighting the same network-reachable, availability-only crash differently, not a disagreement about the mechanism. The predecessor, CVE-2026-33040 / GHSA-gc42-3jg7-rxr2 ("Gossipsub PRUNE Backoff Overflow", published 2026-03-20, CVSS v4.0 8.7 High / CVSS v3.1 7.5 High), documents the earlier insertion-time overflow that CVE-2026-34219's fix builds on.
  • Independently reproduced by NullRabbit. NullRabbit's libp2p known-class corpus driver (known_class_libp2p.py) builds the same wire-level attack: a gossipsub RPC carrying a ControlPrune with backoff = u64::MAX, sent over a real Noise + yamux + /meshsub/1.1.0 libp2p session (via py-libp2p) against a live kubo (go-libp2p) node, and captures the resulting traffic as a labelled bundle (gossipsub_prune_backoff_overflow, NRDAX fidelity lab) shipped in NullRabbit/nr-bundles-public for detection-model training. This confirms the crafted message is protobuf-identical to the wire shape the advisories describe and is deliverable over an ordinary live gossipsub session. Because the capture target here is a go-libp2p node — a different codebase from the vulnerable rust-libp2p crate the CVEs describe — this reproduction does not itself demonstrate the panic; NullRabbit did not separately stand up an affected rust-libp2p build and observe the crash directly.
  • Measured under controlled conditions. Not established. NullRabbit's reproduction is a wire-level traffic capture for detection purposes (see above), not a live crash measurement against a vulnerable rust-libp2p binary.

Operator actions

  • Upgrade rust-libp2p / libp2p-gossipsub to 0.49.4 or later — this is the vendor's documented fix for CVE-2026-34219, and also carries the CVE-2026-33040 fix if you are currently below 0.49.3.
  • Rate limiting does not help. Because this is a single malformed control message rather than a flood, connection- or request-rate limits at the gossipsub layer provide no protection against it.
  • Detection. Watch for gossipsub ControlPrune messages carrying anomalously large backoff values (approaching u64::MAX) from any peer — a fixed, single-message signature rather than a volumetric one. This is a reasonable detection idea consistent with the mechanism above; it is not a mitigation documented by either advisory.

Canonical references

Related attacks

  • gossipsub_subscribe_flood (CVE-2026-46679 / GHSA-4f8r-922h-2vgv) shares the gossip_abuse family and the same shared gossipsub attack surface, and is reproduced via the same corpus driver (known_class_libp2p.py). It is a different implementation (js-libp2p) and a different mechanism (an unbounded per-peer topic map from a unique-topic SUBSCRIBE flood, not this Rust arithmetic-overflow panic) — noted here as a sibling gossipsub finding, not as the same bug.
  • NRDAX-T0120 is a chain-agnostic technique record covering other, unrelated integer-overflow-on-control-message instances in other codebases; those are not described in this brief.

Track attacks affecting rust-libp2p

New libp2p and rust-libp2p infrastructure findings are catalogued as they are reproduced. Track attacks affecting rust-libp2p on NRDAX and in NullRabbit research.


Analysis plus reproducer. No weaponised proof-of-concept code.

researchcve-replicationlibp2prust-libp2pgossipsubgossip_abusep2pinfrastructure-security
Publication policy:Why we publish these findings →

Related Posts

How a missing duplicate-input check in Bitcoin Core let one block crash 0.14.x nodes and silently inflate the supply on 0.15.0–0.16.2 (CVE-2018-17144)

·8 min read

A Bitcoin Core block containing a transaction that spends the same previous output twice reaches a validation path with no duplicate-input check: on 0.14.x this trips an internal assertion and crashes the node, and on 0.15.0-0.16.2 — when the duplicated output was created in an earlier block — it passes silently, letting the block's miner claim that output's value twice. Fixed in 0.16.3 / 0.17.0.

bitcoinbitcoin-coreblock-validation+3 more