{"id":"CVE-2026-102281","aliases":["CLSA-2026-1790870019","CLSA-2026-1790872587","CLSA-2026-1790881234","CLSA-2026-1790882031","CLSA-2026-1792160938","CLSA-2026-1792160959","CLSA-2026-1792160964","CLSA-2026-1792161436","CLSA-2026-1792161437","CLSA-2026-1792161438","CLSA-2026-1792161439","CLSA-2026-1792161497","CLSA-2026-1792161498","CLSA-2026-1792161499","CLSA-2026-1792161676","CLSA-2026-1792161677","CLSA-2026-1792161678","CLSA-2026-1792161679","CLSA-2026-1792161753","CLSA-2026-1792161754","CLSA-2026-1792161755","CLSA-2026-1792161756","CLSA-2026-1792161842","CLSA-2026-1792161843","CLSA-2026-1792161844","CLSA-2026-1792161845","CLSA-2026-1792161910","CLSA-2026-1792161911","CLSA-2026-1792161912","CLSA-2026-1792161970","CLSA-2026-1792161971","CLSA-2026-1792161972","CLSA-2026-1792162005","CLSA-2026-1792162006","CLSA-2026-1792162007","CLSA-2026-1792265594","CLSA-2026-1792325070","CLSA-2026-1792325945","EUVD-2026-88511","GHSA-96h4-vgxj-gvm2","GHSA-9c5c-9qcx-q35q","GHSA-m8vh-jmq9-5rjg"],"status":"published","title":"Nest: Remote process termination via a deeply nested microservice message pattern","description":"Nest is a framework for building scalable Node.js server-side applications. Prior to 11.2.4 and 12.0.2, a single message with a deeply nested object in its pattern can terminate a NestJS microservice using the TCP or RabbitMQ transport. ServerTCP#handleMessage and ServerRMQ#handleMessage pass a client-controlled non-string pattern to JSON.stringify to derive the handler lookup key; sufficiently deep nesting throws RangeError: Maximum call stack size exceeded, and the unhandled promise rejection terminates Node.js under its default behavior. An attacker who can reach the TCP port or publish to the consumed RabbitMQ queue or exchange can crash the service on demand; other transports are not affected because their patterns arrive as strings. This issue is fixed in versions 11.2.4 and 12.0.2.","severity":{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-12","score":0.00586,"percentile":0.48489,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-248","CWE-288","CWE-436","CWE-674","CWE-770"],"published":"2026-09-28T21:21:25Z","modified":"2026-11-10T19:58:32Z","fixes":[{"ecosystem":"npm","package":"@nestjs/microservices","fixed_in":["11.2.5","12.0.3","11.2.4","12.0.2"],"sources":["ghsa","osv"]},{"ecosystem":"npm","package":"@nestjs/platform-fastify","fixed_in":["11.2.4","12.0.2"],"sources":["ghsa","osv"]},{"ecosystem":"TuxCare:npm","package":"@nestjs/websockets","fixed_in":["10.4.22-tuxcare.3","11.2.2-tuxcare.1","11.2.3-tuxcare.1","11.2.4-tuxcare.1","10.4.22-tuxcare.4","11.2.2-tuxcare.2","11.2.3-tuxcare.2"],"sources":["osv"]},{"ecosystem":"TuxCare:npm","package":"@nestjs/core","fixed_in":["11.2.2-tuxcare.1","10.4.22-tuxcare.3","11.2.3-tuxcare.1","11.2.4-tuxcare.1"],"sources":["osv"]},{"ecosystem":"TuxCare:npm","package":"@nestjs/platform-socket.io","fixed_in":["11.2.3-tuxcare.1","10.4.22-tuxcare.3","11.2.2-tuxcare.1","11.2.4-tuxcare.1"],"sources":["osv"]},{"ecosystem":"TuxCare:npm","package":"@nestjs/testing","fixed_in":["10.4.22-tuxcare.3","11.2.2-tuxcare.1","11.2.3-tuxcare.1","11.2.4-tuxcare.1"],"sources":["osv"]},{"ecosystem":"TuxCare:npm","package":"@nestjs/common","fixed_in":["10.4.22-tuxcare.3","11.2.2-tuxcare.1","11.2.3-tuxcare.1","11.2.4-tuxcare.1"],"sources":["osv"]},{"ecosystem":"TuxCare:npm","package":"@nestjs/microservices","fixed_in":["10.4.22-tuxcare.3","11.2.2-tuxcare.1","11.2.3-tuxcare.1","11.2.4-tuxcare.1"],"sources":["osv"]},{"ecosystem":"TuxCare:npm","package":"@nestjs/platform-express","fixed_in":["10.4.22-tuxcare.3","11.2.2-tuxcare.1","11.2.3-tuxcare.1","11.2.4-tuxcare.1"],"sources":["osv"]},{"ecosystem":"TuxCare:npm","package":"@nestjs/platform-fastify","fixed_in":["10.4.22-tuxcare.3","11.2.2-tuxcare.1","11.2.3-tuxcare.1","11.2.4-tuxcare.1"],"sources":["osv"]},{"ecosystem":"TuxCare:npm","package":"@nestjs/platform-ws","fixed_in":["10.4.22-tuxcare.3","11.2.2-tuxcare.1","11.2.3-tuxcare.1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"@nestjs/microservices","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"11.2.5"}]}]},{"source":"ghsa","ecosystem":"npm","package":"@nestjs/microservices","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"12.0.0"},{"fixed":"12.0.3"}]}]},{"source":"ghsa","ecosystem":"npm","package":"@nestjs/platform-fastify","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"11.2.4"}]}]},{"source":"ghsa","ecosystem":"npm","package":"@nestjs/platform-fastify","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"12.0.0"},{"fixed":"12.0.2"}]}]},{"source":"ghsa","ecosystem":"npm","package":"@nestjs/microservices","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"11.2.4"}]}]},{"source":"ghsa","ecosystem":"npm","package":"@nestjs/microservices","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"12.0.0"},{"fixed":"12.0.2"}]}]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/websockets","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"10.4.22-tuxcare.0"},{"fixed":"10.4.22-tuxcare.3"}]}],"versions":["10.4.22","10.4.22-tuxcare.1","10.4.22-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/websockets","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.2-tuxcare.0"},{"fixed":"11.2.2-tuxcare.1"}]}],"versions":["11.2.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/websockets","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.3-tuxcare.0"},{"fixed":"11.2.3-tuxcare.1"}]}],"versions":["11.2.3"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/websockets","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.4-tuxcare.0"},{"fixed":"11.2.4-tuxcare.1"}]}],"versions":["11.2.4"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/core","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.2-tuxcare.0"},{"fixed":"11.2.2-tuxcare.1"}]}],"versions":["11.2.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-socket.io","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.3-tuxcare.0"},{"fixed":"11.2.3-tuxcare.1"}]}],"versions":["11.2.3"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/testing","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"10.4.22-tuxcare.0"},{"fixed":"10.4.22-tuxcare.3"}]}],"versions":["10.4.22","10.4.22-tuxcare.1","10.4.22-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/common","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"10.4.22-tuxcare.0"},{"fixed":"10.4.22-tuxcare.3"}]}],"versions":["10.4.22","10.4.22-tuxcare.1","10.4.22-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/common","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.2-tuxcare.0"},{"fixed":"11.2.2-tuxcare.1"}]}],"versions":["11.2.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/common","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.3-tuxcare.0"},{"fixed":"11.2.3-tuxcare.1"}]}],"versions":["11.2.3"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/common","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.4-tuxcare.0"},{"fixed":"11.2.4-tuxcare.1"}]}],"versions":["11.2.4"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/core","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"10.4.22-tuxcare.0"},{"fixed":"10.4.22-tuxcare.3"}]}],"versions":["10.4.22","10.4.22-tuxcare.1","10.4.22-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/core","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.3-tuxcare.0"},{"fixed":"11.2.3-tuxcare.1"}]}],"versions":["11.2.3"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/core","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.4-tuxcare.0"},{"fixed":"11.2.4-tuxcare.1"}]}],"versions":["11.2.4"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/microservices","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"10.4.22-tuxcare.0"},{"fixed":"10.4.22-tuxcare.3"}]}],"versions":["10.4.22","10.4.22-tuxcare.1","10.4.22-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/microservices","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.2-tuxcare.0"},{"fixed":"11.2.2-tuxcare.1"}]}],"versions":["11.2.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/microservices","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.3-tuxcare.0"},{"fixed":"11.2.3-tuxcare.1"}]}],"versions":["11.2.3"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/microservices","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.4-tuxcare.0"},{"fixed":"11.2.4-tuxcare.1"}]}],"versions":["11.2.4"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-express","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"10.4.22-tuxcare.0"},{"fixed":"10.4.22-tuxcare.3"}]}],"versions":["10.4.22","10.4.22-tuxcare.1","10.4.22-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-express","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.2-tuxcare.0"},{"fixed":"11.2.2-tuxcare.1"}]}],"versions":["11.2.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-express","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.3-tuxcare.0"},{"fixed":"11.2.3-tuxcare.1"}]}],"versions":["11.2.3"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-express","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.4-tuxcare.0"},{"fixed":"11.2.4-tuxcare.1"}]}],"versions":["11.2.4"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-fastify","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"10.4.22-tuxcare.0"},{"fixed":"10.4.22-tuxcare.3"}]}],"versions":["10.4.22","10.4.22-tuxcare.1","10.4.22-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-fastify","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.2-tuxcare.0"},{"fixed":"11.2.2-tuxcare.1"}]}],"versions":["11.2.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-fastify","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.3-tuxcare.0"},{"fixed":"11.2.3-tuxcare.1"}]}],"versions":["11.2.3"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-fastify","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.4-tuxcare.0"},{"fixed":"11.2.4-tuxcare.1"}]}],"versions":["11.2.4"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-socket.io","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"10.4.22-tuxcare.0"},{"fixed":"10.4.22-tuxcare.3"}]}],"versions":["10.4.22","10.4.22-tuxcare.1","10.4.22-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-socket.io","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.2-tuxcare.0"},{"fixed":"11.2.2-tuxcare.1"}]}],"versions":["11.2.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-socket.io","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.4-tuxcare.0"},{"fixed":"11.2.4-tuxcare.1"}]}],"versions":["11.2.4"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-ws","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"10.4.22-tuxcare.0"},{"fixed":"10.4.22-tuxcare.3"}]}],"versions":["10.4.22","10.4.22-tuxcare.1","10.4.22-tuxcare.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-ws","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.2-tuxcare.0"},{"fixed":"11.2.2-tuxcare.1"}]}],"versions":["11.2.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/platform-ws","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.3-tuxcare.0"},{"fixed":"11.2.3-tuxcare.1"}]}],"versions":["11.2.3"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/testing","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.2-tuxcare.0"},{"fixed":"11.2.2-tuxcare.1"}]}],"versions":["11.2.2"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/testing","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.3-tuxcare.0"},{"fixed":"11.2.3-tuxcare.1"}]}],"versions":["11.2.3"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/testing","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.4-tuxcare.0"},{"fixed":"11.2.4-tuxcare.1"}]}],"versions":["11.2.4"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/websockets","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"10.4.22-tuxcare.0"},{"fixed":"10.4.22-tuxcare.4"}]}],"versions":["10.4.22","10.4.22-tuxcare.1","10.4.22-tuxcare.2","10.4.22-tuxcare.3"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/websockets","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.2-tuxcare.0"},{"fixed":"11.2.2-tuxcare.2"}]}],"versions":["11.2.2","11.2.2-tuxcare.1"]},{"source":"osv","ecosystem":"TuxCare:npm","package":"@nestjs/websockets","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"11.2.3-tuxcare.0"},{"fixed":"11.2.3-tuxcare.2"}]}],"versions":["11.2.3","11.2.3-tuxcare.1"]},{"source":"osv","ecosystem":"npm","package":"@nestjs/microservices","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"11.2.5"}]}]},{"source":"osv","ecosystem":"npm","package":"@nestjs/microservices","ranges":[{"type":"SEMVER","events":[{"introduced":"12.0.0"},{"fixed":"12.0.3"}]}]},{"source":"osv","ecosystem":"npm","package":"@nestjs/platform-fastify","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"11.2.4"}]}]},{"source":"osv","ecosystem":"npm","package":"@nestjs/platform-fastify","ranges":[{"type":"SEMVER","events":[{"introduced":"12.0.0"},{"fixed":"12.0.2"}]}]},{"source":"osv","ecosystem":"npm","package":"@nestjs/microservices","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"11.2.4"}]}]},{"source":"osv","ecosystem":"npm","package":"@nestjs/microservices","ranges":[{"type":"SEMVER","events":[{"introduced":"12.0.0"},{"fixed":"12.0.2"}]}]}],"products":[{"vendor":"nestjs","product":"nest"}],"references":[{"url":"https://github.com/nestjs/nest/security/advisories/GHSA-m8vh-jmq9-5rjg","tags":["x_refsource_CONFIRM","exploit","advisory","web"]},{"url":"https://github.com/nestjs/nest/pull/17737","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/nestjs/nest/commit/aa97b5144d8dff1ce700aac521eb86449a679d6f","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/nestjs/nest/commit/e9dcd4c7ac64361fbfe79461da85f5b3fc3e02da","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/nestjs/nest/releases/tag/v11.2.4","tags":["x_refsource_MISC","web"]},{"url":"https://github.com/nestjs/nest/releases/tag/v12.0.2","tags":["x_refsource_MISC","web"]},{"url":"https://github.com/nestjs/nest/security/advisories/GHSA-96h4-vgxj-gvm2","tags":["web"]},{"url":"https://github.com/nestjs/nest/pull/17746","tags":["web"]},{"url":"https://github.com/nestjs/nest/pull/17749","tags":["web"]},{"url":"https://github.com/nestjs/nest/commit/6ca2dd894a6ff964d318724f363061652e822920","tags":["web"]},{"url":"https://github.com/nestjs/nest/commit/781843ac98d429fe1d541c52c7126850be5989a7","tags":["web"]},{"url":"https://github.com/nestjs/nest/commit/dee4ed4dbc2e18e1e722619927647f5441dfe812","tags":["web"]},{"url":"https://github.com/nestjs/nest/releases/tag/v11.2.5","tags":["web"]},{"url":"https://github.com/nestjs/nest/releases/tag/v12.0.3","tags":["web"]},{"url":"https://github.com/advisories/GHSA-96h4-vgxj-gvm2"},{"url":"https://github.com/fastify/middie/security/advisories/GHSA-hx87-8wv7-pjv8","tags":["web"]},{"url":"https://github.com/nestjs/nest/security/advisories/GHSA-9c5c-9qcx-q35q","tags":["web"]},{"url":"https://github.com/nestjs/nest/commit/5226fe084cf64b357de436f154bc89f2d319b621","tags":["web"]},{"url":"https://github.com/nestjs/nest/commit/dda252090ecb65009d9ff366444303796fc44fd7","tags":["web"]},{"url":"https://github.com/advisories/GHSA-9c5c-9qcx-q35q"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-102281","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-m8vh-jmq9-5rjg"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/102xxx/CVE-2026-102281.json","tags":["advisory"]},{"url":"https://github.com/nestjs/nest","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-102281","title":"Nest: Remote process termination via a deeply nested microservice message pattern","description":"Nest is a framework for building scalable Node.js server-side applications. Prior to 11.2.4 and 12.0.2, a single message with a deeply nested object in its pattern can terminate a NestJS microservice using the TCP or RabbitMQ transport. ServerTCP#handleMessage and ServerRMQ#handleMessage pass a client-controlled non-string pattern to JSON.stringify to derive the handler lookup key; sufficiently deep nesting throws RangeError: Maximum call stack size exceeded, and the unhandled promise rejection terminates Node.js under its default behavior. An attacker who can reach the TCP port or publish to the consumed RabbitMQ queue or exchange can crash the service on demand; other transports are not affected because their patterns arrive as strings. This issue is fixed in versions 11.2.4 and 12.0.2.","status":"published","published":"2026-09-28T21:21:25.047Z","modified":"2026-09-29T12:50:34.126Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high","assessor":"cna"}],"cwes":["CWE-248","CWE-674"],"updated_at":"2026-11-02T13:38:54.394896Z"}],"euvd":[{"id":"EUVD-2026-88511","description":"Nest is a framework for building scalable Node.js server-side applications. Prior to 11.2.4 and 12.0.2, a single message with a deeply nested object in its pattern can terminate a NestJS microservice using the TCP or RabbitMQ transport. ServerTCP#handleMessage and ServerRMQ#handleMessage pass a client-controlled non-string pattern to JSON.stringify to derive the handler lookup key; sufficiently deep nesting throws RangeError: Maximum call stack size exceeded, and the unhandled promise rejection terminates Node.js under its default behavior. An attacker who can reach the TCP port or publish to the consumed RabbitMQ queue or exchange can crash the service on demand; other transports are not affected because their patterns arrive as strings. This issue is fixed in versions 11.2.4 and 12.0.2.","status":"published","published":"2026-09-28T21:21:25Z","modified":"2026-09-29T12:50:34Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"updated_at":"2026-11-02T17:27:52.331616Z"}],"ghsa":[{"id":"GHSA-96h4-vgxj-gvm2","title":"Nest: Unbounded memory growth in the NestJS TCP microservice transport","description":"## Summary\n\nA peer that can open a TCP connection to a NestJS microservice using the built-in TCP\ntransport can make the server process allocate memory without limit, on either side of the\nconnection, until the process is killed by the OS or by its container memory limit. No\nauthentication, no credentials, and no valid message are required.\n\nApplications are affected only if they start a microservice with `Transport.TCP` and the\ntransport's port is reachable by an untrusted peer.\n\n\n## Affected versions\n\n| Package | Affected | Patched |\n|---|---|---|\n| `@nestjs/microservices` | `\u003e= 12.0.0, \u003c 12.0.3` | **12.0.3** |\n| `@nestjs/microservices` | `\u003c 11.2.5` | **11.2.5** |\n\nThe same code is present in the 10.x line and earlier. Those lines are end-of-life and\nwill not receive a patch; upgrade to a supported major.\n\nOnly `@nestjs/microservices` is affected. No other package needs updating for this issue.\n\n## Details\n\nTwo independent paths let one peer grow the heap without bound.\n\n### Partial packets are buffered with nothing to reap them\n\nThe TCP transport frames messages as `\u003clength\u003e#\u003cpayload\u003e`. A peer may declare a length,\nsend part of the payload, and then stop. `JsonSocket` keeps the partial payload buffered\nwhile it waits for the rest, and nothing ever reclaimed it: there was no socket timeout, no\ncap on the number of connections, and no tracking of accepted sockets.\n\n`maxBufferSize` did not close this. It caps a single connection, defaulting to 128M\ncharacters, and is enforced per connection, so the effective ceiling was the number of\nconnections an attacker chose to open.\n\nTen connections that each send 20MB and then go silent:\n\n| | rss | heapUsed |\n|---|---|---|\n| baseline | 152.3MB | 28.1MB |\n| after 200MB sent, all stalled | 561.2MB | 229.5MB |\n\nThe memory was held for as long as the connections stayed open. Closing them released it,\nso a peer could hold it indefinitely at negligible cost to itself.\n\n### Response backpressure was ignored\n\n`JsonSocket#handleSend` discarded the return value of `socket.write`. A peer that issues\nrequests and never reads the responses therefore made the process queue every response in\nmemory, with no ceiling and no signal to stop producing more.\n\nThirty requests from a client whose stream is paused, against a handler returning an 8MB\npayload, grew rss from 152.4MB to 419.1MB. The amplification here is roughly 1:1, because\nthe response size is set by the application rather than by the attacker; the defect is that\nthe server buffers all of it rather than applying backpressure or giving up.\n\n## Impact\n\nAn unauthenticated peer that can reach the transport's port can drive the process to an\nout-of-memory kill. Under a container memory limit this is fast and repeatable, and it\nrestarts the pod rather than merely degrading it.\n\nThere is no confidentiality or integrity impact. Nothing is read, written, or executed;\nthe failure mode is availability only.\n\nApplications are not affected if the TCP transport is not used, or if the transport's port\nis reachable only by trusted peers.\n\n## Patches\n\nUpgrade `@nestjs/microservices` to **12.0.3** or **11.2.5**.\n\nThree changes landed together:\n\n- **A stall timer drops a peer that stops sending mid-packet.** It is armed only while a\n  packet is partially received and is refreshed on every read, so a slow but progressing\n  transfer is never interrupted and a peer sitting idle between packets is left alone.\n  Configurable as `incompleteMessageTimeout`, default 30000ms.\n- **Reading is suspended while a peer's outgoing buffer is backed up** and resumes on\n  `drain`, so a peer that stops reading cannot keep issuing requests.\n- **Responses queued for a peer that reads nothing are capped.** Suspending reads is not\n  sufficient on its own, because message handlers are asynchronous: a burst of pipelined\n  requests is dispatched before the first response is written, and those responses still\n  queue. Configurable as `maxSendBufferSize`, default 128MB.\n\nBoth limits are configurable on the server and on the client, and either can be disabled by\nsetting it to `0`.\n\n### Behaviour change\n\nBoth limits are enabled by default, following the precedent set by `maxBufferSize`. A peer\nthat stops sending mid-packet for 30 seconds, or that lets more than 128MB of responses\nqueue unread on a single connection, is now disconnected where previously it was not.\n\nThe send cap can also drop a peer that is genuinely reading, if responses are produced\nfaster than the socket drains for long enough. The default is set high for that reason.\nApplications that stream very large responses to deliberately slow consumers should raise\n`maxSendBufferSize` or set it to `0`.\n\n## Workarounds\n\nFor anyone who cannot upgrade immediately:\n\n- **Restrict who can reach the port.** The TCP transport is designed for trusted\n  service-to-service traffic. A network policy, security group, or L4 firewall that limits\n  the port to known peers removes the exposure entirely, and is worth doing regardless of\n  version.\n- **Lower `maxBufferSize`.** This reduces what a single connection can pin on the receive\n  side. It does not bound the total, because the limit is per connection and the number of\n  connections is not capped, and it does nothing for the response-queueing path.\n- **Supply a custom `socketClass`.** An application-provided socket class can implement its\n  own idle timeout and backpressure handling. This is the only pre-patch mitigation that\n  addresses the sending side.\n\nSetting a process memory limit does not mitigate this. It converts the failure from an\nout-of-memory kill of the host into an out-of-memory kill of the process.\n\n## Credit\n\nReported by Salman Aljardan, who provided a detailed write-up and self-contained proofs of\nconcept for each issue, and coordinated disclosure.","status":"published","published":"2026-09-30T14:44:21Z","modified":"2026-09-30T14:44:24Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"medium"}],"cwes":["CWE-770"],"updated_at":"2026-11-02T14:41:23.783773Z"},{"id":"GHSA-9c5c-9qcx-q35q","title":"@nestjs/platform-fastify: Path-scoped middleware bypass via absolute-form request targets","description":"| Field | Value |\n| --- | --- |\n| Ecosystem | npm |\n| Package | `@nestjs/platform-fastify` |\n| Affected versions | `\u003e= 12.0.0, \u003c 12.0.2` and `\u003c 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\nOn the Fastify adapter, an HTTP request that uses an **absolute-form request target** (`GET http://host/path HTTP/1.1`\ninstead of `GET /path HTTP/1.1`) reaches the route handler without running the path-scoped Nest middleware bound to\nthat route. Applications that enforce authentication or authorization in middleware execute the protected handler\nwith those checks skipped.\n\n### Impact\n\nAny application that\n\n- uses `@nestjs/platform-fastify`, and\n- binds middleware to specific paths via `MiddlewareConsumer.forRoutes(...)` or `.exclude(...)`, and\n- is reachable by a client that controls the raw request line.\n\nNode's HTTP server accepts absolute-form targets, so no special server configuration is needed. Exposure is reduced\nwhen a reverse proxy in front of the application rewrites the request target to origin-form, which most do.\n\nWhere the bypassed middleware performs authentication or authorization, the result is an authentication or\nauthorization bypass. Where it performs logging, rate limiting or body handling, those are silently skipped instead.\n\n### Details\n\nFastify's router (`find-my-way`) resolves an absolute-form target to its path before matching, so the route handler\nis dispatched normally. Two places on the middleware side matched against the **raw** request target instead:\n\n1. The bundled copy of the `@fastify/middie` engine at `packages/platform-fastify/adapters/middie/fastify-middie.ts`.\n   NestJS carried this fork to apply an earlier path-decoding fix and it did not track the upstream absolute-form fix\n   released in `@fastify/middie@9.3.4`.\n2. `FastifyAdapter`'s own re-check in `createMiddlewareFactory()`, which tests the middleware path regexp against\n   `req.originalUrl`.\n\nBoth normalized and percent-decoded the target, but neither resolved absolute-form to a path, so the router and the\nmiddleware layer disagreed about which path was being requested.\n\nA second, related defect contributed. Because the adapter always passes `routerOptions` (to install the version\nconstraint), Fastify did not reflect the deprecated **top-level** router options (`ignoreTrailingSlash`,\n`ignoreDuplicateSlashes`, `caseSensitive`, `useSemicolonDelimiter`) in `initialConfig.routerOptions`, which is what\nthe middleware engine reads. Applications passing those options at the top level had middleware normalize paths\ndifferently from the router, which widened the mismatch.\n\n### Proof of concept\n\n```ts\n@Controller('users')\nexport class UsersController {\n  @Get()\n  findAll() {\n    return 'protected data';\n  }\n}\n\n@Module({ controllers: [UsersController] })\nexport class AppModule implements NestModule {\n  configure(consumer: MiddlewareConsumer) {\n    consumer\n      .apply((req, res) =\u003e res.end('blocked by auth middleware'))\n      .forRoutes({ path: 'users', method: RequestMethod.GET });\n  }\n}\n```\n\n`supertest` and `light-my-request` always emit origin-form targets, so the request has to be written to the socket:\n\n```js\nconst { connect } = require('node:net');\n\nconst socket = connect(3000, '127.0.0.1', () =\u003e {\n  socket.write(\n    'GET http://127.0.0.1:3000/users HTTP/1.1\\r\\n' +\n      'Host: 127.0.0.1:3000\\r\\n' +\n      'Connection: close\\r\\n\\r\\n',\n  );\n});\nsocket.pipe(process.stdout);\n```\n\nObserved on an affected version: `protected data` — the middleware did not run.\nExpected, and observed on a patched version: `blocked by auth middleware`.\n\n### Patches\n\nFixed in **12.0.2** and **11.2.4**. Upgrading to **12.0.3** or **11.2.5** is recommended.\n\n- The bundled `@fastify/middie` fork was removed and the package now depends on `@fastify/middie@9.3.4`, which\n  resolves absolute-form targets before matching.\n- The adapter resolves absolute-form targets in its own route check, mirroring `find-my-way`.\n- Deprecated top-level Fastify router options are folded into `routerOptions` so the middleware engine and the\n  router normalize paths identically.\n\n### Workarounds\n\nIf you cannot upgrade, reject non-origin-form request targets before middleware runs. Register the hook on the\nFastify instance **before the application is initialized**, so that it runs ahead of the middleware engine's own\n`onRequest` hook, and confirm with the request above that the rejection takes effect:\n\n```ts\nconst adapter = new FastifyAdapter();\nadapter.getInstance().addHook('onRequest', (request, reply, done) =\u003e {\n  const target = request.raw.url ?? '';\n  // \"*\" is the legitimate request target of \"OPTIONS * HTTP/1.1\"\n  if (target[0] !== '/' \u0026\u0026 target !== '*') {\n    reply.code(400).send();\n    return;\n  }\n  done();\n});\n```\n\nRejecting or normalizing absolute-form targets at a reverse proxy in front of the application is equally effective.\n\n### Credit\n\nReported by ZeroVuln Labs.","status":"published","published":"2026-09-30T14:41:39Z","modified":"2026-09-30T14:41:40Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high"}],"cwes":["CWE-288","CWE-436"],"updated_at":"2026-11-02T14:41:23.783773Z"},{"id":"GHSA-m8vh-jmq9-5rjg","title":"Nest: Remote process termination via a deeply nested microservice message pattern","description":"| Field | Value |\n| --- | --- |\n| Ecosystem | npm |\n| Package | `@nestjs/microservices` |\n| Affected versions | `\u003e= 12.0.0, \u003c 12.0.2` and `\u003c 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', () =\u003e {\n  // Nest's TCP framing is \u003cbyteLength\u003e#\u003cjson\u003e\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.","status":"published","published":"2026-09-29T23:54:44Z","modified":"2026-09-29T23:54:45Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"cwes":["CWE-248","CWE-674"],"updated_at":"2026-11-02T14:41:23.783773Z"}],"nvd":[{"id":"CVE-2026-102281","description":"Nest is a framework for building scalable Node.js server-side applications. Prior to 11.2.4 and 12.0.2, a single message with a deeply nested object in its pattern can terminate a NestJS microservice using the TCP or RabbitMQ transport. ServerTCP#handleMessage and ServerRMQ#handleMessage pass a client-controlled non-string pattern to JSON.stringify to derive the handler lookup key; sufficiently deep nesting throws RangeError: Maximum call stack size exceeded, and the unhandled promise rejection terminates Node.js under its default behavior. An attacker who can reach the TCP port or publish to the consumed RabbitMQ queue or exchange can crash the service on demand; other transports are not affected because their patterns arrive as strings. This issue is fixed in versions 11.2.4 and 12.0.2.","status":"published","published":"2026-09-28T22:17:32.05Z","modified":"2026-09-30T19:56:45.443Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high","assessor":"secondary"}],"cwes":["CWE-248","CWE-674"],"updated_at":"2026-11-02T14:12:52.413234Z"}],"osv":[{"id":"CVE-2026-102281","title":"Nest: Remote process termination via a deeply nested microservice message pattern","description":"Nest is a framework for building scalable Node.js server-side applications. Prior to 11.2.4 and 12.0.2, a single message with a deeply nested object in its pattern can terminate a NestJS microservice using the TCP or RabbitMQ transport. ServerTCP#handleMessage and ServerRMQ#handleMessage pass a client-controlled non-string pattern to JSON.stringify to derive the handler lookup key; sufficiently deep nesting throws RangeError: Maximum call stack size exceeded, and the unhandled promise rejection terminates Node.js under its default behavior. An attacker who can reach the TCP port or publish to the consumed RabbitMQ queue or exchange can crash the service on demand; other transports are not affected because their patterns arrive as strings. This issue is fixed in versions 11.2.4 and 12.0.2.","status":"published","published":"2026-09-28T21:21:25.047Z","modified":"2026-10-28T02:31:10.951799145Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"cwes":["CWE-248","CWE-674"],"updated_at":"2026-11-02T15:44:53.83521Z"},{"id":"GHSA-96h4-vgxj-gvm2","title":"Nest: Unbounded memory growth in the NestJS TCP microservice transport","description":"## Summary\n\nA peer that can open a TCP connection to a NestJS microservice using the built-in TCP\ntransport can make the server process allocate memory without limit, on either side of the\nconnection, until the process is killed by the OS or by its container memory limit. No\nauthentication, no credentials, and no valid message are required.\n\nApplications are affected only if they start a microservice with `Transport.TCP` and the\ntransport's port is reachable by an untrusted peer.\n\n\n## Affected versions\n\n| Package | Affected | Patched |\n|---|---|---|\n| `@nestjs/microservices` | `\u003e= 12.0.0, \u003c 12.0.3` | **12.0.3** |\n| `@nestjs/microservices` | `\u003c 11.2.5` | **11.2.5** |\n\nThe same code is present in the 10.x line and earlier. Those lines are end-of-life and\nwill not receive a patch; upgrade to a supported major.\n\nOnly `@nestjs/microservices` is affected. No other package needs updating for this issue.\n\n## Details\n\nTwo independent paths let one peer grow the heap without bound.\n\n### Partial packets are buffered with nothing to reap them\n\nThe TCP transport frames messages as `\u003clength\u003e#\u003cpayload\u003e`. A peer may declare a length,\nsend part of the payload, and then stop. `JsonSocket` keeps the partial payload buffered\nwhile it waits for the rest, and nothing ever reclaimed it: there was no socket timeout, no\ncap on the number of connections, and no tracking of accepted sockets.\n\n`maxBufferSize` did not close this. It caps a single connection, defaulting to 128M\ncharacters, and is enforced per connection, so the effective ceiling was the number of\nconnections an attacker chose to open.\n\nTen connections that each send 20MB and then go silent:\n\n| | rss | heapUsed |\n|---|---|---|\n| baseline | 152.3MB | 28.1MB |\n| after 200MB sent, all stalled | 561.2MB | 229.5MB |\n\nThe memory was held for as long as the connections stayed open. Closing them released it,\nso a peer could hold it indefinitely at negligible cost to itself.\n\n### Response backpressure was ignored\n\n`JsonSocket#handleSend` discarded the return value of `socket.write`. A peer that issues\nrequests and never reads the responses therefore made the process queue every response in\nmemory, with no ceiling and no signal to stop producing more.\n\nThirty requests from a client whose stream is paused, against a handler returning an 8MB\npayload, grew rss from 152.4MB to 419.1MB. The amplification here is roughly 1:1, because\nthe response size is set by the application rather than by the attacker; the defect is that\nthe server buffers all of it rather than applying backpressure or giving up.\n\n## Impact\n\nAn unauthenticated peer that can reach the transport's port can drive the process to an\nout-of-memory kill. Under a container memory limit this is fast and repeatable, and it\nrestarts the pod rather than merely degrading it.\n\nThere is no confidentiality or integrity impact. Nothing is read, written, or executed;\nthe failure mode is availability only.\n\nApplications are not affected if the TCP transport is not used, or if the transport's port\nis reachable only by trusted peers.\n\n## Patches\n\nUpgrade `@nestjs/microservices` to **12.0.3** or **11.2.5**.\n\nThree changes landed together:\n\n- **A stall timer drops a peer that stops sending mid-packet.** It is armed only while a\n  packet is partially received and is refreshed on every read, so a slow but progressing\n  transfer is never interrupted and a peer sitting idle between packets is left alone.\n  Configurable as `incompleteMessageTimeout`, default 30000ms.\n- **Reading is suspended while a peer's outgoing buffer is backed up** and resumes on\n  `drain`, so a peer that stops reading cannot keep issuing requests.\n- **Responses queued for a peer that reads nothing are capped.** Suspending reads is not\n  sufficient on its own, because message handlers are asynchronous: a burst of pipelined\n  requests is dispatched before the first response is written, and those responses still\n  queue. Configurable as `maxSendBufferSize`, default 128MB.\n\nBoth limits are configurable on the server and on the client, and either can be disabled by\nsetting it to `0`.\n\n### Behaviour change\n\nBoth limits are enabled by default, following the precedent set by `maxBufferSize`. A peer\nthat stops sending mid-packet for 30 seconds, or that lets more than 128MB of responses\nqueue unread on a single connection, is now disconnected where previously it was not.\n\nThe send cap can also drop a peer that is genuinely reading, if responses are produced\nfaster than the socket drains for long enough. The default is set high for that reason.\nApplications that stream very large responses to deliberately slow consumers should raise\n`maxSendBufferSize` or set it to `0`.\n\n## Workarounds\n\nFor anyone who cannot upgrade immediately:\n\n- **Restrict who can reach the port.** The TCP transport is designed for trusted\n  service-to-service traffic. A network policy, security group, or L4 firewall that limits\n  the port to known peers removes the exposure entirely, and is worth doing regardless of\n  version.\n- **Lower `maxBufferSize`.** This reduces what a single connection can pin on the receive\n  side. It does not bound the total, because the limit is per connection and the number of\n  connections is not capped, and it does nothing for the response-queueing path.\n- **Supply a custom `socketClass`.** An application-provided socket class can implement its\n  own idle timeout and backpressure handling. This is the only pre-patch mitigation that\n  addresses the sending side.\n\nSetting a process memory limit does not mitigate this. It converts the failure from an\nout-of-memory kill of the host into an out-of-memory kill of the process.\n\n## Credit\n\nReported by Salman Aljardan, who provided a detailed write-up and self-contained proofs of\nconcept for each issue, and coordinated disclosure.","status":"published","published":"2026-09-30T14:44:21Z","modified":"2026-09-30T15:00:05.887593652Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"medium"}],"cwes":["CWE-770"],"updated_at":"2026-11-02T15:46:43.123867Z"},{"id":"GHSA-9c5c-9qcx-q35q","title":"@nestjs/platform-fastify: Path-scoped middleware bypass via absolute-form request targets","description":"| Field | Value |\n| --- | --- |\n| Ecosystem | npm |\n| Package | `@nestjs/platform-fastify` |\n| Affected versions | `\u003e= 12.0.0, \u003c 12.0.2` and `\u003c 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\nOn the Fastify adapter, an HTTP request that uses an **absolute-form request target** (`GET http://host/path HTTP/1.1`\ninstead of `GET /path HTTP/1.1`) reaches the route handler without running the path-scoped Nest middleware bound to\nthat route. Applications that enforce authentication or authorization in middleware execute the protected handler\nwith those checks skipped.\n\n### Impact\n\nAny application that\n\n- uses `@nestjs/platform-fastify`, and\n- binds middleware to specific paths via `MiddlewareConsumer.forRoutes(...)` or `.exclude(...)`, and\n- is reachable by a client that controls the raw request line.\n\nNode's HTTP server accepts absolute-form targets, so no special server configuration is needed. Exposure is reduced\nwhen a reverse proxy in front of the application rewrites the request target to origin-form, which most do.\n\nWhere the bypassed middleware performs authentication or authorization, the result is an authentication or\nauthorization bypass. Where it performs logging, rate limiting or body handling, those are silently skipped instead.\n\n### Details\n\nFastify's router (`find-my-way`) resolves an absolute-form target to its path before matching, so the route handler\nis dispatched normally. Two places on the middleware side matched against the **raw** request target instead:\n\n1. The bundled copy of the `@fastify/middie` engine at `packages/platform-fastify/adapters/middie/fastify-middie.ts`.\n   NestJS carried this fork to apply an earlier path-decoding fix and it did not track the upstream absolute-form fix\n   released in `@fastify/middie@9.3.4`.\n2. `FastifyAdapter`'s own re-check in `createMiddlewareFactory()`, which tests the middleware path regexp against\n   `req.originalUrl`.\n\nBoth normalized and percent-decoded the target, but neither resolved absolute-form to a path, so the router and the\nmiddleware layer disagreed about which path was being requested.\n\nA second, related defect contributed. Because the adapter always passes `routerOptions` (to install the version\nconstraint), Fastify did not reflect the deprecated **top-level** router options (`ignoreTrailingSlash`,\n`ignoreDuplicateSlashes`, `caseSensitive`, `useSemicolonDelimiter`) in `initialConfig.routerOptions`, which is what\nthe middleware engine reads. Applications passing those options at the top level had middleware normalize paths\ndifferently from the router, which widened the mismatch.\n\n### Proof of concept\n\n```ts\n@Controller('users')\nexport class UsersController {\n  @Get()\n  findAll() {\n    return 'protected data';\n  }\n}\n\n@Module({ controllers: [UsersController] })\nexport class AppModule implements NestModule {\n  configure(consumer: MiddlewareConsumer) {\n    consumer\n      .apply((req, res) =\u003e res.end('blocked by auth middleware'))\n      .forRoutes({ path: 'users', method: RequestMethod.GET });\n  }\n}\n```\n\n`supertest` and `light-my-request` always emit origin-form targets, so the request has to be written to the socket:\n\n```js\nconst { connect } = require('node:net');\n\nconst socket = connect(3000, '127.0.0.1', () =\u003e {\n  socket.write(\n    'GET http://127.0.0.1:3000/users HTTP/1.1\\r\\n' +\n      'Host: 127.0.0.1:3000\\r\\n' +\n      'Connection: close\\r\\n\\r\\n',\n  );\n});\nsocket.pipe(process.stdout);\n```\n\nObserved on an affected version: `protected data` — the middleware did not run.\nExpected, and observed on a patched version: `blocked by auth middleware`.\n\n### Patches\n\nFixed in **12.0.2** and **11.2.4**. Upgrading to **12.0.3** or **11.2.5** is recommended.\n\n- The bundled `@fastify/middie` fork was removed and the package now depends on `@fastify/middie@9.3.4`, which\n  resolves absolute-form targets before matching.\n- The adapter resolves absolute-form targets in its own route check, mirroring `find-my-way`.\n- Deprecated top-level Fastify router options are folded into `routerOptions` so the middleware engine and the\n  router normalize paths identically.\n\n### Workarounds\n\nIf you cannot upgrade, reject non-origin-form request targets before middleware runs. Register the hook on the\nFastify instance **before the application is initialized**, so that it runs ahead of the middleware engine's own\n`onRequest` hook, and confirm with the request above that the rejection takes effect:\n\n```ts\nconst adapter = new FastifyAdapter();\nadapter.getInstance().addHook('onRequest', (request, reply, done) =\u003e {\n  const target = request.raw.url ?? '';\n  // \"*\" is the legitimate request target of \"OPTIONS * HTTP/1.1\"\n  if (target[0] !== '/' \u0026\u0026 target !== '*') {\n    reply.code(400).send();\n    return;\n  }\n  done();\n});\n```\n\nRejecting or normalizing absolute-form targets at a reverse proxy in front of the application is equally effective.\n\n### Credit\n\nReported by ZeroVuln Labs.","status":"published","published":"2026-09-30T14:41:39Z","modified":"2026-09-30T15:00:05.347048398Z","cvss":[{"version":"3.1","score":7.4,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N","level":"high"}],"cwes":["CWE-288","CWE-436"],"updated_at":"2026-11-02T15:46:43.524801Z"},{"id":"GHSA-m8vh-jmq9-5rjg","title":"Nest: Remote process termination via a deeply nested microservice message pattern","description":"| Field | Value |\n| --- | --- |\n| Ecosystem | npm |\n| Package | `@nestjs/microservices` |\n| Affected versions | `\u003e= 12.0.0, \u003c 12.0.2` and `\u003c 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', () =\u003e {\n  // Nest's TCP framing is \u003cbyteLength\u003e#\u003cjson\u003e\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.","status":"published","published":"2026-09-29T23:54:44Z","modified":"2026-09-30T00:00:03.849760028Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"cwes":["CWE-248","CWE-674"],"updated_at":"2026-11-02T15:46:51.463834Z"},{"id":"CLSA-2026-1790870019","title":"TuxCare security update for @nestjs/websockets (1 CVE)","description":"TuxCare rebuilt @nestjs/websockets to address 1 CVE. Fixed in 10.4.22-tuxcare.3.","status":"published","published":"2026-10-01T15:53:39Z","modified":"2026-10-15T09:48:04.062406404Z","updated_at":"2026-11-02T15:43:48.65893Z"},{"id":"CLSA-2026-1790872587","title":"TuxCare security update for @nestjs/websockets (2 CVEs)","description":"TuxCare rebuilt @nestjs/websockets to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.","status":"published","published":"2026-10-01T16:36:27Z","modified":"2026-10-15T09:48:04.398701349Z","updated_at":"2026-11-02T15:43:48.65893Z"},{"id":"CLSA-2026-1790881234","title":"TuxCare security update for @nestjs/websockets (2 CVEs)","description":"TuxCare rebuilt @nestjs/websockets to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.","status":"published","published":"2026-10-01T19:00:34Z","modified":"2026-10-15T09:48:04.125936776Z","updated_at":"2026-11-02T15:43:48.65893Z"},{"id":"CLSA-2026-1790882031","title":"TuxCare security update for @nestjs/websockets (1 CVE)","description":"TuxCare rebuilt @nestjs/websockets to address 1 CVE. Fixed in 11.2.4-tuxcare.1.","status":"published","published":"2026-10-01T19:13:51Z","modified":"2026-10-15T09:48:04.144352462Z","updated_at":"2026-11-02T15:43:48.65893Z"},{"id":"CLSA-2026-1792160938","title":"TuxCare security update for @nestjs/core (2 CVEs)","description":"TuxCare rebuilt @nestjs/core to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.","status":"published","published":"2026-10-16T14:28:54Z","modified":"2026-10-16T16:30:36.205410101Z","updated_at":"2026-11-02T15:43:50.949147Z"},{"id":"CLSA-2026-1792160959","title":"TuxCare security update for @nestjs/platform-socket.io (2 CVEs)","description":"TuxCare rebuilt @nestjs/platform-socket.io to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.","status":"published","published":"2026-10-16T14:29:15Z","modified":"2026-10-16T16:30:46.035891804Z","updated_at":"2026-11-02T15:43:50.949147Z"},{"id":"CLSA-2026-1792160964","title":"TuxCare security update for @nestjs/testing (1 CVE)","description":"TuxCare rebuilt @nestjs/testing to address 1 CVE. Fixed in 10.4.22-tuxcare.3.","status":"published","published":"2026-10-16T14:29:20Z","modified":"2026-10-16T16:30:46.047118391Z","updated_at":"2026-11-02T15:43:50.949147Z"},{"id":"CLSA-2026-1792161436","title":"TuxCare security update for @nestjs/common (1 CVE)","description":"TuxCare rebuilt @nestjs/common to address 1 CVE. Fixed in 10.4.22-tuxcare.3.","status":"published","published":"2026-10-16T14:37:16Z","modified":"2026-10-16T16:31:02.420333011Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161437","title":"TuxCare security update for @nestjs/common (2 CVEs)","description":"TuxCare rebuilt @nestjs/common to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.","status":"published","published":"2026-10-16T14:37:17Z","modified":"2026-10-16T16:31:02.418824382Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161438","title":"TuxCare security update for @nestjs/common (2 CVEs)","description":"TuxCare rebuilt @nestjs/common to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.","status":"published","published":"2026-10-16T14:37:18Z","modified":"2026-10-16T16:31:02.421766781Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161439","title":"TuxCare security update for @nestjs/common (1 CVE)","description":"TuxCare rebuilt @nestjs/common to address 1 CVE. Fixed in 11.2.4-tuxcare.1.","status":"published","published":"2026-10-16T14:37:19Z","modified":"2026-10-16T16:31:02.423769758Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161497","title":"TuxCare security update for @nestjs/core (1 CVE)","description":"TuxCare rebuilt @nestjs/core to address 1 CVE. Fixed in 10.4.22-tuxcare.3.","status":"published","published":"2026-10-16T14:38:16Z","modified":"2026-10-16T16:30:31.363762647Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161498","title":"TuxCare security update for @nestjs/core (2 CVEs)","description":"TuxCare rebuilt @nestjs/core to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.","status":"published","published":"2026-10-16T14:38:17Z","modified":"2026-10-16T16:30:31.970923811Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161499","title":"TuxCare security update for @nestjs/core (1 CVE)","description":"TuxCare rebuilt @nestjs/core to address 1 CVE. Fixed in 11.2.4-tuxcare.1.","status":"published","published":"2026-10-16T14:38:18Z","modified":"2026-10-16T16:30:09.026633183Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161676","title":"TuxCare security update for @nestjs/microservices (1 CVE)","description":"TuxCare rebuilt @nestjs/microservices to address 1 CVE. Fixed in 10.4.22-tuxcare.3.","status":"published","published":"2026-10-16T14:41:16Z","modified":"2026-10-16T16:31:07.773726855Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161677","title":"TuxCare security update for @nestjs/microservices (1 CVE)","description":"TuxCare rebuilt @nestjs/microservices to address 1 CVE. Fixed in 11.2.2-tuxcare.1.","status":"published","published":"2026-10-16T14:41:17Z","modified":"2026-11-10T19:58:27.252472391Z","updated_at":"2026-11-10T20:07:20.748062Z"},{"id":"CLSA-2026-1792161678","title":"TuxCare security update for @nestjs/microservices (1 CVE)","description":"TuxCare rebuilt @nestjs/microservices to address 1 CVE. Fixed in 11.2.3-tuxcare.1.","status":"published","published":"2026-10-16T14:41:18Z","modified":"2026-11-10T19:58:22.687992515Z","updated_at":"2026-11-10T20:07:25.465481Z"},{"id":"CLSA-2026-1792161679","title":"TuxCare security update for @nestjs/microservices (1 CVE)","description":"TuxCare rebuilt @nestjs/microservices to address 1 CVE. Fixed in 11.2.4-tuxcare.1.","status":"published","published":"2026-10-16T14:41:19Z","modified":"2026-10-16T16:31:07.070461023Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161753","title":"TuxCare security update for @nestjs/platform-express (1 CVE)","description":"TuxCare rebuilt @nestjs/platform-express to address 1 CVE. Fixed in 10.4.22-tuxcare.3.","status":"published","published":"2026-10-16T14:42:33Z","modified":"2026-10-16T16:31:29.128476492Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161754","title":"TuxCare security update for @nestjs/platform-express (2 CVEs)","description":"TuxCare rebuilt @nestjs/platform-express to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.","status":"published","published":"2026-10-16T14:42:34Z","modified":"2026-10-16T16:31:29.28765825Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161755","title":"TuxCare security update for @nestjs/platform-express (2 CVEs)","description":"TuxCare rebuilt @nestjs/platform-express to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.","status":"published","published":"2026-10-16T14:42:35Z","modified":"2026-10-16T16:31:29.134060118Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161756","title":"TuxCare security update for @nestjs/platform-express (1 CVE)","description":"TuxCare rebuilt @nestjs/platform-express to address 1 CVE. Fixed in 11.2.4-tuxcare.1.","status":"published","published":"2026-10-16T14:42:36Z","modified":"2026-10-16T16:31:29.928231975Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161842","title":"TuxCare security update for @nestjs/platform-fastify (1 CVE)","description":"TuxCare rebuilt @nestjs/platform-fastify to address 1 CVE. Fixed in 10.4.22-tuxcare.3.","status":"published","published":"2026-10-16T14:44:02Z","modified":"2026-10-16T16:31:10.987917275Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161843","title":"TuxCare security update for @nestjs/platform-fastify (1 CVE)","description":"TuxCare rebuilt @nestjs/platform-fastify to address 1 CVE. Fixed in 11.2.2-tuxcare.1.","status":"published","published":"2026-10-16T14:44:03Z","modified":"2026-11-10T19:45:13.641287402Z","updated_at":"2026-11-10T20:12:40.351566Z"},{"id":"CLSA-2026-1792161844","title":"TuxCare security update for @nestjs/platform-fastify (1 CVE)","description":"TuxCare rebuilt @nestjs/platform-fastify to address 1 CVE. Fixed in 11.2.3-tuxcare.1.","status":"published","published":"2026-10-16T14:44:04Z","modified":"2026-11-10T19:58:32.157720545Z","updated_at":"2026-11-10T20:07:15.512362Z"},{"id":"CLSA-2026-1792161845","title":"TuxCare security update for @nestjs/platform-fastify (1 CVE)","description":"TuxCare rebuilt @nestjs/platform-fastify to address 1 CVE. Fixed in 11.2.4-tuxcare.1.","status":"published","published":"2026-10-16T14:44:05Z","modified":"2026-10-16T16:31:15.162342602Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161910","title":"TuxCare security update for @nestjs/platform-socket.io (1 CVE)","description":"TuxCare rebuilt @nestjs/platform-socket.io to address 1 CVE. Fixed in 10.4.22-tuxcare.3.","status":"published","published":"2026-10-16T14:45:10Z","modified":"2026-10-16T16:30:53.135934019Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161911","title":"TuxCare security update for @nestjs/platform-socket.io (2 CVEs)","description":"TuxCare rebuilt @nestjs/platform-socket.io to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.","status":"published","published":"2026-10-16T14:45:11Z","modified":"2026-10-16T16:30:53.142434637Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161912","title":"TuxCare security update for @nestjs/platform-socket.io (1 CVE)","description":"TuxCare rebuilt @nestjs/platform-socket.io to address 1 CVE. Fixed in 11.2.4-tuxcare.1.","status":"published","published":"2026-10-16T14:45:12Z","modified":"2026-10-16T16:30:53.153463892Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161970","title":"TuxCare security update for @nestjs/platform-ws (1 CVE)","description":"TuxCare rebuilt @nestjs/platform-ws to address 1 CVE. Fixed in 10.4.22-tuxcare.3.","status":"published","published":"2026-10-16T14:46:10Z","modified":"2026-10-16T16:31:19.552938892Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161971","title":"TuxCare security update for @nestjs/platform-ws (2 CVEs)","description":"TuxCare rebuilt @nestjs/platform-ws to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.","status":"published","published":"2026-10-16T14:46:11Z","modified":"2026-10-16T16:31:19.251897005Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161972","title":"TuxCare security update for @nestjs/platform-ws (2 CVEs)","description":"TuxCare rebuilt @nestjs/platform-ws to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.","status":"published","published":"2026-10-16T14:46:12Z","modified":"2026-10-16T16:31:19.256164944Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792162005","title":"TuxCare security update for @nestjs/testing (2 CVEs)","description":"TuxCare rebuilt @nestjs/testing to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.","status":"published","published":"2026-10-16T14:46:45Z","modified":"2026-10-16T16:31:20.154844824Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792162006","title":"TuxCare security update for @nestjs/testing (2 CVEs)","description":"TuxCare rebuilt @nestjs/testing to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.","status":"published","published":"2026-10-16T14:46:46Z","modified":"2026-10-16T16:31:21.010324595Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792162007","title":"TuxCare security update for @nestjs/testing (1 CVE)","description":"TuxCare rebuilt @nestjs/testing to address 1 CVE. Fixed in 11.2.4-tuxcare.1.","status":"published","published":"2026-10-16T14:46:47Z","modified":"2026-10-16T16:31:20.662691123Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792265594","title":"TuxCare security update for @nestjs/websockets (2 CVEs)","description":"TuxCare rebuilt @nestjs/websockets to address 2 CVEs. Fixed in 10.4.22-tuxcare.4.","status":"published","published":"2026-10-17T19:33:14Z","modified":"2026-10-18T01:30:33.143010315Z","updated_at":"2026-11-02T15:43:52.288832Z"},{"id":"CLSA-2026-1792325070","title":"TuxCare security update for @nestjs/websockets (1 CVE)","description":"TuxCare rebuilt @nestjs/websockets to address 1 CVE. Fixed in 11.2.2-tuxcare.2.","status":"published","published":"2026-10-18T12:04:30Z","modified":"2026-10-18T13:15:39.69817889Z","updated_at":"2026-11-02T15:43:52.545698Z"},{"id":"CLSA-2026-1792325945","title":"TuxCare security update for @nestjs/websockets (1 CVE)","description":"TuxCare rebuilt @nestjs/websockets to address 1 CVE. Fixed in 11.2.3-tuxcare.2.","status":"published","published":"2026-10-18T12:19:01Z","modified":"2026-10-18T13:15:57.762374317Z","updated_at":"2026-11-02T15:43:52.545698Z"}]}}
