Every CVE Search/ Get API key

CVE-2026-102281

Nest: Remote process termination via a deeply nested microservice message pattern

7.5 HighFix available

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.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
High

Exploit likelihood

0.59%Up 0.2 points since Sep 29, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.5

Nest: Remote process termination via a deeply nested microservice message pattern

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.

Record
CVE-2026-102281
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-248, CWE-674
Updated
2026-11-02
EUVDEUVD-2026-88511 7.5

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.

Record
EUVD-2026-88511
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-96h4-vgxj-gvm2 6.5

Nest: Unbounded memory growth in the NestJS TCP microservice transport

Summary

A peer that can open a TCP connection to a NestJS microservice using the built-in TCP transport can make the server process allocate memory without limit, on either side of the connection, until the process is killed by the OS or by its container memory limit. No authentication, no credentials, and no valid message are required.

Applications are affected only if they start a microservice with Transport.TCP and the transport's port is reachable by an untrusted peer.

Affected versions

| Package | Affected | Patched | |---|---|---| | @nestjs/microservices | >= 12.0.0, < 12.0.3 | 12.0.3 | | @nestjs/microservices | < 11.2.5 | 11.2.5 |

The same code is present in the 10.x line and earlier. Those lines are end-of-life and will not receive a patch; upgrade to a supported major.

Only @nestjs/microservices is affected. No other package needs updating for this issue.

Details

Two independent paths let one peer grow the heap without bound.

Partial packets are buffered with nothing to reap them

The TCP transport frames messages as <length>#<payload>. A peer may declare a length, send part of the payload, and then stop. JsonSocket keeps the partial payload buffered while it waits for the rest, and nothing ever reclaimed it: there was no socket timeout, no cap on the number of connections, and no tracking of accepted sockets.

maxBufferSize did not close this. It caps a single connection, defaulting to 128M characters, and is enforced per connection, so the effective ceiling was the number of connections an attacker chose to open.

Ten connections that each send 20MB and then go silent:

| | rss | heapUsed | |---|---|---| | baseline | 152.3MB | 28.1MB | | after 200MB sent, all stalled | 561.2MB | 229.5MB |

The memory was held for as long as the connections stayed open. Closing them released it, so a peer could hold it indefinitely at negligible cost to itself.

Response backpressure was ignored

JsonSocket#handleSend discarded the return value of socket.write. A peer that issues requests and never reads the responses therefore made the process queue every response in memory, with no ceiling and no signal to stop producing more.

Thirty requests from a client whose stream is paused, against a handler returning an 8MB payload, grew rss from 152.4MB to 419.1MB. The amplification here is roughly 1:1, because the response size is set by the application rather than by the attacker; the defect is that the server buffers all of it rather than applying backpressure or giving up.

Impact

An unauthenticated peer that can reach the transport's port can drive the process to an out-of-memory kill. Under a container memory limit this is fast and repeatable, and it restarts the pod rather than merely degrading it.

There is no confidentiality or integrity impact. Nothing is read, written, or executed; the failure mode is availability only.

Applications are not affected if the TCP transport is not used, or if the transport's port is reachable only by trusted peers.

Patches

Upgrade @nestjs/microservices to 12.0.3 or 11.2.5.

Three changes landed together:

  • A stall timer drops a peer that stops sending mid-packet. It is armed only while a packet is partially received and is refreshed on every read, so a slow but progressing transfer is never interrupted and a peer sitting idle between packets is left alone. Configurable as incompleteMessageTimeout, default 30000ms.
  • Reading is suspended while a peer's outgoing buffer is backed up and resumes on drain, so a peer that stops reading cannot keep issuing requests.
  • Responses queued for a peer that reads nothing are capped. Suspending reads is not sufficient on its own, because message handlers are asynchronous: a burst of pipelined requests is dispatched before the first response is written, and those responses still queue. Configurable as maxSendBufferSize, default 128MB.

Both limits are…

Record
GHSA-96h4-vgxj-gvm2
CVSS 3.1
6.5 MediumCVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-770
Updated
2026-11-02
GitHub AdvisoriesGHSA-9c5c-9qcx-q35q 7.4

@nestjs/platform-fastify: Path-scoped middleware bypass via absolute-form request targets

| Field | Value | | --- | --- | | Ecosystem | npm | | Package | @nestjs/platform-fastify | | Affected versions | >= 12.0.0, < 12.0.2 and < 11.2.4 | | Patched versions | 12.0.2 and 11.2.4 (upgrade to 12.0.3 / 11.2.5) |

Summary

