Back to Blog
high SEVERITY9 min read

How Denial of Service via Memory Exhaustion happens in Node.js Socket.IO and how to fix it

CVE-2026-69185 is a high-severity Denial of Service vulnerability in `socket.io-parser` where crafted malicious packets can exhaust server memory, crashing real-time Node.js applications. The fix upgrades `socket.io-parser` from version 4.2.6 to 4.2.7 and pins the dependency via an `overrides` field in `package.json` to ensure the patched version is used throughout the dependency tree. Any application using Socket.IO for bidirectional real-time communication is potentially at risk until this upg

O
By Orbis AppSec
Published August 26, 2026Reviewed August 26, 2026

Answer Summary

CVE-2026-69185 is a Denial of Service (DoS) vulnerability in the `socket.io-parser` npm package (Node.js), classified under CWE-400 (Uncontrolled Resource Consumption). An attacker can send specially crafted Socket.IO packets that cause the parser to allocate unbounded memory, exhausting server resources and crashing the application. The fix is to upgrade `socket.io-parser` to version 4.2.7 (or 3.4.5 / 3.3.6 for older branches) and pin the version using the `overrides` field in `package.json` to prevent transitive dependency resolution from pulling in the vulnerable version.

Vulnerability at a Glance

cweCWE-400
fixUpgrade socket.io-parser to 4.2.7 and pin the version with package.json overrides
riskUnauthenticated attackers can crash the server by sending crafted Socket.IO packets
languageJavaScript / Node.js
root causesocket.io-parser 4.2.6 does not enforce limits on memory allocation when parsing incoming packet data
vulnerabilityDenial of Service via Memory Exhaustion

How Denial of Service via Memory Exhaustion Happens in Node.js Socket.IO and How to Fix It


Vulnerability at a Glance

Field Detail
Vulnerability Denial of Service via Memory Exhaustion
CWE CWE-400: Uncontrolled Resource Consumption
Language JavaScript / Node.js
Risk Unauthenticated attackers can crash the server with crafted packets
Root Cause socket.io-parser 4.2.6 allocates memory without enforcing limits on incoming packet data
Fix Upgrade to socket.io-parser 4.2.7 and pin with package.json overrides

Direct Answer

CVE-2026-69185 is a high-severity Denial of Service vulnerability in the socket.io-parser npm package (Node.js), classified under CWE-400 (Uncontrolled Resource Consumption). An attacker can send specially crafted Socket.IO packets that cause the parser to allocate unbounded memory, exhausting server resources and crashing the application. The fix is to upgrade socket.io-parser to version 4.2.7 (or 3.4.5 / 3.3.6 for older branches) and pin the version using the overrides field in package.json to prevent transitive dependency resolution from pulling in the vulnerable version.


Introduction

Real-time communication is at the heart of many modern web applications — multiplayer games, collaborative tools, live dashboards. Socket.IO is the library that powers much of this, and socket.io-parser is the component that sits at the edge: it receives raw bytes from untrusted clients and turns them into structured events. That position — parsing untrusted data before any application logic runs — makes it a high-value attack surface.

In this project's package-lock.json, the dependency socket.io-parser was pinned to version 4.2.6, which contains a flaw tracked as CVE-2026-69185. A remote attacker who can open a Socket.IO connection (often requiring no authentication in real-time apps) can send crafted packets that trigger uncontrolled memory allocation inside the parser, exhausting the Node.js process heap and taking down the entire server. No application-level code needs to be exploited — the vulnerability lives entirely in the parsing layer.


The Vulnerability Explained

What Does socket.io-parser Actually Do?

socket.io-parser implements the Socket.IO wire protocol. Every message sent over a Socket.IO connection — whether from a browser, a mobile client, or another server — passes through this library's decode() path before your application event handlers ever see it. The parser reconstructs multi-packet binary messages, allocates buffers for attachments, and assembles the final event payload.

The Flaw in 4.2.6

The vulnerability in version 4.2.6 involves insufficient validation of packet metadata during the reconstruction of multi-part (binary) messages. When a client sends a packet claiming to contain a large number of binary attachments, the parser in 4.2.6 allocates internal data structures proportional to that claimed count before verifying that the corresponding data actually arrives. An attacker can craft a packet header that declares thousands of pending attachments, causing the server to pre-allocate large arrays and hold them in memory indefinitely while waiting for data that never comes.

