CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-49866

CVE-2026-49866: CPU-Based Denial of Service in @libp2p/gossipsub Protobuf Parser

Amit Schendel
Amit Schendel
Senior Security Researcher

Jul 10, 2026·6 min read·2 visits

Executive Summary (TL;DR)

Unbounded protobuf limits and synchronous array loops in @libp2p/gossipsub allow unauthenticated remote attackers to block the single-threaded Node.js event loop, causing a complete denial of service.

A high-severity denial-of-service vulnerability in @libp2p/gossipsub prior to version 16.0.0 allows unauthenticated remote attackers to trigger event loop starvation and complete node freeze by exploiting unbounded protobuf decoding limits and nested synchronous array iteration loops.

Vulnerability Overview

The vulnerability identified as CVE-2026-49866 is a high-severity denial-of-service vulnerability affecting @libp2p/gossipsub, which is the pubsub routing stack implementation within the js-libp2p network environment. Gossipsub plays a key role in maintaining robust network routing and message propagation across peer-to-peer networks. Because it exposes an open network surface to incoming peer-to-peer RPC control messages, any unauthenticated entity can connect and interact with the protocol parser.\n\nThe vulnerability falls under CWE-770 (Allocation of Resources Without Limits or Throttling). It occurs because the decoding interface does not enforce upper bounds on nested arrays within gossip-routing control frames. Under default configurations, an attacker can transmit structured RPC messages that consume disproportionate processing time, resulting in complete service exhaustion. This bypasses the typical message boundaries and overwhelms the thread architecture.

Root Cause Analysis

The root cause of CVE-2026-49866 lies in a combination of unbounded default decoding limits, structural key mismatches during parser configuration, and synchronous processing of uncontrolled inputs. During initialization, the defaultDecodeRpcLimits configuration defines limits for arrays like maxIhaveMessageIDs and maxIwantMessageIDs as Infinity. This instructs the underlying parser (protons-runtime) to bypass length checks, enabling arbitrary memory allocation for incoming nested control arrays.\n\nCompounding this, the RPC decoding call in gossipsub.ts utilizes an incorrect schema structure key when mapping limits for nested fields. Specifically, the limits object expects properties mapped inside a dedicated structure nested under the control$ namespace, but the key mismatch fails to apply these parameters correctly. Consequently, even if a user attempts to define manual limits, the validator falls back to defaults or fails to restrict the deserialization process.\n\nOnce decoded, the application processes these populated arrays synchronously using nested .forEach loops. Because the Node.js runtime is single-threaded, synchronous execution blocks the main thread from handling any other network events, timer expirations, or operational tasks. An attacker can package approximately 180,000 message IDs within a single 4 MB physical frame, requiring the event loop to spend 135ms to 200ms of CPU time synchronously converting and analyzing the IDs.\n\nmermaid\ngraph LR\n A["Remote Unauthenticated Peer"] -->|"4MB RPC Frame"| B["Network Socket Interface"]\n B -->|"Passes Raw Bytes"| C["Protobuf Parser (protons-runtime)"]\n C -->|"No Length Validation (Infinity Limits)"| D["handleIHave / handleIWant Functions"]\n D -->|"Synchronous Array Iteration (180,000 elements)"| E["Node.js Event Loop Blocked"]\n E -->|"Thread Starvation"| F["Dropped Peer Connections & DoS"]\n

Code Analysis