On the Fastify adapter, an HTTP request that uses an absolute-form request target (GET http://host/path HTTP/1.1 instead of GET /path HTTP/1.1) reaches the route handler without running the path-scoped Nest middleware bound to that route. Applications that enforce authentication or authorization in middleware execute the protected handler with those checks skipped.

Impact

Any application that

  • uses @nestjs/platform-fastify, and
  • binds middleware to specific paths via MiddlewareConsumer.forRoutes(...) or .exclude(...), and
  • is reachable by a client that controls the raw request line.

Node's HTTP server accepts absolute-form targets, so no special server configuration is needed. Exposure is reduced when a reverse proxy in front of the application rewrites the request target to origin-form, which most do.

Where the bypassed middleware performs authentication or authorization, the result is an authentication or authorization bypass. Where it performs logging, rate limiting or body handling, those are silently skipped instead.

Details

Fastify's router (find-my-way) resolves an absolute-form target to its path before matching, so the route handler is dispatched normally. Two places on the middleware side matched against the raw request target instead:

  1. The bundled copy of the @fastify/middie engine at packages/platform-fastify/adapters/middie/fastify-middie.ts. NestJS carried this fork to apply an earlier path-decoding fix and it did not track the upstream absolute-form fix released in @fastify/[email protected].
  2. FastifyAdapter's own re-check in createMiddlewareFactory(), which tests the middleware path regexp against req.originalUrl.

Both normalized and percent-decoded the target, but neither resolved absolute-form to a path, so the router and the middleware layer disagreed about which path was being requested.

A second, related defect contributed. Because the adapter always passes routerOptions (to install the version constraint), Fastify did not reflect the deprecated top-level router options (ignoreTrailingSlash, ignoreDuplicateSlashes, caseSensitive, useSemicolonDelimiter) in initialConfig.routerOptions, which is what the middleware engine reads. Applications passing those options at the top level had middleware normalize paths differently from the router, which widened the mismatch.

Proof of concept

@Controller('users')
export class UsersController {
  @Get()
  findAll() {
    return 'protected data';
  }
}

@Module({ controllers: [UsersController] })
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply((req, res) => res.end('blocked by auth middleware'))
      .forRoutes({ path: 'users', method: RequestMethod.GET });
  }
}

supertest and light-my-request always emit origin-form targets, so the request has to be written to the socket:

const { connect } = require('node:net');

const socket = connect(3000, '127.0.0.1', () => {
  socket.write(
    'GET http://127.0.0.1:3000/users HTTP/1.1\r\n' +
      'Host: 127.0.0.1:3000\r\n' +
      'Connection: close\r\n\r\n',
  );
});
socket.pipe(process.stdout);

Observed on an affected version: protected data — the middleware did not run. Expected, and observed on a patched version: blocked by auth middleware.

Patches

Fixed in 12.0.2 and 11.2.4. Upgrading to 12.0.3 or 11.2.5 is recommended.

  • The bundled @fastify/middie fork was removed and the package now depends on @fastify/[email protected], which resolves absolute-form targets before matching.
  • The adapter resolves absolute-form targets in its own route check, mirroring find-my-way. -…
Record
GHSA-9c5c-9qcx-q35q
CVSS 3.1
7.4 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-288, CWE-436
Updated
2026-11-02
GitHub AdvisoriesGHSA-m8vh-jmq9-5rjg 7.5

Nest: Remote process termination via a deeply nested microservice message pattern

| Field | Value | | --- | --- | | Ecosystem | npm | | Package | @nestjs/microservices | | Affected versions | >= 12.0.0, < 12.0.2 and < 11.2.4 | | Patched versions | 12.0.2 and 11.2.4 (upgrade to 12.0.3 / 11.2.5) |

Summary

A single message whose pattern is a deeply nested object terminates a NestJS microservice that uses the TCP or RabbitMQ transport. The server serialized the client-supplied pattern with JSON.stringify to derive the handler lookup key; on deeply nested input this throws RangeError: Maximum call stack size exceeded. The exception escaped the asynchronous message handler as an unhandled promise rejection, which terminates the Node.js process under the default --unhandled-rejections=throw.

Impact

Denial of service, one message per crash, repeatable. The attacker needs to be able to reach the transport: connect to the TCP transport's port, or publish to the queue or exchange the service consumes from. The TCP transport performs no authentication by default, so on a reachable port this requires nothing else.

Only the TCP and RabbitMQ transports are affected. The other transports take the pattern as a string from the broker topic or channel and never serialize a client-supplied object to build it.

Details

In ServerTCP#handleMessage and ServerRMQ#handleMessage the pattern was stringified without a guard:

const pattern = isString(packet.pattern)
  ? packet.pattern
  : JSON.stringify(packet.pattern);

JSON.parse accepts nesting depths that JSON.stringify cannot re-serialize, because JSON.stringify recurses natively, so an attacker can craft a payload that parses successfully on arrival and then throws when the pattern is converted back to a string. Neither transport attached a rejection handler to the promise returned by handleMessage, so the RangeError propagated out as an unhandled rejection.

Proof of concept

Against a NestJS microservice on the TCP transport (default port 3001). The nested JSON is built as text rather than with JSON.stringify, which is what makes the payload serializable by the attacker but not by the victim:

const { connect } = require('node:net');

const DEPTH = 100_000;
const pattern = '{"nested":'.repeat(DEPTH) + '{}' + '}'.repeat(DEPTH);
const payload = `{"pattern":${pattern},"data":null,"id":"1"}`;

const socket = connect(3001, '127.0.0.1', () => {
  // Nest's TCP framing is <byteLength>#<json>
  socket.write(`${Buffer.byteLength(payload)}#${payload}`);
});

The service exits with RangeError: Maximum call stack size exceeded. The equivalent payload published to the consumed queue crashes a RabbitMQ-transport service.

Patches

