10 High
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
CHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
0.002 Low
EPSS
Percentile
59.3%
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`
});
});
undefined
Sample 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:
[email protected]
[email protected]
[email protected]
[email protected]
socket.io
packagesocket.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
packagesocket.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: |
csirt.divd.nl/cases/DIVD-2022-00045
csirt.divd.nl/CVE-2022-2421
csirt.divd.nl/cves/CVE-2022-2421
csirt.divd.nl/DIVD-2022-00045
github.com/socketio/socket.io-parser
github.com/socketio/socket.io-parser/commit/04d23cecafe1b859fb03e0cbf6ba3b74dff56d14
github.com/socketio/socket.io-parser/commit/b559f050ee02bd90bd853b9823f8de7fa94a80d4
github.com/socketio/socket.io-parser/commit/b5d0cb7dc56a0601a09b056beaeeb0e43b160050
github.com/socketio/socket.io-parser/commit/fb21e422fc193b34347395a33e0f625bebc09983
nvd.nist.gov/vuln/detail/CVE-2022-2421