Severity by source
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
AC:H reflects the meaningful precondition that circular JS object graphs must reach the API; no confidentiality or integrity impact applies.
Primary rating from Vendor (https://github.com/RebeccaStevens/deepmerge-ts).
CVSS VectorVendor: https://github.com/RebeccaStevens/deepmerge-ts
Lifecycle Timeline
6DescriptionCVE.org
Summary
deepmerge() and deepmergeInto() can be crashed with a crafted recursive object graph. When both merged values contain self-references at the same property path, the library recurses until Node throws RangeError: Maximum call stack size exceeded.
Details
Record merging is implemented recursively. For each enumerable key, the library collects the values from every input object and immediately calls the same merge routine on that property.
There is no visited-object tracking, pair tracking, or cycle detection in that recursion. As a result, if two merged records both point back to themselves through the same key path, the merge logic keeps revisiting the same object pair forever.
This is reachable through the real public API:
deepmerge(...)deepmergeCustom(...)(...)deepmergeInto(target, ...)deepmergeIntoCustom(...)(target, ...)
The issue only occurs when recursive object graphs are supplied. Plain JSON alone does not create this condition.
PoC
import { deepmerge, deepmergeInto } from "deepmerge-ts";
const left = {};
left.self = left;
const right = {};
right.self = right;
try {
deepmerge(left, right);
} catch (error) {
console.log(error.name, error.message);
// Expected: the merge should reject or safely handle recursive input without exhausting the stack.
// Vulnerable behavior: RangeError Maximum call stack size exceeded
}
const target = {};
target.self = target;
const source = {};
source.self = source;
try {
deepmergeInto(target, source);
} catch (error) {
console.log(error.name, error.message);
// Expected: the merge should reject or safely handle recursive input without exhausting the stack.
// Vulnerable behavior: RangeError Maximum call stack size exceeded
}Impact
Applications that pass attacker-controlled recursive object graphs into these APIs can be forced into a synchronous crash path. In Node.js services, that can terminate request handling for the affected process or trigger repeated worker restarts until the malicious input is blocked.
Articles & Coverage 1
AnalysisAI
Stack exhaustion denial-of-service in deepmerge-ts crashes Node.js processes when attacker-controlled recursive object graphs are passed to deepmerge(), deepmergeInto(), deepmergeCustom()(), or deepmergeIntoCustom()(). All versions prior to 8.0.0 lack cycle detection in the recursive record-merge routine, allowing two self-referencing objects sharing a key path to drive the process into infinite recursion until the Node.js runtime throws RangeError: Maximum call stack size exceeded. A public proof-of-concept is included in the GitHub security advisory; no CISA KEV listing exists at time of analysis.
Technical ContextAI
CWE-674 (Uncontrolled Recursion) describes the root cause: the library's record-merge kernel iterates over enumerable keys and immediately recurses on collected property values with no visited-object tracking, pair tracking, or depth limit. When both merged objects contain a self-referential property at the same path - for example left.self = left and right.self = right - the merge routine re-encounters the same object pair on every recursive call and never converges. The affected package is pkg:npm/deepmerge-ts, all releases before 8.0.0. The condition cannot be triggered by plain JSON deserialization alone because JSON.parse cannot produce circular references; it requires JavaScript object graphs built programmatically or through frameworks that preserve reference cycles.
RemediationAI
Upgrade deepmerge-ts to version 8.0.0 or later, which introduces circular-reference support configurable via a new maxDepth option and a mergeCircularReferences merge-function option; see the security advisory at https://github.com/RebeccaStevens/deepmerge-ts/security/advisories/GHSA-ggr8-5vv4-36mx and the release notes at https://github.com/RebeccaStevens/deepmerge-ts/releases/tag/v8.0.0. Note that v8.0.0 is a major release with breaking changes: Map values are now deep-merged by default (opt out with deepmergeCustom({ mergeMaps: false })), DeepMergeMetaMetaData is renamed to DeepMergeMergeInfo, and DeepMergeIntoFunctionUtils is renamed to DeepMergeIntoUtils with no backwards-compatible alias. If an immediate upgrade is not feasible, the specific compensating control is to validate all inputs for circular references before calling any deepmerge-ts function - for example, using a JSON serialize-and-parse round-trip to strip cycles, or running a depth-limited traversal check; the trade-off is added latency and the inability to intentionally merge circular structures.
A vulnerability in the NuPoint Unified Messaging (NPM) component of Mitel MiCollab through 9.8 SP1 FP2 (9.8.1.201) could
FortiOS and FortiProxy contain an authentication bypass via the Node.js websocket module allowing unauthenticated remote
Denial of service against HTTP/2 server implementations allows remote unauthenticated attackers to exhaust server resour
Eval injection vulnerability in the internals.batch function in lib/batch.js in the bassmaster plugin before 1.5.2 for t
Flowise version 3.0.5 contains a remote code execution vulnerability in the CustomMCP node. The mcpServerConfig paramete
Node.js 8.5.0 before 8.6.0 allows remote attackers to access unintended files, because a change to ".." handling was inc
An issue was discovered in the node-serialize package 0.0.4 for Node.js. Rated critical severity (CVSS 9.8), this vulner
OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph
Directory traversal vulnerability in the st module before 0.2.5 for Node.js allows remote attackers to read arbitrary fi
Multiple SQL injection vulnerabilities in the Manage Accounts page in the AccountManagement.asmx service in the Solarwin
The JS-YAML module before 2.0.5 for Node.js parses input without properly considering the unsafe !!js/function tag, whic
The AES-NI implementation in OpenSSL before 1.0.1t and 1.0.2 before 1.0.2h does not consider memory allocation during a
Same weakness CWE-674 – Uncontrolled Recursion
View allSame technique Denial Of Service
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-63468
GHSA-ggr8-5vv4-36mx