Fixed in 12.0.2 and 11.2.4.

  • Incoming patterns are converted through a guarded Server#getPatternAsString, which falls back to a sentinel value that matches no handler. Such a message now receives the ordinary "no message handler" response (TCP) or is negatively acknowledged (RabbitMQ) instead of crashing the process.
  • Rejections escaping handleMessage in both transports are routed to handleError rather than left unhandled.

Workarounds

If you cannot upgrade, restrict network access to the transport so that only trusted peers can reach it. Running the process with --unhandled-rejections=warn prevents the crash but leaves the message unprocessed and is not a substitute for the fix.

Credit

Reported by ZeroVuln Labs.

Record
GHSA-m8vh-jmq9-5rjg
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-248, CWE-674
Updated
2026-11-02
NVD 7.5

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.

Record
CVE-2026-102281
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-248, CWE-674
Updated
2026-11-02
Show 42 moreShow less
OSV 7.5

Nest: Remote process termination via a deeply nested microservice message pattern

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.

Record
CVE-2026-102281
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-248, CWE-674
Updated
2026-11-02
OSVGHSA-96h4-vgxj-gvm2 6.5

Nest: Unbounded memory growth in the NestJS TCP microservice transport

Summary

A peer that can open a TCP connection to a NestJS microservice using the built-in TCP transport can make the server process allocate memory without limit, on either side of the connection, until the process is killed by the OS or by its container memory limit. No authentication, no credentials, and no valid message are required.

Applications are affected only if they start a microservice with Transport.TCP and the transport's port is reachable by an untrusted peer.

Affected versions

| Package | Affected | Patched | |---|---|---| | @nestjs/microservices | >= 12.0.0, < 12.0.3 | 12.0.3 | | @nestjs/microservices | < 11.2.5 | 11.2.5 |

The same code is present in the 10.x line and earlier. Those lines are end-of-life and will not receive a patch; upgrade to a supported major.

Only @nestjs/microservices is affected. No other package needs updating for this issue.

Details

Two independent paths let one peer grow the heap without bound.

Partial packets are buffered with nothing to reap them

The TCP transport frames messages as <length>#<payload>. A peer may declare a length, send part of the payload, and then stop. JsonSocket keeps the partial payload buffered while it waits for the rest, and nothing ever reclaimed it: there was no socket timeout, no cap on the number of connections, and no tracking of accepted sockets.

maxBufferSize did not close this. It caps a single connection, defaulting to 128M characters, and is enforced per connection, so the effective ceiling was the number of connections an attacker chose to open.

Ten connections that each send 20MB and then go silent:

| | rss | heapUsed | |---|---|---| | baseline | 152.3MB | 28.1MB | | after 200MB sent, all stalled | 561.2MB | 229.5MB |

The memory was held for as long as the connections stayed open. Closing them released it, so a peer could hold it indefinitely at negligible cost to itself.

Response backpressure was ignored

JsonSocket#handleSend discarded the return value of socket.write. A peer that issues requests and never reads the responses therefore made the process queue every response in memory, with no ceiling and no signal to stop producing more.

Thirty requests from a client whose stream is paused, against a handler returning an 8MB payload, grew rss from 152.4MB to 419.1MB. The amplification here is roughly 1:1, because the response size is set by the application rather than by the attacker; the defect is that the server buffers all of it rather than applying backpressure or giving up.

Impact

An unauthenticated peer that can reach the transport's port can drive the process to an out-of-memory kill. Under a container memory limit this is fast and repeatable, and it restarts the pod rather than merely degrading it.

There is no confidentiality or integrity impact. Nothing is read, written, or executed; the failure mode is availability only.

Applications are not affected if the TCP transport is not used, or if the transport's port is reachable only by trusted peers.

Patches

Upgrade @nestjs/microservices to 12.0.3 or 11.2.5.

Three changes landed together:

  • A stall timer drops a peer that stops sending mid-packet. It is armed only while a packet is partially received and is refreshed on every read, so a slow but progressing transfer is never interrupted and a peer sitting idle between packets is left alone. Configurable as incompleteMessageTimeout, default 30000ms.
  • Reading is suspended while a peer's outgoing buffer is backed up and resumes on drain, so a peer that stops reading cannot keep issuing requests.
  • Responses queued for a peer that reads nothing are capped. Suspending reads is not sufficient on its own, because message handlers are asynchronous: a burst of pipelined requests is dispatched before the first response is written, and those responses still queue. Configurable as maxSendBufferSize, default 128MB.

Both limits are…

Record
GHSA-96h4-vgxj-gvm2
CVSS 3.1
6.5 MediumCVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-770
Updated
2026-11-02
OSVGHSA-9c5c-9qcx-q35q 7.4

@nestjs/platform-fastify: Path-scoped middleware bypass via absolute-form request targets

| Field | Value | | --- | --- | | Ecosystem | npm | | Package | @nestjs/platform-fastify | | Affected versions | >= 12.0.0, < 12.0.2 and < 11.2.4 | | Patched versions | 12.0.2 and 11.2.4 (upgrade to 12.0.3 / 11.2.5) |

Summary

