{"description":"Trending threats, MITRE ATT\u0026CK coverage, and detection metadata. Fed continuously.","feed_url":"https://feed.craftedsignal.io/products/@libp2p/gossipsub/feed.json","home_page_url":"https://feed.craftedsignal.io/","items":[{"_cs_actors":[],"_cs_cpes":[],"_cs_cves":[],"_cs_exploited":false,"_cs_has_poc":false,"_cs_poc_references":[],"_cs_products":["js-libp2p","@libp2p/gossipsub"],"_cs_severities":["medium"],"_cs_tags":["dos","memory-exhaustion","libp2p"],"_cs_type":"threat","_cs_vendors":["libp2p"],"content_html":"\u003cp\u003eA memory exhaustion vulnerability has been identified in \u003ccode\u003e@libp2p/gossipsub\u003c/code\u003e, a component of the js-libp2p library. The vulnerability stems from three design flaws: the lack of a decode-level cap on subscription entries per RPC (\u003ccode\u003edefaultDecodeRpcLimits.maxSubscriptions = Infinity\u003c/code\u003e), unbounded growth in the \u003ccode\u003ehandleReceivedSubscription\u003c/code\u003e function, and the failure to remove empty Sets from \u003ccode\u003ethis.topics\u003c/code\u003e after a peer disconnect in the \u003ccode\u003eremovePeer\u003c/code\u003e function. This allows an unauthenticated peer to exhaust the Node.js heap of a gossipsub node with default options by sending a flood of unique topic subscriptions. A single 4MB frame can carry 349,525 unique topic SUBSCRIBE entries, causing approximately 89MB of heap growth, leading to a crash after around 17 frames, demonstrating a significant amplification factor. This affects any gossipsub node with default options.\u003c/p\u003e\n\u003ch2 id=\"attack-chain\"\u003eAttack Chain\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eAttacker dials a victim node and opens a gossipsub stream.\u003c/li\u003e\n\u003cli\u003eThe attacker\u0026rsquo;s initial score is 0, which is greater than the default \u003ccode\u003egossipThreshold\u003c/code\u003e of -10, allowing subscriptions to be processed immediately without score checks.\u003c/li\u003e\n\u003cli\u003eThe attacker constructs a malicious RPC message containing 349,525 SUBSCRIBE entries, each with a unique 6-character topic string. The total encoded size of this RPC is approximately 4MB.\u003c/li\u003e\n\u003cli\u003eThe victim\u0026rsquo;s \u003ccode\u003ehandleReceivedRpc\u003c/code\u003e processes the RPC and iterates through each subscription entry, calling \u003ccode\u003ehandleReceivedSubscription\u003c/code\u003e for each unique topic.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehandleReceivedSubscription\u003c/code\u003e adds each new topic to the \u003ccode\u003ethis.topics\u003c/code\u003e map without any limits or per-peer count restrictions, leading to uncontrolled memory allocation.\u003c/li\u003e\n\u003cli\u003eThe victim\u0026rsquo;s \u003ccode\u003ethis.topics\u003c/code\u003e map grows by 349,525 entries, consuming approximately 89MB of heap space and blocking the event loop for approximately 224ms.\u003c/li\u003e\n\u003cli\u003eThe attacker reconnects and repeats the process, sending additional RPCs with unique topic subscriptions. No score decay or penalties are applied.\u003c/li\u003e\n\u003cli\u003eAfter approximately 17 rounds, the Node.js process exhausts its 1.5GB heap limit, resulting in an Out-Of-Memory (OOM) crash, causing a denial-of-service.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"impact\"\u003eImpact\u003c/h2\u003e\n\u003cp\u003eSuccessful exploitation of this vulnerability leads to a denial-of-service condition, as the target Node.js process crashes due to memory exhaustion. The attack requires only approximately 68MB of total attacker bandwidth, achievable in approximately 5 seconds at 100Mbps. The vulnerability affects any gossipsub node running with default options, making it a widespread risk. The memory leak in \u003ccode\u003eremovePeer\u003c/code\u003e also contributes to long-term performance degradation as \u003ccode\u003ethis.topics\u003c/code\u003e accumulates entries.\u003c/p\u003e\n\u003ch2 id=\"recommendation\"\u003eRecommendation\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eApply patches to \u003ccode\u003e@libp2p/gossipsub\u003c/code\u003e to limit the number of subscriptions accepted per RPC and implement per-peer topic count limits.\u003c/li\u003e\n\u003cli\u003eImplement a mechanism to remove empty Sets from \u003ccode\u003ethis.topics\u003c/code\u003e in the \u003ccode\u003eremovePeer\u003c/code\u003e function to prevent memory leaks, mitigating defect 3.\u003c/li\u003e\n\u003cli\u003eDeploy the Sigma rule \u0026ldquo;Detect High Topic Count in Gossipsub Subscriptions\u0026rdquo; to identify and potentially block malicious subscription floods.\u003c/li\u003e\n\u003cli\u003eMonitor Node.js process memory usage and restart gossipsub nodes exceeding a defined memory threshold to mitigate the impact of memory exhaustion.\u003c/li\u003e\n\u003cli\u003eReview and adjust the default \u003ccode\u003egossipThreshold\u003c/code\u003e to require higher scores for subscription processing, potentially mitigating step 2 of the attack chain.\u003c/li\u003e\n\u003c/ul\u003e\n","date_modified":"2026-05-21T21:40:43Z","date_published":"2026-05-21T21:40:43Z","id":"https://feed.craftedsignal.io/briefs/2026-05-js-libp2p-dos/","summary":"A memory exhaustion vulnerability exists in `@libp2p/gossipsub` due to unbounded subscription handling, allowing a single attacker to exhaust a Node.js heap by flooding unique topic subscriptions, leading to denial-of-service.","title":"js-libp2p Gossipsub Memory Exhaustion via Subscription Flood","url":"https://feed.craftedsignal.io/briefs/2026-05-js-libp2p-dos/"}],"language":"en","title":"CraftedSignal Threat Feed — @Libp2p/Gossipsub","version":"https://jsonfeed.org/version/1.1"}