To understand the technical vulnerability, we must examine the configuration that defines default limits and the parsing routine. In the vulnerable version, packages/gossipsub/src/message/decodeRpc.ts establishes unbounded array length constraints:\n\ntypescript\n// VULNERABLE: Default configurations allow infinite elements\nexport const defaultDecodeRpcLimits: DecodeRPCLimits = {\n maxSubscriptions: Infinity,\n maxMessages: Infinity,\n maxIhaveMessageIDs: Infinity, // Bypasses array limitation\n maxIwantMessageIDs: Infinity, // Bypasses array limitation\n maxIdontwantMessageIDs: Infinity,\n maxControlMessages: Infinity,\n maxPeerInfos: Infinity\n}\n\n\nThe parsed control arrays are processed directly inside gossipsub.ts using nested loops that do not implement exit conditions or element limit validation:\n\ntypescript\n// VULNERABLE: Loops iterate over the entire array size synchronously\nihave.forEach(({ topicID, messageIDs }) => {\n messageIDs.forEach((msgId) => {\n const msgIdStr = this.msgIdToStrFn(msgId);\n if (!this.seenCache.has(msgIdStr)) {\n iwant.set(msgIdStr, msgId);\n idonthave++;\n }\n });\n});\n\n\nThe patch resolves these weaknesses by introducing strict boundaries. In the updated packages/gossipsub/src/message/decodeRpc.ts, limits are assigned concrete maximum sizes, and schema structures are aligned:\n\ntypescript\n// PATCHED: Imposes rigorous limits on array decoding\nexport const defaultDecodeRpcLimits: DecodeRPCLimits = {\n maxSubscriptions: 5000,\n maxMessages: 5000,\n maxIhaveMessageIDs: 5000, // Enforces early parser-level rejection\n maxIwantMessageIDs: 5000, // Enforces early parser-level rejection\n maxControlMessages: 5000,\n maxIdontwantMessageIDs: 512,\n maxPeerInfos: 16\n}\n\n\nFurthermore, the nested loops inside gossipsub.ts are refactored to check a counter and break execution when the limits are reached:\n\ntypescript\n// PATCHED: Integrates labeled break to enforce upper boundaries\nlet processed = 0;\nout: for (const { topicID, messageIDs } of ihave) {\n if (topicID == null || messageIDs == null || !this.mesh.has(topicID)) {\n continue;\n }\n let idonthave = 0;\n for (const msgId of messageIDs) {\n if (processed >= constants.GossipsubMaxIHaveLength) { // Default is 5000\n break out; // Exits processing loop early\n }\n processed++;\n const msgIdStr = this.msgIdToStrFn(msgId);\n if (!this.seenCache.has(msgIdStr)) {\n iwant.set(msgIdStr, msgId);\n idonthave++;\n }\n }\n}\n

Exploitation Methodology

Exploiting CVE-2026-49866 does not require specialized credentials or complex configurations. An attacker first establishes a standard peer-to-peer TCP or WebSocket connection with a vulnerable Node.js js-libp2p peer. The target node accepts the initial connection and initiates a standard Gossipsub stream handshake, transitioning the connection into an active state.\n\nOnce connected, the attacker constructs a serialized Protocol Buffer RPC payload specifically containing nested ihave or iwant control messages. The attacker loads the nested messageIDs array with up to 180,000 distinct entries, keeping the entire payload just below the 4 MB length-prefixed frame limit enforced by the libp2p connection manager. Because the victim utilizes unbounded deserialization, the incoming message is fully parsed, and its contents are immediately queued for synchronous application-layer processing.\n\nAs soon as the processing handler invokes handleIHave or handleIWant, the single thread of the Node.js process is fully consumed by array iteration, string translation, and cache lookups. This blocks the event loop for 135ms to 200ms per frame. By repeatedly streaming these structured payloads, the attacker starves the event loop continuously, preventing the server from handling standard runtime callbacks or network I/O.

Impact Assessment

The practical impact of this vulnerability is a complete and sustained denial of service (DoS) of the target Node.js application. While the process itself does not crash immediately due to memory corruption, the total starvation of the Node.js event loop causes critical side effects across the entire networking layer. Healthy peers fail to receive timely response frames, resulting in missed heartbeat timeouts and widespread disconnection of honest nodes.\n\nBecause libp2p nodes often serve as routing relays, validators, or RPC endpoints in decentralized networks, a single blocked instance can disrupt wider network consensus or communications. The CVSS score of 7.5 reflects this high impact on availability, combined with low attack complexity and the lack of required privileges or user interaction.

Remediation & Mitigation

The primary remediation strategy is upgrading the @libp2p/gossipsub package dependency to version 16.0.0 or higher. This update corrects the parser schema mapping, restricts default parsing configurations, and embeds loop-breaking defensive constraints in the event handlers. Additionally, the update integrates stateful rate limiting to prevent peers from requesting excessive data within a single heartbeat window.\n\nIf immediate package updates are blocked by deployment schedules, developers should implement a manual runtime workaround during GossipSub initialization. This involves passing a manually defined decodeRpcLimits object to override the dangerous default Infinity parameters:\n\njavascript\nimport { GossipSub } from '@libp2p/gossipsub';\n\nconst safeGossipsub = new GossipSub({\n decodeRpcLimits: {\n maxSubscriptions: 5000,\n maxMessages: 5000,\n maxIhaveMessageIDs: 5000,\n maxIwantMessageIDs: 5000,\n maxControlMessages: 5000,\n maxIdontwantMessageIDs: 512,\n maxPeerInfos: 16\n }\n});\n\n\nSecurity teams should also implement performance monitoring with tools like perf_hooks or blocked-at to observe event loop lag. Lag spikes beyond 50ms should trigger alerts, indicating that the runtime may be undergoing resource exhaustion or active exploitation attempts.