On the Fastify adapter, an HTTP request that uses an absolute-form request target (GET http://host/path HTTP/1.1 instead of GET /path HTTP/1.1) reaches the route handler without running the path-scoped Nest middleware bound to that route. Applications that enforce authentication or authorization in middleware execute the protected handler with those checks skipped.

Impact

Any application that

  • uses @nestjs/platform-fastify, and
  • binds middleware to specific paths via MiddlewareConsumer.forRoutes(...) or .exclude(...), and
  • is reachable by a client that controls the raw request line.

Node's HTTP server accepts absolute-form targets, so no special server configuration is needed. Exposure is reduced when a reverse proxy in front of the application rewrites the request target to origin-form, which most do.

Where the bypassed middleware performs authentication or authorization, the result is an authentication or authorization bypass. Where it performs logging, rate limiting or body handling, those are silently skipped instead.

Details

Fastify's router (find-my-way) resolves an absolute-form target to its path before matching, so the route handler is dispatched normally. Two places on the middleware side matched against the raw request target instead:

  1. The bundled copy of the @fastify/middie engine at packages/platform-fastify/adapters/middie/fastify-middie.ts. NestJS carried this fork to apply an earlier path-decoding fix and it did not track the upstream absolute-form fix released in @fastify/[email protected].
  2. FastifyAdapter's own re-check in createMiddlewareFactory(), which tests the middleware path regexp against req.originalUrl.

Both normalized and percent-decoded the target, but neither resolved absolute-form to a path, so the router and the middleware layer disagreed about which path was being requested.

A second, related defect contributed. Because the adapter always passes routerOptions (to install the version constraint), Fastify did not reflect the deprecated top-level router options (ignoreTrailingSlash, ignoreDuplicateSlashes, caseSensitive, useSemicolonDelimiter) in initialConfig.routerOptions, which is what the middleware engine reads. Applications passing those options at the top level had middleware normalize paths differently from the router, which widened the mismatch.

Proof of concept

@Controller('users')
export class UsersController {
  @Get()
  findAll() {
    return 'protected data';
  }
}

@Module({ controllers: [UsersController] })
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply((req, res) => res.end('blocked by auth middleware'))
      .forRoutes({ path: 'users', method: RequestMethod.GET });
  }
}

supertest and light-my-request always emit origin-form targets, so the request has to be written to the socket:

const { connect } = require('node:net');

const socket = connect(3000, '127.0.0.1', () => {
  socket.write(
    'GET http://127.0.0.1:3000/users HTTP/1.1\r\n' +
      'Host: 127.0.0.1:3000\r\n' +
      'Connection: close\r\n\r\n',
  );
});
socket.pipe(process.stdout);

Observed on an affected version: protected data — the middleware did not run. Expected, and observed on a patched version: blocked by auth middleware.

Patches

Fixed in 12.0.2 and 11.2.4. Upgrading to 12.0.3 or 11.2.5 is recommended.

  • The bundled @fastify/middie fork was removed and the package now depends on @fastify/[email protected], which resolves absolute-form targets before matching.
  • The adapter resolves absolute-form targets in its own route check, mirroring find-my-way. -…
Record
GHSA-9c5c-9qcx-q35q
CVSS 3.1
7.4 HighCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-288, CWE-436
Updated
2026-11-02
OSVGHSA-m8vh-jmq9-5rjg 7.5

Nest: Remote process termination via a deeply nested microservice message pattern

| Field | Value | | --- | --- | | Ecosystem | npm | | Package | @nestjs/microservices | | Affected versions | >= 12.0.0, < 12.0.2 and < 11.2.4 | | Patched versions | 12.0.2 and 11.2.4 (upgrade to 12.0.3 / 11.2.5) |

Summary

A single message whose pattern is a deeply nested object terminates a NestJS microservice that uses the TCP or RabbitMQ transport. The server serialized the client-supplied pattern with JSON.stringify to derive the handler lookup key; on deeply nested input this throws RangeError: Maximum call stack size exceeded. The exception escaped the asynchronous message handler as an unhandled promise rejection, which terminates the Node.js process under the default --unhandled-rejections=throw.

Impact

Denial of service, one message per crash, repeatable. The attacker needs to be able to reach the transport: connect to the TCP transport's port, or publish to the queue or exchange the service consumes from. The TCP transport performs no authentication by default, so on a reachable port this requires nothing else.

Only the TCP and RabbitMQ transports are affected. The other transports take the pattern as a string from the broker topic or channel and never serialize a client-supplied object to build it.

Details

In ServerTCP#handleMessage and ServerRMQ#handleMessage the pattern was stringified without a guard:

const pattern = isString(packet.pattern)
  ? packet.pattern
  : JSON.stringify(packet.pattern);

JSON.parse accepts nesting depths that JSON.stringify cannot re-serialize, because JSON.stringify recurses natively, so an attacker can craft a payload that parses successfully on arrival and then throws when the pattern is converted back to a string. Neither transport attached a rejection handler to the promise returned by handleMessage, so the RangeError propagated out as an unhandled rejection.

Proof of concept

Against a NestJS microservice on the TCP transport (default port 3001). The nested JSON is built as text rather than with JSON.stringify, which is what makes the payload serializable by the attacker but not by the victim:

const { connect } = require('node:net');

