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-45740
5.30.06%

CVE-2026-45740: Uncontrolled Recursion in protobufjs Leading to Denial of Service

Alon Barad
Alon Barad
Software Engineer

May 19, 2026·6 min read·5 visits

PoC Available

Executive Summary (TL;DR)

protobufjs fails to enforce recursion limits during JSON parsing, allowing remote attackers to crash the Node.js process via deeply nested schema payloads.

An uncontrolled recursion vulnerability exists in the protobufjs library prior to versions 7.5.8 and 8.2.0. The lack of depth limits in the JSON descriptor parsing logic allows attackers to cause a stack overflow and crash the Node.js process via deeply nested payloads.

Vulnerability Overview

The protobufjs package is a widely used Node.js library responsible for compiling Protocol Buffer definitions into JavaScript functions. A fundamental weakness exists in how the library handles the expansion of nested JSON descriptors. Specifically, the parsing engine does not enforce limitations on the maximum nesting depth of input schemas.

This flaw is classified as CWE-674: Uncontrolled Recursion. The vulnerability resides within the Root.fromJSON() and Namespace.addJSON() methods. These methods traverse the properties of parsed JSON objects recursively to construct the final programmatic schema representation.

When a deeply nested JSON object is passed to these methods, the JavaScript engine allocates a new stack frame for each level of recursion. Because there is no artificial bound applied to this traversal, a malicious input can force the engine to exceed its maximum call stack size limit.

This vulnerability affects branches of the protobufjs library prior to version 7.5.8, as well as the 8.0.x release line prior to version 8.2.0. The primary impact is a Denial of Service (DoS) resulting from an unhandled RangeError exception that terminates the Node.js execution environment.

Root Cause Analysis

The vulnerability stems from the unconstrained recursive design of the JSON descriptor expansion logic. When protobufjs processes a JSON representation of a protobuf schema, it traverses the nested properties of the object to build the internal namespace hierarchy. This traversal relies on function calls that invoke one another synchronously.

During normal operation, Root.fromJSON(json) receives the initial input and passes the json.nested object to root.addJSON(). The addJSON method iterates over the keys of this nested object. For each key, it determines the appropriate constructor and invokes its respective fromJSON method, such as Namespace.fromJSON.

Inside Namespace.fromJSON, the code encounters further nested properties and calls addJSON again to process them. In vulnerable versions, the application maintained no state regarding the current depth of this call chain. The V8 engine enforces a strict limit on the number of synchronous frames on the call stack, typically around 10,000 frames depending on the environment.

The cyclical call between Namespace.fromJSON and namespace.addJSON continues unabated until the V8 engine aborts the operation. This architectural oversight exposes the application to resource exhaustion based entirely on the structure of the provided input.

Code Analysis

Prior to the patch, the Namespace.prototype.addJSON function accepted an object and iterated through it, calling the appropriate parsing functions without any depth context. The underlying fromJSON methods similarly lacked any parameters to track how far down the schema hierarchy the parser had traveled.

The maintainers addressed this in commit 9050289ad214ea351d3b030cbc74385e81e02d79 by introducing global limits that align with the default behavior of the official protoc compiler. They added util.recursionLimit = 100 for general namespace traversal and util.nestingLimit = 32 for message-level nesting.

The signatures of the parsing functions were updated to accept a depth parameter. The root entry points initialize this parameter to zero, and each recursive call increments it. The core mitigation logic validates this incremented value against the newly defined global limits.

// src/namespace.js (Patched)
Namespace.fromJSON = function fromJSON(name, json, depth) {
    // ... initialization ...
    if (json.nested) {
        // depth is passed and checked within addJSON
        namespace.addJSON(json.nested, depth);
    }
    return namespace;
};
 
Namespace.prototype.addJSON = function addJSON(nested, depth) {
    depth = depth || 0;
    if (depth > util.recursionLimit) {
        throw Error("max depth exceeded");
    }
    // ... recursively call child fromJSON methods with (depth + 1)
    for (var i = 0; i < keys.length; ++i) {
        // ...
        this.add(ctor.fromJSON(keys[i], nested[keys[i]], depth + 1));
    }
};

Exploitation

To exploit this vulnerability, an attacker must have a vector to supply an arbitrary JSON schema to the target application. This scenario is common in applications that dynamically generate protobuf configurations, accept schemas via API endpoints for validation, or process user-uploaded definition files.

The attacker constructs a specialized JSON payload containing a deeply nested hierarchical structure. Because the structure only requires empty nested objects, the payload size remains exceptionally small, making the attack highly efficient. The payload leverages the nested key to build a chain of objects that exceeds the target engine's stack limit.

