Safeguard
Vulnerability Analysis

socket.io-parser denial of service (CVE-2020-28477)

A remote, unauthenticated attacker could crash Socket.IO servers with one malformed packet. Here's the CVE-2020-28477 breakdown and how to fix it.

Nayan Dey
Security Researcher
7 min read

Node.js applications that lean on real-time messaging almost always pull in Socket.IO, and Socket.IO leans on a small, unglamorous dependency called socket.io-parser to encode and decode every packet that crosses the wire. CVE-2020-28477 is a denial-of-service vulnerability in that parser: a remote, unauthenticated attacker can send a single malformed packet that crashes the entire Node.js process hosting the Socket.IO server, dropping every connected client and taking the service offline until it's manually restarted. Because socket.io-parser sits underneath one of the most widely used real-time libraries in the JavaScript ecosystem, the practical blast radius extends to chat apps, collaborative editors, trading dashboards, IoT telemetry pipelines, and any other service that depends on persistent WebSocket connections.

The bug itself is unremarkable in isolation — it's the kind of input-validation gap that shows up in dozens of parsing libraries every year. What makes it worth revisiting is what it represents: a transitive dependency, several layers removed from application code, that most engineering teams never audit directly, yet one malformed message away from an outage.

Affected Versions and Components

socket.io-parser is maintained as a separate npm package and is pulled in automatically as a dependency of socket.io (server) and, in earlier releases, socket.io-client. The vulnerability affects:

  • socket.io-parser versions prior to 3.3.2 (used by socket.io 1.x and 2.x lines)
  • socket.io-parser versions 4.0.0 through 4.0.3 (used by socket.io 3.x)

The root cause is insufficient validation of packet structure during decoding. When the parser encounters a packet with a malformed or unexpected attachment count / payload shape, it throws an exception outside of a code path that the library or the surrounding application is prepared to catch. In a standard Node.js event-loop model, an uncaught exception at that layer doesn't just fail one request — it can bring down the entire process, terminating every open socket connection served by that instance.

Fixed versions are socket.io-parser@3.3.2 and socket.io-parser@4.0.4. Because most teams don't depend on socket.io-parser directly, the more actionable takeaway is the parent package: upgrade socket.io to 2.4.0 or later (which resolves to the patched 3.x parser) or 3.0.5 or later (which resolves to the patched 4.x parser). If you maintain a custom Socket.IO client or a polyglot server implementation that vendors the parser logic, check that codebase independently — CVE fixes in upstream npm packages don't propagate to forks or hand-rolled reimplementations.

Severity: CVSS, EPSS, and KEV Context

The National Vulnerability Database lists CVE-2020-28477 with a CVSS v3.1 base score of 7.5 (High), reflecting the vector AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — network-exploitable, low attack complexity, no privileges or user interaction required, no impact on confidentiality or integrity, but a high impact on availability. That combination is exactly what you'd expect from a remotely triggerable crash bug: trivial to exploit, limited to service disruption, but capable of taking down every user session on the affected instance in one shot.

EPSS (Exploit Prediction Scoring System) data for this CVE sits in the low range typical of library-level DoS issues that don't have a well-known, weaponized public exploit chain — there's no evidence of widespread automated scanning or exploitation campaigns targeting this specific flaw. It also does not appear on CISA's Known Exploited Vulnerabilities (KEV) catalog, which tracks vulnerabilities with confirmed active exploitation in the wild. That's a useful data point for prioritization, but not a reason to deprioritize the fix: KEV absence reflects observed exploitation, not exploitability, and a crash-on-input bug in a library this widely deployed is exactly the kind of thing that gets rediscovered and abused opportunistically once attention returns to it.

Timeline

  • Pre-disclosure: The socket.io-parser maintainers identified and fixed the packet-validation gap in coordinated patch releases for both the 3.x and 4.x parser lines.
  • Patch release: socket.io-parser@3.3.2 and socket.io-parser@4.0.4 shipped to npm with the input-validation fix, alongside corresponding socket.io releases (2.4.0 and 3.0.5) that pinned the patched parser as a dependency.
  • Public disclosure: The issue was published as a GitHub Security Advisory and formally assigned CVE-2020-28477, entering the NVD with its CVSS scoring shortly after.
  • Ecosystem lag: As with most transitive-dependency CVEs, the advisory's publication didn't translate into immediate remediation across the ecosystem. Because socket.io-parser is rarely a direct dependency, many projects only received the fix incidentally — when a routine npm update bumped socket.io itself — while pinned or lockfile-frozen projects remained exposed indefinitely.

That lag is the real story behind most "old" CVEs like this one: the patch has existed for years, but SBOM and dependency-tree visibility gaps mean vulnerable versions are still resolvable in fresh npm install runs today if a project's lockfile was generated before the fix, or if an outdated Docker base image bakes in a stale node_modules layer.

Remediation Steps

  1. Identify exposure. Check whether your application or any internal service depends on socket.io or socket.io-parser directly:

    npm ls socket.io socket.io-parser
    

    Do this at every layer of your dependency tree — transitive inclusion via an internal SDK, an admin dashboard, or a third-party widget is common and easy to miss.

  2. Upgrade the parent package. Bump socket.io in package.json to a version that resolves to a patched parser:

    npm install socket.io@^2.4.0   # or ^3.0.5, or latest current major
    

    If you can move to a current major release (Socket.IO 4.x) rather than the minimum patched version, do so — it also picks up unrelated hardening and bug fixes shipped since.

  3. Regenerate lockfiles. A version bump in package.json alone doesn't help if package-lock.json or yarn.lock still resolves to the old parser. Regenerate the lockfile and commit it, and rebuild any Docker images that cache a pre-fix node_modules.

  4. Audit forks and vendored copies. If your team maintains a custom Socket.IO-compatible client (common in embedded or IoT contexts), verify the packet-decoding path independently validates attachment counts and payload structure before trusting client input.

  5. Add process-level resilience regardless of patch status. Run Socket.IO servers under a process manager (PM2, systemd with Restart=always, or a Kubernetes liveness probe) so an unexpected crash — from this or any future uncaught-exception bug — results in automatic recovery rather than sustained downtime.

  6. Verify with a dependency scan. After upgrading, re-scan the project to confirm no other path in the tree still resolves to a vulnerable socket.io-parser version — multiple internal packages depending on different socket.io majors is a common way for the vulnerable version to survive a "successful" upgrade.

How Safeguard Helps

CVEs like this one are rarely hard to fix once found — the hard part is finding them before an attacker does, and knowing whether they actually matter in your specific deployment. Safeguard's SBOM generation and ingestion continuously map every direct and transitive dependency across your services, so a vulnerable socket.io-parser buried three layers deep in a bundled admin tool doesn't stay invisible. Our reachability analysis goes further than "is it present" and answers "is the vulnerable decode path actually reachable from an exposed WebSocket endpoint" — cutting through alert noise so teams don't waste cycles patching library versions their runtime never calls into. Griffin, Safeguard's AI security analyst, correlates the CVE, its CVSS/EPSS context, and your codebase's actual call graph to explain the real risk in plain language, and for confirmed, reachable findings like this one, Safeguard can open an auto-fix pull request that bumps the dependency and regenerates the lockfile — turning a multi-step remediation into a single review-and-merge action.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.