const DEPTH = 100_000;
const pattern = '{"nested":'.repeat(DEPTH) + '{}' + '}'.repeat(DEPTH);
const payload = `{"pattern":${pattern},"data":null,"id":"1"}`;

const socket = connect(3001, '127.0.0.1', () => {
  // Nest's TCP framing is <byteLength>#<json>
  socket.write(`${Buffer.byteLength(payload)}#${payload}`);
});

The service exits with RangeError: Maximum call stack size exceeded. The equivalent payload published to the consumed queue crashes a RabbitMQ-transport service.

Patches

Fixed in 12.0.2 and 11.2.4.

  • Incoming patterns are converted through a guarded Server#getPatternAsString, which falls back to a sentinel value that matches no handler. Such a message now receives the ordinary "no message handler" response (TCP) or is negatively acknowledged (RabbitMQ) instead of crashing the process.
  • Rejections escaping handleMessage in both transports are routed to handleError rather than left unhandled.

Workarounds

If you cannot upgrade, restrict network access to the transport so that only trusted peers can reach it. Running the process with --unhandled-rejections=warn prevents the crash but leaves the message unprocessed and is not a substitute for the fix.

Credit

Reported by ZeroVuln Labs.

Record
GHSA-m8vh-jmq9-5rjg
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-248, CWE-674
Updated
2026-11-02
OSVCLSA-2026-1790870019 No score

TuxCare security update for @nestjs/websockets (1 CVE)

TuxCare rebuilt @nestjs/websockets to address 1 CVE. Fixed in 10.4.22-tuxcare.3.

Record
CLSA-2026-1790870019
Updated
2026-11-02
OSVCLSA-2026-1790872587 No score

TuxCare security update for @nestjs/websockets (2 CVEs)

TuxCare rebuilt @nestjs/websockets to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.

Record
CLSA-2026-1790872587
Updated
2026-11-02
OSVCLSA-2026-1790881234 No score

TuxCare security update for @nestjs/websockets (2 CVEs)

TuxCare rebuilt @nestjs/websockets to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.

Record
CLSA-2026-1790881234
Updated
2026-11-02
OSVCLSA-2026-1790882031 No score

TuxCare security update for @nestjs/websockets (1 CVE)

TuxCare rebuilt @nestjs/websockets to address 1 CVE. Fixed in 11.2.4-tuxcare.1.

Record
CLSA-2026-1790882031
Updated
2026-11-02
OSVCLSA-2026-1792160938 No score

TuxCare security update for @nestjs/core (2 CVEs)

TuxCare rebuilt @nestjs/core to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.

Record
CLSA-2026-1792160938
Updated
2026-11-02
OSVCLSA-2026-1792160959 No score

TuxCare security update for @nestjs/platform-socket.io (2 CVEs)

TuxCare rebuilt @nestjs/platform-socket.io to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.

Record
CLSA-2026-1792160959
Updated
2026-11-02
OSVCLSA-2026-1792160964 No score

TuxCare security update for @nestjs/testing (1 CVE)

TuxCare rebuilt @nestjs/testing to address 1 CVE. Fixed in 10.4.22-tuxcare.3.

Record
CLSA-2026-1792160964
Updated
2026-11-02
OSVCLSA-2026-1792161436 No score

TuxCare security update for @nestjs/common (1 CVE)

TuxCare rebuilt @nestjs/common to address 1 CVE. Fixed in 10.4.22-tuxcare.3.

Record
CLSA-2026-1792161436
Updated
2026-11-02
OSVCLSA-2026-1792161437 No score

TuxCare security update for @nestjs/common (2 CVEs)

TuxCare rebuilt @nestjs/common to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.

Record
CLSA-2026-1792161437
Updated
2026-11-02
OSVCLSA-2026-1792161438 No score

TuxCare security update for @nestjs/common (2 CVEs)

TuxCare rebuilt @nestjs/common to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.

Record
CLSA-2026-1792161438
Updated
2026-11-02
OSVCLSA-2026-1792161439 No score

TuxCare security update for @nestjs/common (1 CVE)

TuxCare rebuilt @nestjs/common to address 1 CVE. Fixed in 11.2.4-tuxcare.1.

Record
CLSA-2026-1792161439
Updated
2026-11-02
OSVCLSA-2026-1792161497 No score

TuxCare security update for @nestjs/core (1 CVE)

TuxCare rebuilt @nestjs/core to address 1 CVE. Fixed in 10.4.22-tuxcare.3.

Record
CLSA-2026-1792161497
Updated
2026-11-02
OSVCLSA-2026-1792161498 No score

TuxCare security update for @nestjs/core (2 CVEs)

TuxCare rebuilt @nestjs/core to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.

Record
CLSA-2026-1792161498
Updated
2026-11-02
OSVCLSA-2026-1792161499 No score

TuxCare security update for @nestjs/core (1 CVE)

TuxCare rebuilt @nestjs/core to address 1 CVE. Fixed in 11.2.4-tuxcare.1.

Record
CLSA-2026-1792161499
Updated
2026-11-02
OSVCLSA-2026-1792161676 No score

TuxCare security update for @nestjs/microservices (1 CVE)

TuxCare rebuilt @nestjs/microservices to address 1 CVE. Fixed in 10.4.22-tuxcare.3.