Upon processing the malicious payload, the application enters the synchronous parsing loop. Because Node.js operates primarily on a single-threaded event loop, this synchronous exhaustion blocks all other operations. The V8 engine eventually throws a RangeError: Maximum call stack size exceeded exception.

const protobuf = require("protobufjs");
 
// Generate a deeply nested JSON descriptor
function generatePayload(depth) {
    let root = { nested: {} };
    let current = root.nested;
    for (let i = 0; i < depth; i++) {
        const name = "n" + i;
        current[name] = { nested: {} };
        current = current[name].nested;
    }
    return root;
}
 
// 2000 levels is sufficient to exhaust the V8 stack limit
const payload = generatePayload(2000); 
 
// Triggers the Denial of Service
protobuf.Root.fromJSON(payload);

Impact Assessment

The direct consequence of this vulnerability is an application crash. In the Node.js ecosystem, an unhandled RangeError originating from stack exhaustion causes the entire process to terminate immediately. This architecture amplifies the severity of the flaw compared to similar vulnerabilities in multi-threaded environments.

Process termination results in an immediate Denial of Service for all active and pending connections handled by the affected instance. If the application is managed by a process manager (such as PM2 or Kubernetes), the service will restart, but continuous submission of the malicious payload will result in a persistent outage condition known as a crash loop.

The National Vulnerability Database (NVD) assigned a base CVSS score of 5.3, categorizing the availability impact as Low. However, third-party security scanners frequently evaluate the availability impact as High, resulting in a CVSS score of 7.5. This higher rating accurately reflects the total loss of availability for the process processing the payload.

Applications that accept schemas from untrusted sources are at the highest risk. Systems that only compile static, developer-controlled .proto files during the build process are generally not exposed to runtime exploitation via this vector.

Remediation

Organizations must upgrade their protobufjs dependencies to incorporate the patch. The maintainers have released fixes in versions 7.5.8 and 8.2.0. Upgrading to these versions or higher ensures the parsing logic respects the newly introduced recursion depth limits.

If immediate patching is not feasible due to dependency constraints, developers must implement an input validation mechanism before passing untrusted JSON schemas to protobufjs. This mechanism involves creating a custom, iterative function to calculate the maximum depth of the JSON object.

The pre-validation function must operate without utilizing deep recursion to avoid triggering the very stack overflow it aims to prevent. Payloads exceeding a conservative depth threshold, such as 32 levels, should be rejected at the application boundary.

Security and operations teams should utilize dependency scanning tools to identify vulnerable configurations within their environments. Scanning package-lock.json or yarn.lock files for protobufjs versions prior to 7.5.8 or within the 8.0.0 to 8.1.9 range will isolate components requiring remediation.

Official Patches

GitHub Security AdvisoryOfficial GHSA Advisory
protobufjsPatch commit applying recursion limits

Fix Analysis (1)

Technical Appendix

CVSS Score
5.3/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
EPSS Probability
0.06%
Top 82% most exploited

Affected Systems

Node.js applications utilizing protobufjs < 7.5.8Node.js applications utilizing protobufjs 8.0.0 - 8.1.9

Affected Versions Detail

Product
Affected Versions
Fixed Version
protobufjs
protobufjs_project
< 7.5.87.5.8
protobufjs
protobufjs_project
>= 8.0.0, < 8.2.08.2.0
AttributeDetail
CWE IDCWE-674
Attack VectorNetwork-based
CVSS Base Score5.3 (NVD) / 7.5 (Scanners)
EPSS Score0.00058
ImpactDenial of Service (Process Crash)
Exploit StatusProof-of-Concept
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499.003Endpoint Denial of Service: Application Exhaustion
Impact
CWE-674
Uncontrolled Recursion

The product does not properly control the amount of recursion that takes place, consuming excessive resources, such as allocated memory or the program stack.

Known Exploits & Detection

Research ContextProof of Concept demonstrating process crash via 2000-level nested JSON structure
NucleiDetection Template Available

Vulnerability Timeline

Initial hardening of input handling in version 8.0.2 (PR #2143)
2026-04-27
Version 8.2.0 released with primary fixes
2026-05-09
GHSA-jggg-4jg4-v7c6 published and version 8.2.1 released
2026-05-13
CVE-2026-45740 published to the NVD
2026-05-13

References & Sources

  • [1]GitHub Security Advisory: GHSA-jggg-4jg4-v7c6
  • [2]Protobuf.js Changelog
  • [3]NVD CVE-2026-45740
  • [4]Fix Commit 9050289

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.