{"schema":"threatline.record/2","record":{"id":"CVE-2026-102281","aliases":["GHSA-m8vh-jmq9-5rjg"],"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.","categories":["Frameworks"],"product":"@nestjs/microservices","vendor":"nestjs","ecosystem":"npm","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-m8vh-jmq9-5rjg","source_modified_at":"2026-09-29T23:54:45Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"npm","name":"@nestjs/microservices"},"range":"< 11.2.4"},{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-m8vh-jmq9-5rjg","source_modified_at":"2026-09-29T23:54:45Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"npm","name":"@nestjs/microservices"},"range":">= 12.0.0, < 12.0.2"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-102281","source_modified_at":"2026-09-29T12:50:34.126Z","fetched_at":"2026-10-23T18:45:31.882637Z","product":"nest","vendor":"nestjs","versions":[{"version":"< 11.2.4","status":"affected"},{"version":">= 12.0.0, < 12.0.2","status":"affected"}],"defaultStatus":null},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-m8vh-jmq9-5rjg","source_modified_at":"2026-09-30T00:00:03.849760028Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"@nestjs/microservices","ecosystem":"npm","purl":"pkg:npm/%40nestjs/microservices"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"11.2.4"}]}],"versions":[]},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-m8vh-jmq9-5rjg","source_modified_at":"2026-09-30T00:00:03.849760028Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"@nestjs/microservices","ecosystem":"npm","purl":"pkg:npm/%40nestjs/microservices"},"ranges":[{"type":"SEMVER","events":[{"introduced":"12.0.0"},{"fixed":"12.0.2"}]}],"versions":[]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-m8vh-jmq9-5rjg","source_modified_at":"2026-09-29T23:54:45Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"npm","name":"@nestjs/microservices"},"version":"11.2.4"},{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-m8vh-jmq9-5rjg","source_modified_at":"2026-09-29T23:54:45Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"npm","name":"@nestjs/microservices"},"version":"12.0.2"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-m8vh-jmq9-5rjg","source_modified_at":"2026-09-30T00:00:03.849760028Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"@nestjs/microservices","ecosystem":"npm","purl":"pkg:npm/%40nestjs/microservices"},"version":"11.2.4"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-m8vh-jmq9-5rjg","source_modified_at":"2026-09-30T00:00:03.849760028Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"@nestjs/microservices","ecosystem":"npm","purl":"pkg:npm/%40nestjs/microservices"},"version":"12.0.2"}],"cvss":7.5,"severity":"High","kev":{"listed":false},"epss":{"probability":0.00376,"percentile":0.30393,"score_date":"2026-10-23"},"published_at":"2026-09-28T21:21:25.047Z","modified_at":"2026-09-30T00:00:03.849760028Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-m8vh-jmq9-5rjg","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-09-29T23:54:45Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-102281","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-09-29T12:50:34.126Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-m8vh-jmq9-5rjg","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-09-30T00:00:03.849760028Z"},{"source":"EPSS","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-102281","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-23"}],"sources":["GitHub Advisory Database","CVE List","OSV","EPSS"],"references":[{"source":"CVE List","url":"https://github.com/nestjs/nest/security/advisories/GHSA-m8vh-jmq9-5rjg","tags":["exploit"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-102281","source":"GitHub Advisory Database"},{"source":"CVE List","url":"https://github.com/nestjs/nest/pull/17737","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/nestjs/nest/commit/aa97b5144d8dff1ce700aac521eb86449a679d6f","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/nestjs/nest/commit/e9dcd4c7ac64361fbfe79461da85f5b3fc3e02da","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/nestjs/nest/releases/tag/v11.2.4","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/nestjs/nest/releases/tag/v12.0.2","tags":["x_refsource_MISC"]},{"url":"https://github.com/advisories/GHSA-m8vh-jmq9-5rjg","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","ssvc":{"exploitation":"poc","automatable":"yes","technical_impact":"partial","assessed_at":"2026-09-29T12:49:43.038730Z"},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"product","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-09-30T00:00:03.849760028Z","content_hash":"68d808de8706e98fa2d746d17da8c1ba6a29f10df30dc9bb8106789c58a9026a"}}