Record
CLSA-2026-1792161676
Updated
2026-11-02
OSVCLSA-2026-1792161677 No score

TuxCare security update for @nestjs/microservices (2 CVEs)

TuxCare rebuilt @nestjs/microservices to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.

Record
CLSA-2026-1792161677
Updated
2026-11-02
OSVCLSA-2026-1792161678 No score

TuxCare security update for @nestjs/microservices (2 CVEs)

TuxCare rebuilt @nestjs/microservices to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.

Record
CLSA-2026-1792161678
Updated
2026-11-02
OSVCLSA-2026-1792161679 No score

TuxCare security update for @nestjs/microservices (1 CVE)

TuxCare rebuilt @nestjs/microservices to address 1 CVE. Fixed in 11.2.4-tuxcare.1.

Record
CLSA-2026-1792161679
Updated
2026-11-02
OSVCLSA-2026-1792161753 No score

TuxCare security update for @nestjs/platform-express (1 CVE)

TuxCare rebuilt @nestjs/platform-express to address 1 CVE. Fixed in 10.4.22-tuxcare.3.

Record
CLSA-2026-1792161753
Updated
2026-11-02
OSVCLSA-2026-1792161754 No score

TuxCare security update for @nestjs/platform-express (2 CVEs)

TuxCare rebuilt @nestjs/platform-express to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.

Record
CLSA-2026-1792161754
Updated
2026-11-02
OSVCLSA-2026-1792161755 No score

TuxCare security update for @nestjs/platform-express (2 CVEs)

TuxCare rebuilt @nestjs/platform-express to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.

Record
CLSA-2026-1792161755
Updated
2026-11-02
OSVCLSA-2026-1792161756 No score

TuxCare security update for @nestjs/platform-express (1 CVE)

TuxCare rebuilt @nestjs/platform-express to address 1 CVE. Fixed in 11.2.4-tuxcare.1.

Record
CLSA-2026-1792161756
Updated
2026-11-02
OSVCLSA-2026-1792161842 No score

TuxCare security update for @nestjs/platform-fastify (1 CVE)

TuxCare rebuilt @nestjs/platform-fastify to address 1 CVE. Fixed in 10.4.22-tuxcare.3.

Record
CLSA-2026-1792161842
Updated
2026-11-02
OSVCLSA-2026-1792161843 No score

TuxCare security update for @nestjs/platform-fastify (2 CVEs)

TuxCare rebuilt @nestjs/platform-fastify to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.

Record
CLSA-2026-1792161843
Updated
2026-11-02
OSVCLSA-2026-1792161844 No score

TuxCare security update for @nestjs/platform-fastify (2 CVEs)

TuxCare rebuilt @nestjs/platform-fastify to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.

Record
CLSA-2026-1792161844
Updated
2026-11-02
OSVCLSA-2026-1792161845 No score

TuxCare security update for @nestjs/platform-fastify (1 CVE)

TuxCare rebuilt @nestjs/platform-fastify to address 1 CVE. Fixed in 11.2.4-tuxcare.1.

Record
CLSA-2026-1792161845
Updated
2026-11-02
OSVCLSA-2026-1792161910 No score

TuxCare security update for @nestjs/platform-socket.io (1 CVE)

TuxCare rebuilt @nestjs/platform-socket.io to address 1 CVE. Fixed in 10.4.22-tuxcare.3.

Record
CLSA-2026-1792161910
Updated
2026-11-02
OSVCLSA-2026-1792161911 No score

TuxCare security update for @nestjs/platform-socket.io (2 CVEs)

TuxCare rebuilt @nestjs/platform-socket.io to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.

Record
CLSA-2026-1792161911
Updated
2026-11-02
OSVCLSA-2026-1792161912 No score

TuxCare security update for @nestjs/platform-socket.io (1 CVE)

TuxCare rebuilt @nestjs/platform-socket.io to address 1 CVE. Fixed in 11.2.4-tuxcare.1.

Record
CLSA-2026-1792161912
Updated
2026-11-02
OSVCLSA-2026-1792161970 No score

TuxCare security update for @nestjs/platform-ws (1 CVE)

TuxCare rebuilt @nestjs/platform-ws to address 1 CVE. Fixed in 10.4.22-tuxcare.3.

Record
CLSA-2026-1792161970
Updated
2026-11-02
OSVCLSA-2026-1792161971 No score

TuxCare security update for @nestjs/platform-ws (2 CVEs)

TuxCare rebuilt @nestjs/platform-ws to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.

Record
CLSA-2026-1792161971
Updated
2026-11-02
OSVCLSA-2026-1792161972 No score

TuxCare security update for @nestjs/platform-ws (2 CVEs)

TuxCare rebuilt @nestjs/platform-ws to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.

Record
CLSA-2026-1792161972
Updated
2026-11-02
OSVCLSA-2026-1792162005 No score

TuxCare security update for @nestjs/testing (2 CVEs)

TuxCare rebuilt @nestjs/testing to address 2 CVEs. Fixed in 11.2.2-tuxcare.1.

Record
CLSA-2026-1792162005
Updated
2026-11-02
OSVCLSA-2026-1792162006 No score