The vulnerable dependency entry in package-lock.json before the fix:

"node_modules/socket.io-parser": {
  "version": "4.2.6",
  "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz",
  "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==",
  "license": "MIT",
  "dependencies": {
    "@socket.io/component-emitter": "~3.1.0",
    ...
  }
}

A Concrete Attack Scenario

Consider a multiplayer game server built on Socket.IO. The game allows unauthenticated connections during the matchmaking phase — players connect first, then authenticate. An attacker writes a script that:

  1. Opens dozens of concurrent WebSocket connections to the server.
  2. On each connection, sends a crafted binary Socket.IO packet with a header claiming nsp: "/", type: 5 (BINARY_EVENT), and attachments: 9999.
  3. Sends the header but never sends the 9999 promised binary frames.

The parser in 4.2.6 dutifully allocates an array of 9999 slots for each connection and holds it in a pending-reconstruction queue. With 50 concurrent connections each holding such a queue entry, the server's heap balloons by hundreds of megabytes. Node.js's garbage collector cannot reclaim these objects because they are still referenced by the parser's internal state machine, waiting for data that will never arrive. The process eventually hits its memory limit and crashes — taking down all legitimate connected players with it.

Real-World Impact

This is particularly dangerous for applications that:
- Allow unauthenticated or loosely authenticated Socket.IO connections
- Run in memory-constrained environments (containers, serverless, shared hosting)
- Handle high connection volumes (gaming, trading platforms, chat systems)
- Use Socket.IO's binary event support (emit with Buffer or ArrayBuffer payloads)


The Fix

What Changed

The fix involves two coordinated changes: upgrading the resolved version of socket.io-parser in package-lock.json, and adding an overrides block to package.json to ensure no transitive dependency can re-introduce the vulnerable version.

package-lock.json — Version Bump

Before:

"node_modules/socket.io-parser": {
  "version": "4.2.6",
  "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz",
  "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg=="
}

After:

"node_modules/socket.io-parser": {
  "version": "4.2.7",
  "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.7.tgz",
  "integrity": "sha512-IH/iSeO9T6gz1KkFleGDWkG9N3dl4jXVYUtMhIqH10Md0ttMer8nUNWiP1DKuNrybD2xBrixLJdCC9J6ECoYkg=="
}

Version 4.2.7 introduces validation that caps the number of declared binary attachments against a safe maximum and validates the claimed count before any allocation occurs. Packets that exceed the limit are rejected early, before any heap-resident state is created for them.

package.json — Dependency Override

This is the more important of the two changes for long-term security:

Before:

{
  "dependencies": {
    "socket.io-client": "^4.8.3",
    "three": "^0.184.0",
    "three-mesh-bvh": "^0.9.9"
  }
}

After:

{
  "dependencies": {
    "socket.io-client": "^4.8.3",
    "three": "^0.184.0",
    "three-mesh-bvh": "^0.9.9"
  },
  "overrides": {
    "socket.io-parser": "4.2.7"
  }
}

Why the overrides Field Matters

socket.io-parser is not a direct dependency of this project — it is a transitive dependency pulled in by socket.io-client. Without the overrides block, running npm install after a socket.io-client upgrade could silently resolve socket.io-parser back to a vulnerable version if the new socket.io-client release still permits 4.2.6 in its own semver range.

The overrides field (introduced in npm 8.3) forces npm's dependency resolver to use exactly 4.2.7 for every occurrence of socket.io-parser in the dependency tree, regardless of what any intermediate package requests. This is the correct pattern for patching transitive vulnerabilities in npm projects.

Patch Coverage Across Branches

The PR title notes three patched versions: 4.2.7, 3.4.5, and 3.3.6. This reflects the fact that the vulnerability exists across multiple major release lines of socket.io-parser. Projects using older Socket.IO versions (v2 or v3 server) should ensure they are on the appropriate patched branch:

Branch Vulnerable Patched
4.x 4.2.6 and earlier 4.2.7
3.4.x 3.4.4 and earlier 3.4.5
3.3.x 3.3.5 and earlier 3.3.6

Prevention & Best Practices

