CVE-2026-102281: Nest Remote Process Termination Vulnerability
HIGHCVE-2026-102281 is a HIGH (CVSS 7.5) remote process termination vulnerability (CWE-674: Uncontrolled Recursion) affecting Nest libraries in the npm ecosystem. The issue involves remote process termination via a deeply nested microservice message pattern. Remediation is available by upgrading affected packages to version 11.2.4, 12.0.2.
CVE-2026-102281 at a Glance
Security Impact
CVSS: 7.5
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H).
How to Fix CVE-2026-102281
To remediate this vulnerability, upgrade all affected Nest dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
npm install @nestjs/microservices@11.2.4
npm install @nestjs/microservices@12.0.2
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
npm ls @nestjs/microservices
How to Check if You Are Affected
To determine whether your Node.js application is affected by CVE-2026-102281, inspect your project dependencies using npm:
npm ls @nestjs/microservices
Analyze the terminal output to locate any version of Nest in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 11.2.4), your application is affected.
Note: The npm ls @nestjs/microservices command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-674: Uncontrolled Recursion, where the product does not properly control the amount of recursion that takes place, consuming excessive resources, such as allocated memory or the program stack. In Nest, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-102281 Affected Nest Versions
2 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
@nestjs/microservices
|
npm |
< 11.2.4
|
11.2.4
|
|
@nestjs/microservices
|
npm |
≥ 12.0.0
< 12.0.2
|
12.0.2
|
References
Frequently Asked Questions
What is CVE-2026-102281?
Which Nest versions are affected?
What version fixes CVE-2026-102281?
Is @nestjs/microservices affected?
What is the CVSS score of CVE-2026-102281?
What CWE is associated with CVE-2026-102281?
How can I check npm dependencies for CVE-2026-102281?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-m8vh-jmq9-5rjg",
"modified" : "2026-09-29T23:54:44Z",
"published" : "2026-09-29T23:54:44Z",
"aliases" : [ "CVE-2026-102281" ],
"summary" : "Nest: Remote process termination via a deeply nested microservice message pattern",
"details" : "| Field | Value |\n| --- | --- |\n| Ecosystem | npm |\n| Package | `@nestjs/microservices` |\n| Affected versions | `>= 12.0.0, < 12.0.2` and `< 11.2.4` |\n| Patched versions | `12.0.2` and `11.2.4` (upgrade to `12.0.3` / `11.2.5`) |\n\n### Summary\n\nA single message whose `pattern` is a deeply nested object terminates a NestJS microservice that uses the TCP or\nRabbitMQ transport. The server serialized the client-supplied pattern with `JSON.stringify` to derive the handler\nlookup key; on deeply nested input this throws `RangeError: Maximum call stack size exceeded`. The exception escaped\nthe asynchronous message handler as an unhandled promise rejection, which terminates the Node.js process under the\ndefault `--unhandled-rejections=throw`.\n\n### Impact\n\nDenial of service, one message per crash, repeatable. The attacker needs to be able to reach the transport: connect\nto the TCP transport's port, or publish to the queue or exchange the service consumes from. The TCP transport\nperforms no authentication by default, so on a reachable port this requires nothing else.\n\nOnly the **TCP** and **RabbitMQ** transports are affected. The other transports take the pattern as a string from the\nbroker topic or channel and never serialize a client-supplied object to build it.\n\n### Details\n\nIn `ServerTCP#handleMessage` and `ServerRMQ#handleMessage` the pattern was stringified without a guard:\n\n```ts\nconst pattern = isString(packet.pattern)\n ? packet.pattern\n : JSON.stringify(packet.pattern);\n```\n\n`JSON.parse` accepts nesting depths that `JSON.stringify` cannot re-serialize, because `JSON.stringify` recurses\nnatively, so an attacker can craft a payload that parses successfully on arrival and then throws when the pattern is\nconverted back to a string. Neither transport attached a rejection handler to the promise returned by\n`handleMessage`, so the `RangeError` propagated out as an unhandled rejection.\n\n### Proof of concept\n\nAgainst a NestJS microservice on the TCP transport (default port 3001). The nested JSON is built as text rather than\nwith `JSON.stringify`, which is what makes the payload serializable by the attacker but not by the victim:\n\n```js\nconst { connect } = require('node:net');\n\nconst DEPTH = 100_000;\nconst pattern = '{\"nested\":'.repeat(DEPTH) + '{}' + '}'.repeat(DEPTH);\nconst payload = `{\"pattern\":${pattern},\"data\":null,\"id\":\"1\"}`;\n\nconst socket = connect(3001, '127.0.0.1', () => {\n // Nest's TCP framing is <byteLength>#<json>\n socket.write(`${Buffer.byteLength(payload)}#${payload}`);\n});\n```\n\nThe service exits with `RangeError: Maximum call stack size exceeded`. The equivalent payload published to the\nconsumed queue crashes a RabbitMQ-transport service.\n\n### Patches\n\nFixed in **12.0.2** and **11.2.4**.\n\n- Incoming patterns are converted through a guarded `Server#getPatternAsString`, which falls back to a sentinel value\n that matches no handler. Such a message now receives the ordinary \"no message handler\" response (TCP) or is\n negatively acknowledged (RabbitMQ) instead of crashing the process.\n- Rejections escaping `handleMessage` in both transports are routed to `handleError` rather than left unhandled.\n\n### Workarounds\n\nIf you cannot upgrade, restrict network access to the transport so that only trusted peers can reach it. Running the\nprocess with `--unhandled-rejections=warn` prevents the crash but leaves the message unprocessed and is not a\nsubstitute for the fix.\n\n### Credit\n\nReported by ZeroVuln Labs.",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "npm",
"name" : "@nestjs/microservices"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "11.2.4"
} ]
} ]
}, {
"package" : {
"ecosystem" : "npm",
"name" : "@nestjs/microservices"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "12.0.0"
}, {
"fixed" : "12.0.2"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/nestjs/nest/security/advisories/GHSA-m8vh-jmq9-5rjg"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-102281"
}, {
"type" : "WEB",
"url" : "https://github.com/nestjs/nest/pull/17737"
}, {
"type" : "WEB",
"url" : "https://github.com/nestjs/nest/commit/aa97b5144d8dff1ce700aac521eb86449a679d6f"
}, {
"type" : "WEB",
"url" : "https://github.com/nestjs/nest/commit/e9dcd4c7ac64361fbfe79461da85f5b3fc3e02da"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/nestjs/nest"
}, {
"type" : "WEB",
"url" : "https://github.com/nestjs/nest/releases/tag/v11.2.4"
}, {
"type" : "WEB",
"url" : "https://github.com/nestjs/nest/releases/tag/v12.0.2"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-248", "CWE-674" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2026-09-29T23:54:44Z",
"nvd_published_at" : "2026-09-28T22:17:32Z"
}
}