TuxCare security update for @nestjs/testing (2 CVEs)

TuxCare rebuilt @nestjs/testing to address 2 CVEs. Fixed in 11.2.3-tuxcare.1.

Record
CLSA-2026-1792162006
Updated
2026-11-02
OSVCLSA-2026-1792162007 No score

TuxCare security update for @nestjs/testing (1 CVE)

TuxCare rebuilt @nestjs/testing to address 1 CVE. Fixed in 11.2.4-tuxcare.1.

Record
CLSA-2026-1792162007
Updated
2026-11-02
OSVCLSA-2026-1792265594 No score

TuxCare security update for @nestjs/websockets (2 CVEs)

TuxCare rebuilt @nestjs/websockets to address 2 CVEs. Fixed in 10.4.22-tuxcare.4.

Record
CLSA-2026-1792265594
Updated
2026-11-02
OSVCLSA-2026-1792325070 No score

TuxCare security update for @nestjs/websockets (1 CVE)

TuxCare rebuilt @nestjs/websockets to address 1 CVE. Fixed in 11.2.2-tuxcare.2.

Record
CLSA-2026-1792325070
Updated
2026-11-02
OSVCLSA-2026-1792325945 No score

TuxCare security update for @nestjs/websockets (1 CVE)

TuxCare rebuilt @nestjs/websockets to address 1 CVE. Fixed in 11.2.3-tuxcare.2.