1. Treat Transitive Dependencies as First-Class Security Concerns

The vulnerable code here is not in any file you wrote — it is two levels deep in your dependency tree. Use npm audit, trivy, or Snyk in your CI pipeline to catch these issues automatically. A dependency scanner running on every pull request would have flagged this before it ever reached production.

# Run in CI on every PR
npm audit --audit-level=high

2. Use overrides for Transitive Vulnerability Patches

When a vulnerability is in a transitive (indirect) dependency, a simple npm install of the parent package may not be enough. Always pair the package-lock.json update with an overrides entry in package.json:

"overrides": {
  "vulnerable-package": "safe-version"
}

This ensures the fix survives future npm install runs.

3. Apply Rate Limiting and Connection Throttling

While not a substitute for patching, rate limiting at the connection and message level reduces the blast radius of parser-level DoS attacks:

// Example: limit connections per IP with socket.io
const rateLimit = require('express-rate-limit');
io.use((socket, next) => {
  // Enforce max message rate per socket
  socket.conn.on('data', throttle(() => {}, 100)); // 100ms minimum between packets
  next();
});

4. Monitor Heap Usage in Production

For real-time Node.js servers, heap memory is a key health signal. Instrument your application with metrics that alert when heap usage climbs abnormally:

setInterval(() => {
  const used = process.memoryUsage().heapUsed / 1024 / 1024;
  if (used > HEAP_WARN_THRESHOLD_MB) {
    logger.warn(`Heap usage high: ${used.toFixed(1)} MB`);
  }
}, 10000);

5. Keep Socket.IO and Its Parser in Sync

Always upgrade socket.io, socket.io-client, and socket.io-parser together. The parser version is tightly coupled to the protocol version, and upgrading one without the others can cause subtle compatibility issues or leave you on a vulnerable parser even after upgrading the main package.

Security Standards Reference

  • OWASP A05:2021 – Security Misconfiguration covers failure to update vulnerable components
  • OWASP A06:2021 – Vulnerable and Outdated Components directly applies here
  • CWE-400: Uncontrolled Resource Consumption is the root-cause classification

Key Takeaways

  • socket.io-parser 4.2.6 allocates memory proportional to attacker-supplied attachment counts — upgrading to 4.2.7 adds a validation gate before any allocation occurs.
  • The overrides field in package.json is essential for transitive dependency patches — without it, a future npm install could silently re-introduce the vulnerable version.
  • Unauthenticated connection phases are the highest-risk surface for this DoS — any Socket.IO server that accepts connections before authentication is directly exposed.
  • Trivy caught this in package-lock.json before it caused an incident — dependency scanning in CI is the correct defense-in-depth layer for supply-chain vulnerabilities.
  • All three release branches (4.x, 3.4.x, 3.3.x) were vulnerable — check which branch your socket.io version pulls in and patch accordingly.

How Orbis AppSec Detected This

  • Source: Incoming WebSocket frames from unauthenticated or authenticated remote clients, processed by socket.io-parser's decode path
  • Sink: The binary packet reconstruction logic inside socket.io-parser 4.2.6, which allocates internal buffer arrays sized by the attacker-controlled attachments field in the packet header
  • Missing control: No upper-bound validation on the declared attachment count before memory allocation; the parser trusted the client-supplied value unconditionally
  • CWE: CWE-400 — Uncontrolled Resource Consumption
  • Fix: Upgraded socket.io-parser from 4.2.6 to 4.2.7 in package-lock.json and added a package.json overrides entry to pin the patched version across the full dependency tree

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.


Conclusion

CVE-2026-69185 is a reminder that the most dangerous vulnerabilities in modern web applications are often not in the code you write — they are in the parsing layer that processes untrusted input before your code ever runs. socket.io-parser sits at exactly that boundary: every byte from every connected client flows through it. A single missing bounds check in version 4.2.6 was enough to make any Socket.IO server vulnerable to a heap-exhaustion crash with no authentication required.

The fix is straightforward — upgrade to 4.2.7 and pin the version with overrides — but the lesson is broader: transitive dependencies deserve the same security scrutiny as your own code. Automated scanning with tools like Trivy, combined with CI enforcement and proper use of npm's dependency override mechanisms, transforms this class of vulnerability from a silent risk into a detected-and-patched non-event.


