CVE-2026-102281
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.
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
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 High
CVSS: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 High
CVSS: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 Medium
CVSS: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:
- The bundled copy of the
@fastify/middieengine atpackages/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]. FastifyAdapter's own re-check increateMiddlewareFactory(), which tests the middleware path regexp againstreq.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/middiefork 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 High
CVSS: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
handleMessagein both transports are routed tohandleErrorrather 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 High
CVSS: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 High
CVSS: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 High
CVSS: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 Medium
CVSS: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:
- The bundled copy of the
@fastify/middieengine atpackages/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]. FastifyAdapter's own re-check increateMiddlewareFactory(), which tests the middleware path regexp againstreq.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/middiefork 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 High
CVSS: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
handleMessagein both transports are routed tohandleErrorrather 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 High
CVSS: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
| Package | Affected | Fixed |
|---|---|---|
@nestjs/microservicesnpm |
before 11.2.5 | 11.2.5 |
@nestjs/microservicesnpm |
12.0.0 up to 12.0.3 | 12.0.3 |
@nestjs/platform-fastifynpm |
before 11.2.4 | 11.2.4 |
@nestjs/platform-fastifynpm |
12.0.0 up to 12.0.2 | 12.0.2 |
@nestjs/microservicesnpm |
before 11.2.4 | 11.2.4 |
@nestjs/microservicesnpm |
12.0.0 up to 12.0.2 | 12.0.2 |
@nestjs/websocketsTuxCare: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/websocketsTuxCare: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/websocketsTuxCare: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/websocketsTuxCare: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
| Package | Affected | Fixed |
|---|---|---|
@nestjs/coreTuxCare: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.ioTuxCare: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/testingTuxCare: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/commonTuxCare: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/commonTuxCare: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/commonTuxCare: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/commonTuxCare: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/coreTuxCare: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/coreTuxCare: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/coreTuxCare: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/microservicesTuxCare: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/microservicesTuxCare: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/microservicesTuxCare: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/microservicesTuxCare: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-expressTuxCare: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-expressTuxCare: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-expressTuxCare: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-expressTuxCare: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-fastifyTuxCare: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-fastifyTuxCare: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-fastifyTuxCare: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-fastifyTuxCare: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.ioTuxCare: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.ioTuxCare: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.ioTuxCare: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-wsTuxCare: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-wsTuxCare: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-wsTuxCare: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/testingTuxCare: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/testingTuxCare: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/testingTuxCare: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/websocketsTuxCare: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/websocketsTuxCare: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/websocketsTuxCare: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
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE 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
github.com/nestjs/nest/security/advisories/GHSA-m8vh-jmq9-5rjg
github.com/nestjs/nest/pull/17737
github.com/nestjs/nest/commit/aa97b5144d8dff1ce700aac521eb86449a679d6f
github.com/nestjs/nest/commit/e9dcd4c7ac64361fbfe79461da85f5b3fc3e02da
github.com/nestjs/nest/releases/tag/v11.2.4
github.com/nestjs/nest/releases/tag/v12.0.2
Show 18 moreShow less
github.com/nestjs/nest/security/advisories/GHSA-96h4-vgxj-gvm2
github.com/nestjs/nest/pull/17746
github.com/nestjs/nest/pull/17749
github.com/nestjs/nest/commit/6ca2dd894a6ff964d318724f363061652e822920
github.com/nestjs/nest/commit/781843ac98d429fe1d541c52c7126850be5989a7
github.com/nestjs/nest/commit/dee4ed4dbc2e18e1e722619927647f5441dfe812
github.com/nestjs/nest/releases/tag/v11.2.5
github.com/nestjs/nest/releases/tag/v12.0.3
github.com/advisories/GHSA-96h4-vgxj-gvm2
github.com/fastify/middie/security/advisories/GHSA-hx87-8wv7-pjv8
github.com/nestjs/nest/security/advisories/GHSA-9c5c-9qcx-q35q
github.com/nestjs/nest/commit/5226fe084cf64b357de436f154bc89f2d319b621
github.com/nestjs/nest/commit/dda252090ecb65009d9ff366444303796fc44fd7
github.com/advisories/GHSA-9c5c-9qcx-q35q
nvd.nist.gov/vuln/detail/CVE-2026-102281
github.com/advisories/GHSA-m8vh-jmq9-5rjg
github.com/CVEProject/cvelistV5/tree/main/cves/2026/102xxx/CVE-2026-102281.json
github.com/nestjs/nest
Left out here: the rest of 4 source descriptions. The JSON record has them.