All the vulnerabilities related to the version 1.1.1 of the package
socket.io has an unhandled 'error' event
A specially crafted Socket.IO packet can trigger an uncaught exception on the Socket.IO server, thus killing the Node.js process.
node:events:502
throw err; // Unhandled 'error' event
^
Error [ERR_UNHANDLED_ERROR]: Unhandled error. (undefined)
at new NodeError (node:internal/errors:405:5)
at Socket.emit (node:events:500:17)
at /myapp/node_modules/socket.io/lib/socket.js:531:14
at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
code: 'ERR_UNHANDLED_ERROR',
context: undefined
}
| Version range | Needs minor update? |
|------------------|------------------------------------------------|
| 4.6.2...latest | Nothing to do |
| 3.0.0...4.6.1 | Please upgrade to socket.io@4.6.2 (at least) |
| 2.3.0...2.5.0 | Please upgrade to socket.io@2.5.1 |
This issue is fixed by https://github.com/socketio/socket.io/commit/15af22fc22bc6030fcead322c106f07640336115, included in socket.io@4.6.2 (released in May 2023).
The fix was backported in the 2.x branch today: https://github.com/socketio/socket.io/commit/d30630ba10562bf987f4d2b42440fc41a828119c
As a workaround for the affected versions of the socket.io package, you can attach a listener for the "error" event:
io.on("connection", (socket) => {
socket.on("error", () => {
// ...
});
});
If you have any questions or comments about this advisory:
Thanks a lot to Paul Taylor for the responsible disclosure.
CORS misconfiguration in socket.io
The package socket.io before 2.4.0 are vulnerable to Insecure Defaults due to CORS Misconfiguration. All domains are whitelisted by default.
debug Inefficient Regular Expression Complexity vulnerability
A vulnerability classified as problematic has been found in debug-js debug up to 3.0.x. This affects the function useColors of the file src/node.js. The manipulation of the argument str leads to inefficient regular expression complexity. Upgrading to version 3.1.0 is able to address this issue. The name of the patch is c38a0166c266a679c8de012d4eaccec3f944e685. It is recommended to upgrade the affected component. The identifier VDB-217665 was assigned to this vulnerability. The patch has been backported to the 2.6.x branch in version 2.6.9.
Regular Expression Denial of Service in debug
Affected versions of debug are vulnerable to regular expression denial of service when untrusted user input is passed into the o formatter.
As it takes 50,000 characters to block the event loop for 2 seconds, this issue is a low severity issue.
This was later re-introduced in version v3.2.0, and then repatched in versions 3.2.7 and 4.3.1.
Version 2.x.x: Update to version 2.6.9 or later. Version 3.1.x: Update to version 3.1.0 or later. Version 3.2.x: Update to version 3.2.7 or later. Version 4.x.x: Update to version 4.3.1 or later.
Vercel ms Inefficient Regular Expression Complexity vulnerability
A vulnerability, which was classified as problematic, has been found in vercel ms up to 1.x. This issue affects the function parse of the file index.js. The manipulation of the argument str leads to inefficient regular expression complexity. The attack may be initiated remotely. The exploit has been disclosed to the public and may be used. Upgrading to version 2.0.0 is able to address this issue. The name of the patch is caae2988ba2a37765d055c4eee63d383320ee662. It is recommended to upgrade the affected component. The associated identifier of this vulnerability is VDB-217451.
Resource exhaustion in engine.io
Engine.IO before 4.0.0 and 3.6.0 allows attackers to cause a denial of service (resource consumption) via a POST request to the long polling transport.
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.ioThanks to Jonathan Neve for the responsible disclosure.
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.
Insufficient validation when decoding a Socket.IO packet
A specially crafted Socket.IO packet can trigger an uncaught exception on the Socket.IO server, thus killing the Node.js process.
TypeError: Cannot convert object to primitive value
at Socket.emit (node:events:507:25)
at .../node_modules/socket.io/lib/socket.js:531:14
A fix has been released today (2023/05/22):
socket.io-parser@4.2.3socket.io-parser@3.4.3Another fix has been released for the 3.3.x branch:
| socket.io version | socket.io-parser version | Needs minor update? |
|---------------------|---------------------------------------------------------------------------------------------------------|--------------------------------------|
| 4.5.2...latest | ~4.2.0 (ref) | npm audit fix should be sufficient |
| 4.1.3...4.5.1 | ~4.1.1 (ref) | Please upgrade to socket.io@4.6.x |
| 3.0.5...4.1.2 | ~4.0.3 (ref) | Please upgrade to socket.io@4.6.x |
| 3.0.0...3.0.4 | ~4.0.1 (ref) | Please upgrade to socket.io@4.6.x |
| 2.3.0...2.5.0 | ~3.4.0 (ref) | npm audit fix should be sufficient |
There is no known workaround except upgrading to a safe version.
If you have any questions or comments about this advisory:
Thanks to @rafax00 for the responsible disclosure.
Insufficient validation when decoding a Socket.IO packet
Due to improper type validation in the socket.io-parser library (which is used by the socket.io and socket.io-client packages to encode and decode Socket.IO packets), it is possible to overwrite the _placeholder object which allows an attacker to place references to functions at arbitrary places in the resulting query object.
Example:
const decoder = new Decoder();
decoder.on("decoded", (packet) => {
console.log(packet.data); // prints [ 'hello', [Function: splice] ]
})
decoder.add('51-["hello",{"_placeholder":true,"num":"splice"}]');
decoder.add(Buffer.from("world"));
This bubbles up in the socket.io package:
io.on("connection", (socket) => {
socket.on("hello", (val) => {
// here, "val" could be a function instead of a buffer
});
});
:warning: IMPORTANT NOTE :warning:
You need to make sure that the payload that you received from the client is actually a Buffer object:
io.on("connection", (socket) => {
socket.on("hello", (val) => {
if (!Buffer.isBuffer(val)) {
socket.disconnect();
return;
}
// ...
});
});
If that's already the case, then you are not impacted by this issue, and there is no way an attacker could make your server crash (or escalate privileges, ...).
Example of values that could be sent by a malicious user:
Sample packet: 451-["hello",{"_placeholder":true,"num":10}]
io.on("connection", (socket) => {
socket.on("hello", (val) => {
// val is `undefined`
});
});
undefinedSample packet: 451-["hello",{"_placeholder":true,"num":undefined}]
io.on("connection", (socket) => {
socket.on("hello", (val) => {
// val is `undefined`
});
});
Array, like "push"Sample packet: 451-["hello",{"_placeholder":true,"num":"push"}]
io.on("connection", (socket) => {
socket.on("hello", (val) => {
// val is a reference to the "push" function
});
});
Object, like "hasOwnProperty"Sample packet: 451-["hello",{"_placeholder":true,"num":"hasOwnProperty"}]
io.on("connection", (socket) => {
socket.on("hello", (val) => {
// val is a reference to the "hasOwnProperty" function
});
});
This should be fixed by:
socket.io-parser@4.2.1socket.io-parser@4.0.5socket.io-parser@3.4.2socket.io-parser@3.3.3socket.io package| socket.io version | socket.io-parser version | Covered? |
|---------------------|---------------------------------------------------------------------------------------------------------|------------------------|
| 4.5.2...latest | ~4.2.0 (ref) | Yes :heavy_check_mark: |
| 4.1.3...4.5.1 | ~4.0.4 (ref) | Yes :heavy_check_mark: |
| 3.0.5...4.1.2 | ~4.0.3 (ref) | Yes :heavy_check_mark: |
| 3.0.0...3.0.4 | ~4.0.1 (ref) | Yes :heavy_check_mark: |
| 2.3.0...2.5.0 | ~3.4.0 (ref) | Yes :heavy_check_mark: |
socket.io-client package| socket.io-client version | socket.io-parser version | Covered? |
|----------------------------|----------------------------------------------------------------------------------------------------------------|------------------------------------|
| 4.5.0...latest | ~4.2.0 (ref) | Yes :heavy_check_mark: |
| 4.3.0...4.4.1 | ~4.1.1 (ref) | No, but the impact is very limited |
| 3.1.0...4.2.0 | ~4.0.4 (ref) | Yes :heavy_check_mark: |
| 3.0.5 | ~4.0.3 (ref) | Yes :heavy_check_mark: |
| 3.0.0...3.0.4 | ~4.0.1 (ref) | Yes :heavy_check_mark: |
| 2.2.0...2.5.0 | ~3.3.0 (ref) | Yes :heavy_check_mark: |
Resource exhaustion in socket.io-parser
The socket.io-parser npm package before versions 3.3.2 and 3.4.1 allows attackers to cause a denial of service (memory consumption) via a large packet because a concatenation approach is used.
Prototype Pollution in JSON5 via Parse Method
The parse method of the JSON5 library before and including version 2.2.1 does not restrict parsing of keys named __proto__, allowing specially crafted strings to pollute the prototype of the resulting object.
This vulnerability pollutes the prototype of the object returned by JSON5.parse and not the global Object prototype, which is the commonly understood definition of Prototype Pollution. However, polluting the prototype of a single object can have significant security impact for an application if the object is later used in trusted operations.
This vulnerability could allow an attacker to set arbitrary and unexpected keys on the object returned from JSON5.parse. The actual impact will depend on how applications utilize the returned object and how they filter unwanted keys, but could include denial of service, cross-site scripting, elevation of privilege, and in extreme cases, remote code execution.
This vulnerability is patched in json5 v2.2.2 and later. A patch has also been backported for json5 v1 in versions v1.0.2 and later.
Suppose a developer wants to allow users and admins to perform some risky operation, but they want to restrict what non-admins can do. To accomplish this, they accept a JSON blob from the user, parse it using JSON5.parse, confirm that the provided data does not set some sensitive keys, and then performs the risky operation using the validated data:
const JSON5 = require('json5');
const doSomethingDangerous = (props) => {
if (props.isAdmin) {
console.log('Doing dangerous thing as admin.');
} else {
console.log('Doing dangerous thing as user.');
}
};
const secCheckKeysSet = (obj, searchKeys) => {
let searchKeyFound = false;
Object.keys(obj).forEach((key) => {
if (searchKeys.indexOf(key) > -1) {
searchKeyFound = true;
}
});
return searchKeyFound;
};
const props = JSON5.parse('{"foo": "bar"}');
if (!secCheckKeysSet(props, ['isAdmin', 'isMod'])) {
doSomethingDangerous(props); // "Doing dangerous thing as user."
} else {
throw new Error('Forbidden...');
}
If the user attempts to set the isAdmin key, their request will be rejected:
const props = JSON5.parse('{"foo": "bar", "isAdmin": true}');
if (!secCheckKeysSet(props, ['isAdmin', 'isMod'])) {
doSomethingDangerous(props);
} else {
throw new Error('Forbidden...'); // Error: Forbidden...
}
However, users can instead set the __proto__ key to {"isAdmin": true}. JSON5 will parse this key and will set the isAdmin key on the prototype of the returned object, allowing the user to bypass the security check and run their request as an admin:
const props = JSON5.parse('{"foo": "bar", "__proto__": {"isAdmin": true}}');
if (!secCheckKeysSet(props, ['isAdmin', 'isMod'])) {
doSomethingDangerous(props); // "Doing dangerous thing as admin."
} else {
throw new Error('Forbidden...');
}
Regular Expression Denial of Service (ReDoS) in cross-spawn
Versions of the package cross-spawn before 7.0.5 are vulnerable to Regular Expression Denial of Service (ReDoS) due to improper input sanitization. An attacker can increase the CPU usage and crash the program by crafting a very large and well crafted string.
yargs-parser Vulnerable to Prototype Pollution
Affected versions of yargs-parser are vulnerable to prototype pollution. Arguments are not properly sanitized, allowing an attacker to modify the prototype of Object, causing the addition or modification of an existing property that will exist on all objects.
Parsing the argument --foo.__proto__.bar baz' adds a bar property with value baz to all objects. This is only exploitable if attackers have control over the arguments being passed to yargs-parser.
Upgrade to versions 13.1.2, 15.0.1, 18.1.1 or later.
Babel vulnerable to arbitrary code execution when compiling specifically crafted malicious code
Using Babel to compile code that was specifically crafted by an attacker can lead to arbitrary code execution during compilation, when using plugins that rely on the path.evaluate()or path.evaluateTruthy() internal Babel methods.
Known affected plugins are:
@babel/plugin-transform-runtime@babel/preset-env when using its useBuiltIns option@babel/helper-define-polyfill-provider, such as babel-plugin-polyfill-corejs3, babel-plugin-polyfill-corejs2, babel-plugin-polyfill-es-shims, babel-plugin-polyfill-regeneratorNo other plugins under the @babel/ namespace are impacted, but third-party plugins might be.
Users that only compile trusted code are not impacted.
The vulnerability has been fixed in @babel/traverse@7.23.2.
Babel 6 does not receive security fixes anymore (see Babel's security policy), hence there is no patch planned for babel-traverse@6.
@babel/traverse to v7.23.2 or higher. You can do this by deleting it from your package manager's lockfile and re-installing the dependencies. @babel/core >=7.23.2 will automatically pull in a non-vulnerable version.@babel/traverse and are using one of the affected packages mentioned above, upgrade them to their latest version to avoid triggering the vulnerable code path in affected @babel/traverse versions:
@babel/plugin-transform-runtime v7.23.2@babel/preset-env v7.23.2@babel/helper-define-polyfill-provider v0.4.3babel-plugin-polyfill-corejs2 v0.4.6babel-plugin-polyfill-corejs3 v0.8.5babel-plugin-polyfill-es-shims v0.10.0babel-plugin-polyfill-regenerator v0.5.3parse-uri Regular expression Denial of Service (ReDoS)
An issue in parse-uri v1.0.9 allows attackers to cause a Regular expression Denial of Service (ReDoS) via a crafted URL.
async function exploit() {
const parseuri = require("parse-uri");
// This input is designed to cause excessive backtracking in the regex
const craftedInput = 'http://example.com/' + 'a'.repeat(30000) + '?key=value';
const result = await parseuri(craftedInput);
}
await exploit();
Regular Expression Denial of Service in parsejson
Affected versions of parsejson are vulnerable to a regular expression denial of service when parsing untrusted user input.
The parsejson package has not been functionally updated since it was initially released.
Additionally, it provides functionality which is natively included in Node.js, and therefore the native JSON.parse() should be used, for both performance and security reasons.