References

Frequently Asked Questions

What is a Denial of Service via memory exhaustion vulnerability?

It occurs when an application allocates memory in response to attacker-controlled input without enforcing an upper bound, allowing an attacker to exhaust available RAM and crash the process.

How do you prevent memory exhaustion DoS in Node.js Socket.IO applications?

Keep socket.io-parser up to date, use the package.json overrides field to pin transitive dependencies, and apply rate limiting or payload size caps on incoming Socket.IO connections.

What CWE is Denial of Service via memory exhaustion?

CWE-400: Uncontrolled Resource Consumption, which covers cases where an application does not limit resource usage in response to external input.

Is rate limiting alone enough to prevent this Socket.IO DoS?

No. Rate limiting reduces the attack surface but does not fix the underlying parser flaw. Upgrading socket.io-parser to 4.2.7 is required to patch the root cause.

Can static analysis detect this type of vulnerability?

Yes. Dependency scanners like Trivy, Snyk, and npm audit can flag known-vulnerable package versions in package-lock.json, which is exactly how CVE-2026-69185 was detected here.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #16

Related Articles

high

How Denial of Service via Unbounded Intermediate Arrays happens in JavaScript and how to fix it

CVE-2026-69152 is a high-severity Denial of Service vulnerability in the `brace-expansion` npm package (versions prior to 1.1.18/2.1.4/3.0.6/5.0.9) that allows attackers to crash a Node.js application by crafting glob patterns that generate unbounded intermediate arrays, effectively bypassing the earlier CVE-2026-14257 mitigation. The fix upgrades `brace-expansion` from 1.1.14 to 1.1.18 in `frontend/package-lock.json`, closing the bypass and restoring safe memory bounds during pattern expansion.

high

How Quadratic CPU Consumption happens in JavaScript YAML parsing and how to fix it

A high-severity denial-of-service vulnerability (GHSA-5p4m-2wfm-xmqj) was discovered in js-yaml affecting both the 3.x and 4.x branches, where parsing YAML documents containing `!!omap` tags triggers quadratic CPU consumption. The fix upgrades js-yaml from `^4.1.1` to `5.2.0` in the project's GitHub Actions workflow dependencies, closing the attack surface for any untrusted YAML input processed by CI/CD tooling.

critical

How Missing Rate Limiting happens in Express.js and how to fix it

Two public API endpoints in `server.js` — `/api/health` and `/api/contact` — were exposed without any rate limiting middleware, allowing attackers to exhaust server resources or spam an SMTP server with unlimited requests. The fix adds rate limiting to both endpoints, with stricter controls on the resource-intensive `/api/contact` route that triggers email sending operations. This change closes a directly exploitable denial-of-service vector in a production web service.

high

How Denial of Service via Specific Input Sequence happens in JavaScript (marked) and how to fix it

CVE-2026-41680 is a high-severity Denial of Service vulnerability in the marked Markdown parsing library, affecting versions prior to 18.0.2. By supplying a crafted input sequence to the parser, an attacker can cause the application to hang or exhaust resources, making the frontend unavailable. Upgrading marked from 18.0.0 to 18.0.2 in both `package.json` and `package-lock.json` closes the vulnerability without affecting valid Markdown rendering.

high

How Quadratic CPU Consumption happens in JavaScript YAML parsing and how to fix it

A high-severity denial-of-service vulnerability in js-yaml (GHSA-5p4m-2wfm-xmqj) caused quadratic CPU consumption when resolving `!!omap` YAML types in both the 3.x and 4.x branches. The fix upgrades js-yaml from 3.14.2 to 3.15.1 and from 4.1.1 to 4.3.1, eliminating the algorithmic complexity exploit while leaving all valid YAML inputs unaffected.

high

How Denial of Service via Unbounded Data Happens in JavaScript and how to fix it

CVE-2025-58754 is a high-severity Denial of Service vulnerability in the popular axios HTTP client library, caused by the absence of a data size check on incoming response or request payloads. An attacker who can influence the size of data processed by axios could exhaust server memory or CPU, bringing down dependent Node.js applications. The fix upgrades axios from version 1.8.4 to 1.18.0, closing the unbounded data processing path.