Record
CLSA-2026-1792325945
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
@nestjs/microservices
npm
before 11.2.5
11.2.5
@nestjs/microservices
npm
12.0.0 up to 12.0.3
12.0.3
@nestjs/platform-fastify
npm
before 11.2.4
11.2.4
@nestjs/platform-fastify
npm
12.0.0 up to 12.0.2
12.0.2
@nestjs/microservices
npm
before 11.2.4
11.2.4
@nestjs/microservices
npm
12.0.0 up to 12.0.2
12.0.2
@nestjs/websockets
TuxCare:npm
10.4.22-tuxcare.0 up to 10.4.22-tuxcare.3, plus listed versions
10.4.2210.4.22-tuxcare.110.4.22-tuxcare.2
10.4.22-tuxcare.3
@nestjs/websockets
TuxCare:npm
11.2.2-tuxcare.0 up to 11.2.2-tuxcare.1, plus listed versions
11.2.2
11.2.2-tuxcare.1
@nestjs/websockets
TuxCare:npm
11.2.3-tuxcare.0 up to 11.2.3-tuxcare.1, plus listed versions
11.2.3
11.2.3-tuxcare.1
@nestjs/websockets
TuxCare:npm
11.2.4-tuxcare.0 up to 11.2.4-tuxcare.1, plus listed versions
11.2.4
11.2.4-tuxcare.1
Show 34 moreShow less
Affected packages
PackageAffectedFixed
@nestjs/core
TuxCare:npm
11.2.2-tuxcare.0 up to 11.2.2-tuxcare.1, plus listed versions
11.2.2
11.2.2-tuxcare.1
@nestjs/platform-socket.io
TuxCare:npm
11.2.3-tuxcare.0 up to 11.2.3-tuxcare.1, plus listed versions
11.2.3
11.2.3-tuxcare.1
@nestjs/testing
TuxCare:npm
10.4.22-tuxcare.0 up to 10.4.22-tuxcare.3, plus listed versions
10.4.2210.4.22-tuxcare.110.4.22-tuxcare.2
10.4.22-tuxcare.3
@nestjs/common
TuxCare:npm
10.4.22-tuxcare.0 up to 10.4.22-tuxcare.3, plus listed versions
10.4.2210.4.22-tuxcare.110.4.22-tuxcare.2
10.4.22-tuxcare.3
@nestjs/common
TuxCare:npm
11.2.2-tuxcare.0 up to 11.2.2-tuxcare.1, plus listed versions
11.2.2
11.2.2-tuxcare.1
@nestjs/common
TuxCare:npm
11.2.3-tuxcare.0 up to 11.2.3-tuxcare.1, plus listed versions
11.2.3
11.2.3-tuxcare.1
@nestjs/common
TuxCare:npm
11.2.4-tuxcare.0 up to 11.2.4-tuxcare.1, plus listed versions
11.2.4
11.2.4-tuxcare.1
@nestjs/core
TuxCare:npm
10.4.22-tuxcare.0 up to 10.4.22-tuxcare.3, plus listed versions
10.4.2210.4.22-tuxcare.110.4.22-tuxcare.2
10.4.22-tuxcare.3
@nestjs/core
TuxCare:npm
11.2.3-tuxcare.0 up to 11.2.3-tuxcare.1, plus listed versions
11.2.3
11.2.3-tuxcare.1
@nestjs/core
TuxCare:npm
11.2.4-tuxcare.0 up to 11.2.4-tuxcare.1, plus listed versions
11.2.4
11.2.4-tuxcare.1
@nestjs/microservices
TuxCare:npm
10.4.22-tuxcare.0 up to 10.4.22-tuxcare.3, plus listed versions
10.4.2210.4.22-tuxcare.110.4.22-tuxcare.2
10.4.22-tuxcare.3
@nestjs/microservices
TuxCare:npm
11.2.2-tuxcare.0 up to 11.2.2-tuxcare.1, plus listed versions
11.2.2
11.2.2-tuxcare.1
@nestjs/microservices
TuxCare:npm
11.2.3-tuxcare.0 up to 11.2.3-tuxcare.1, plus listed versions
11.2.3
11.2.3-tuxcare.1
@nestjs/microservices
TuxCare:npm
11.2.4-tuxcare.0 up to 11.2.4-tuxcare.1, plus listed versions
11.2.4
11.2.4-tuxcare.1
@nestjs/platform-express
TuxCare:npm
10.4.22-tuxcare.0 up to 10.4.22-tuxcare.3, plus listed versions
10.4.2210.4.22-tuxcare.110.4.22-tuxcare.2
10.4.22-tuxcare.3
@nestjs/platform-express
TuxCare:npm
11.2.2-tuxcare.0 up to 11.2.2-tuxcare.1, plus listed versions
11.2.2
11.2.2-tuxcare.1
@nestjs/platform-express
TuxCare:npm
11.2.3-tuxcare.0 up to 11.2.3-tuxcare.1, plus listed versions
11.2.3
11.2.3-tuxcare.1
@nestjs/platform-express
TuxCare:npm
11.2.4-tuxcare.0 up to 11.2.4-tuxcare.1, plus listed versions
11.2.4
11.2.4-tuxcare.1
@nestjs/platform-fastify
TuxCare:npm
10.4.22-tuxcare.0 up to 10.4.22-tuxcare.3, plus listed versions
10.4.2210.4.22-tuxcare.110.4.22-tuxcare.2
10.4.22-tuxcare.3
@nestjs/platform-fastify
TuxCare:npm
11.2.2-tuxcare.0 up to 11.2.2-tuxcare.1, plus listed versions
11.2.2
11.2.2-tuxcare.1
@nestjs/platform-fastify
TuxCare:npm
11.2.3-tuxcare.0 up to 11.2.3-tuxcare.1, plus listed versions
11.2.3
11.2.3-tuxcare.1
@nestjs/platform-fastify
TuxCare:npm
11.2.4-tuxcare.0 up to 11.2.4-tuxcare.1, plus listed versions
11.2.4
11.2.4-tuxcare.1
@nestjs/platform-socket.io
TuxCare:npm
10.4.22-tuxcare.0 up to 10.4.22-tuxcare.3, plus listed versions
10.4.2210.4.22-tuxcare.110.4.22-tuxcare.2
10.4.22-tuxcare.3
@nestjs/platform-socket.io
TuxCare:npm
11.2.2-tuxcare.0 up to 11.2.2-tuxcare.1, plus listed versions
11.2.2
11.2.2-tuxcare.1
@nestjs/platform-socket.io
TuxCare:npm
11.2.4-tuxcare.0 up to 11.2.4-tuxcare.1, plus listed versions
11.2.4
11.2.4-tuxcare.1
@nestjs/platform-ws
TuxCare:npm
10.4.22-tuxcare.0 up to 10.4.22-tuxcare.3, plus listed versions
10.4.2210.4.22-tuxcare.110.4.22-tuxcare.2
10.4.22-tuxcare.3
@nestjs/platform-ws
TuxCare:npm
11.2.2-tuxcare.0 up to 11.2.2-tuxcare.1, plus listed versions
11.2.2
11.2.2-tuxcare.1
@nestjs/platform-ws
TuxCare:npm
11.2.3-tuxcare.0 up to 11.2.3-tuxcare.1, plus listed versions
11.2.3
11.2.3-tuxcare.1
@nestjs/testing
TuxCare:npm
11.2.2-tuxcare.0 up to 11.2.2-tuxcare.1, plus listed versions
11.2.2
11.2.2-tuxcare.1
@nestjs/testing
TuxCare:npm
11.2.3-tuxcare.0 up to 11.2.3-tuxcare.1, plus listed versions
11.2.3
11.2.3-tuxcare.1
@nestjs/testing
TuxCare:npm
11.2.4-tuxcare.0 up to 11.2.4-tuxcare.1, plus listed versions
11.2.4
11.2.4-tuxcare.1
@nestjs/websockets
TuxCare:npm
10.4.22-tuxcare.0 up to 10.4.22-tuxcare.4, plus listed versions
10.4.2210.4.22-tuxcare.110.4.22-tuxcare.210.4.22-tuxcare.3
10.4.22-tuxcare.4
@nestjs/websockets
TuxCare:npm
11.2.2-tuxcare.0 up to 11.2.2-tuxcare.2, plus listed versions
11.2.211.2.2-tuxcare.1
11.2.2-tuxcare.2
@nestjs/websockets
TuxCare:npm
11.2.3-tuxcare.0 up to 11.2.3-tuxcare.2, plus listed versions
11.2.311.2.3-tuxcare.1
11.2.3-tuxcare.2

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-102281 is a high vulnerability (CVSS 7.5) in Nestjs Nest, published September 28, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.59%, the 48th percentile. Fixed in @nestjs/microservices 11.2.5.

References

Show 18 moreShow less
This page doesn't list everything

Left out here: the rest of 4 source descriptions. The JSON record has them.

MoveEnter Open