Technical Appendix

CVSS Score
7.5/ 10

Affected Systems

@libp2p/gossipsub prior to 16.0.0js-libp2p installations using vulnerable @libp2p/gossipsub modules
AttributeDetail
CWE IDCWE-770
Attack VectorNetwork (AV:N)
CVSS Score7.5
EPSS Score0.00446
Exploit Statuspoc
KEV Statusnot-listed

More Reports

•about 2 hours ago•CVE-2026-49858
5.9

CVE-2026-49858: Cross-User Attribute and Relation Leak in API Platform Core Serializers

CVE-2026-49858 is a vulnerability in API Platform Core's JSON:API and HAL item normalizers where conditionally secured attributes are cached globally in memory. When deployed in long-running PHP execution environments such as FrankenPHP worker mode, Swoole, or RoadRunner, this persistent caching bypasses property-level security constraints, allowing unprivileged users to access sensitive, unauthorized fields cached during privileged requests.

Alon Barad
Alon Barad
4 views•7 min read
•about 2 hours ago•CVE-2026-5078
5.3

CVE-2026-5078: Log Forging and Injection via :remote-user Token in Morgan Logging Middleware

CVE-2026-5078 is a log injection vulnerability in Morgan, the widely deployed Node.js HTTP request logging middleware. The vulnerability arises because the ':remote-user' logging token decodes and outputs basic authentication usernames containing control characters, such as Carriage Return (CR) and Line Feed (LF), without sanitization. An unauthenticated attacker can bypass native HTTP header parsers by Base64-encoding CRLF sequences in the Authorization header. When Morgan logs the request, these control characters force newlines in the log stream, enabling log forging, SIEM evasion, and system activity spoofing.

Alon Barad
Alon Barad
5 views•7 min read
•about 13 hours ago•CVE-2026-48861
2.1

CVE-2026-48861: HTTP Request Splitting and Smuggling via Method Parameter CRLF Injection in Elixir Mint

CVE-2026-48861 is a client-side HTTP request-line CRLF (Carriage Return Line Feed) injection vulnerability in the popular Elixir HTTP client library, Mint. The vulnerability permits HTTP Request Splitting and HTTP Request Smuggling when an application forwards untrusted, attacker-controlled inputs to Mint's HTTP client requests as either the HTTP request method or target. By embedding CRLF characters within these parameters, an attacker can terminate the request line prematurely, inject malicious headers, or pipeline entirely independent requests. These smuggled requests are then processed by upstream or downstream proxy servers as separate HTTP queries on the same TCP connection. While Mint version 1.7.0 introduced target validation to secure the request target, the HTTP request method parameter remained completely unvalidated. This flaw allows attackers to bypass routing filters, access restricted internal APIs, or poison HTTP caches under default configurations.

Amit Schendel
Amit Schendel
6 views•7 min read
•about 14 hours ago•CVE-2026-49753
6.3

CVE-2026-49753: HTTP Request/Response Smuggling via Inconsistent Content-Length Parsing in Elixir Mint Client

An Inconsistent Interpretation of HTTP Requests (HTTP Request/Response Smuggling) vulnerability in the Elixir Mint HTTP client allows attacker-controlled HTTP/1 servers to desynchronize response framing on shared connections due to over-lenient parsing of sign-prefixed Content-Length headers.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 14 hours ago•CVE-2026-49754
8.2

CVE-2026-49754: Denial of Service via Unbounded HTTP/2 CONTINUATION Frame Accumulation in Elixir Mint

An allocation of resources without limits or throttling vulnerability in Elixir Mint allows an attacker-controlled HTTP/2 server to exhaust memory in a Mint client. The vulnerability is exploited by sending a HEADERS frame without the END_HEADERS flag followed by an infinite stream of CONTINUATION frames. Because the client lacks limits on the incoming header-block accumulator, the client continuously consumes memory until an out-of-memory crash occurs.

Amit Schendel
Amit Schendel
7 views•6 min read
•about 15 hours ago•CVE-2026-48596
2.1

CVE-2026-48596: Improper Neutralization of CRLF Sequences in Elixir Tesla Multipart HTTP Client

CVE-2026-48596 is an Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Request/Response Splitting, CWE-113) in the Elixir Tesla HTTP client. The flaw resides in how multipart content-type parameters are joined and serialized, enabling attackers to inject arbitrary headers or split HTTP requests when applications pass untrusted inputs to the parameters of multipart uploads.

Alon Barad
Alon Barad
5 views•6 min read