How a single crafted gossipsub PRUNE backoff value panics rust-libp2p nodes via an Instant overflow (CVE-2026-34219)
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
ControlPrunemessage for a topic, with thebackofffield set to a value nearu64::MAX. The target stores this as a futureInstantin its per-peer backoff-tracking state. An earlier advisory, CVE-2026-33040 (GHSA-gc42-3jg7-rxr2, fixed inlibp2p-gossipsub0.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, cratelibp2p-gossipsub. - Component: gossipsub
ControlPrunebackoff 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-gossipsubRust crate itself; NullRabbit has not separately confirmed this against any specific downstream blockchain client that embedsrust-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
libp2pknown-class corpus driver (known_class_libp2p.py) builds the same wire-level attack: a gossipsub RPC carrying aControlPrunewithbackoff = u64::MAX, sent over a real Noise + yamux +/meshsub/1.1.0libp2p 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 fidelitylab) shipped inNullRabbit/nr-bundles-publicfor 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 vulnerablerust-libp2pcrate the CVEs describe — this reproduction does not itself demonstrate the panic; NullRabbit did not separately stand up an affectedrust-libp2pbuild 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-libp2pbinary.
Operator actions
- Upgrade
rust-libp2p/libp2p-gossipsubto 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
ControlPrunemessages carrying anomalously largebackoffvalues (approachingu64::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
- NRDAX technique: NRDAX-T0120 — integer-overflow-panic-control-message (this brief covers only the
rust-libp2pgossipsub instance) - NullRabbit advisory: none. This is a replication of a public disclosure; there is no associated NullRabbit advisory number.
- Evidence bundle (Hugging Face): NullRabbit/nr-bundles-public — primitive
gossipsub_prune_backoff_overflow - Upstream:
- GHSA-xqmp-fxgv-xvq5 / CVE-2026-34219 —
libp2p/rust-libp2psecurity advisory, fixed inlibp2p-gossipsub0.49.4 - GHSA-gc42-3jg7-rxr2 / CVE-2026-33040 — predecessor advisory, fixed in
libp2p-gossipsub0.49.3 - NVD: CVE-2026-34219 · NVD: CVE-2026-33040
- GHSA-xqmp-fxgv-xvq5 / CVE-2026-34219 —
Related attacks
gossipsub_subscribe_flood(CVE-2026-46679 / GHSA-4f8r-922h-2vgv) shares thegossip_abusefamily 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-topicSUBSCRIBEflood, 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.
Related Posts
How CometBFT's SecretConnection handshake spends CPU before authenticating the peer
CometBFT completes the full SecretConnection STS handshake — an X25519 Diffie–Hellman exchange and an Ed25519 signature verification — for any connecting peer before checking whether that peer's node-ID is allowlisted, so an unauthenticated remote source can spend the node's asymmetric-crypto budget at will.
How an unauthenticated TLS half-open flood pins rippled's memory and crashes it under low file-descriptor limits
rippled's inbound TLS listeners on the peer port (51235) and the RPC-HTTPS port (5006) accept a partial TLS handshake with no deadline and no per-IP half-open cap, so a single source IP can pin server memory indefinitely and, at a default file-descriptor limit, crash the process.
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)
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.
