Uncaught Exception in engine.io
Description
Engine.IO is the implementation of transport-based cross-browser/cross-device bi-directional communication layer for Socket.IO. A specially crafted HTTP request can trigger an uncaught exception on the Engine.IO server, thus killing the Node.js process. This impacts all the users of the engine.io package starting from version 4.0.0, including those who uses depending packages like socket.io. Versions prior to 4.0.0 are not impacted. A fix has been released for each major branch, namely 4.1.2 for the 4.x.x branch, 5.2.1 for the 5.x.x branch, and 6.1.1 for the 6.x.x branch. There is no known workaround except upgrading to a safe version.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
engine.ionpm | >= 4.0.0, < 4.1.2 | 4.1.2 |
engine.ionpm | >= 5.0.0, < 5.2.1 | 5.2.1 |
engine.ionpm | >= 6.0.0, < 6.1.1 | 6.1.1 |
Affected products
1Patches
3c0e194d44933fix: properly handle invalid data sent by a malicious websocket client
2 files changed · +40 −3
lib/server.ts+0 −3 modified@@ -609,9 +609,6 @@ export class Server extends BaseServer { client.maybeUpgrade(transport); } } else { - // transport error handling takes over - websocket.removeListener("error", onUpgradeError); - const closeConnection = (errorCode, errorContext) => abortUpgrade(socket, errorCode, errorContext); this.handshake(req._query.transport, req, closeConnection);
test/server.js+40 −0 modified@@ -157,6 +157,46 @@ describe("server", () => { } ); }); + + it("should not throw when the client sends invalid data during the handshake (ws only)", done => { + listen(port => { + // will throw "RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear" + request + .get(`http://localhost:${port}/engine.io/`) + .set("connection", "upgrade") + .set("upgrade", "websocket") + .set("Sec-WebSocket-Version", "13") + .set("Sec-WebSocket-Key", "DXR4dX615eRds8nRmlhqtw==") + .query({ transport: "websocket", EIO: 4 }) + .send("test") + .end(() => {}); + + setTimeout(done, 50); + }); + }); + + it("should not throw when the client sends invalid data during the handshake (upgrade)", done => { + listen(port => { + request + .get(`http://localhost:${port}/engine.io/`) + .query({ transport: "polling", EIO: 4 }) + .end((err, res) => { + const sid = JSON.parse(res.text.substring(1)).sid; + + request + .get(`http://localhost:${port}/engine.io/`) + .set("connection", "upgrade") + .set("upgrade", "websocket") + .set("Sec-WebSocket-Version", "13") + .set("Sec-WebSocket-Key", "DXR4dX615eRds8nRmlhqtw==") + .query({ transport: "websocket", EIO: 4, sid }) + .send("test") + .end(() => {}); + + setTimeout(done, 50); + }); + }); + }); }); describe("handshake", () => {
a70800d7e96dfix: properly handle invalid data sent by a malicious websocket client
2 files changed · +40 −3
lib/server.js+0 −3 modified@@ -372,9 +372,6 @@ class Server extends EventEmitter { client.maybeUpgrade(transport); } } else { - // transport error handling takes over - socket.removeListener("error", onUpgradeError); - this.handshake(req._query.transport, req); }
test/server.js+40 −0 modified@@ -107,6 +107,46 @@ describe("server", () => { } ); }); + + it("should not throw when the client sends invalid data during the handshake (ws only)", done => { + listen(port => { + // will throw "RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear" + request + .get(`http://localhost:${port}/engine.io/`) + .set("connection", "upgrade") + .set("upgrade", "websocket") + .set("Sec-WebSocket-Version", "13") + .set("Sec-WebSocket-Key", "DXR4dX615eRds8nRmlhqtw==") + .query({ transport: "websocket", EIO: 4 }) + .send("test") + .end(() => {}); + + setTimeout(done, 50); + }); + }); + + it("should not throw when the client sends invalid data during the handshake (upgrade)", done => { + listen(port => { + request + .get(`http://localhost:${port}/engine.io/`) + .query({ transport: "polling", EIO: 4 }) + .end((err, res) => { + const sid = JSON.parse(res.text.substring(1)).sid; + + request + .get(`http://localhost:${port}/engine.io/`) + .set("connection", "upgrade") + .set("upgrade", "websocket") + .set("Sec-WebSocket-Version", "13") + .set("Sec-WebSocket-Key", "DXR4dX615eRds8nRmlhqtw==") + .query({ transport: "websocket", EIO: 4, sid }) + .send("test") + .end(() => {}); + + setTimeout(done, 50); + }); + }); + }); }); describe("handshake", () => {
66f889fc1d96fix: properly handle invalid data sent by a malicious websocket client
2 files changed · +40 −3
lib/server.js+0 −3 modified@@ -454,9 +454,6 @@ class Server extends EventEmitter { client.maybeUpgrade(transport); } } else { - // transport error handling takes over - websocket.removeListener("error", onUpgradeError); - const closeConnection = (errorCode, errorContext) => abortUpgrade(socket, errorCode, errorContext); this.handshake(req._query.transport, req, closeConnection);
test/server.js+40 −0 modified@@ -157,6 +157,46 @@ describe("server", () => { } ); }); + + it("should not throw when the client sends invalid data during the handshake (ws only)", done => { + listen(port => { + // will throw "RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear" + request + .get(`http://localhost:${port}/engine.io/`) + .set("connection", "upgrade") + .set("upgrade", "websocket") + .set("Sec-WebSocket-Version", "13") + .set("Sec-WebSocket-Key", "DXR4dX615eRds8nRmlhqtw==") + .query({ transport: "websocket", EIO: 4 }) + .send("test") + .end(() => {}); + + setTimeout(done, 50); + }); + }); + + it("should not throw when the client sends invalid data during the handshake (upgrade)", done => { + listen(port => { + request + .get(`http://localhost:${port}/engine.io/`) + .query({ transport: "polling", EIO: 4 }) + .end((err, res) => { + const sid = JSON.parse(res.text.substring(1)).sid; + + request + .get(`http://localhost:${port}/engine.io/`) + .set("connection", "upgrade") + .set("upgrade", "websocket") + .set("Sec-WebSocket-Version", "13") + .set("Sec-WebSocket-Key", "DXR4dX615eRds8nRmlhqtw==") + .query({ transport: "websocket", EIO: 4, sid }) + .send("test") + .end(() => {}); + + setTimeout(done, 50); + }); + }); + }); }); describe("handshake", () => {
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- github.com/advisories/GHSA-273r-mgr4-v34fghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-21676ghsaADVISORY
- github.com/socketio/engine.io/commit/66f889fc1d966bf5bfa0de1939069153643874abghsax_refsource_MISCWEB
- github.com/socketio/engine.io/commit/a70800d7e96da32f6e6622804ef659ebc58659dbghsax_refsource_MISCWEB
- github.com/socketio/engine.io/commit/c0e194d44933bd83bf9a4b126fca68ba7bf5098cghsax_refsource_MISCWEB
- github.com/socketio/engine.io/releases/tag/4.1.2ghsax_refsource_MISCWEB
- github.com/socketio/engine.io/releases/tag/5.2.1ghsax_refsource_MISCWEB
- github.com/socketio/engine.io/releases/tag/6.1.1ghsax_refsource_MISCWEB
- github.com/socketio/engine.io/security/advisories/GHSA-273r-mgr4-v34fghsax_refsource_CONFIRMWEB
- security.netapp.com/advisory/ntap-20220209-0002ghsaWEB
- security.netapp.com/advisory/ntap-20220209-0002/mitrex_refsource_CONFIRM
News mentions
0No linked articles in our index yet.