CVE-2023-32695 Solution options without installing a new version #4722
-
Not many developers are ready to switch to a new version of socket.io, so I suggest a manual solution for these developers.
import {Server} from "socket.io";
const server = new Server();
const copyIsPayloadValid = server._parser.Decoder.isPayloadValid;
server._parser.Decoder.isPayloadValid = function (type, payload) {
switch (type) {
case 2:
case 5:
return (
Array.isArray(payload) &&
(typeof payload[0] === "string" || typeof payload[0] === "number")
);
default:
return copyIsPayloadValid(type, payload);
}
}
import {Socket} from "socket.io";
const CopyDispatch = Socket.prototype.dispatch;
Socket.prototype.dispatch = function(packet) {
if(Array.isArray(packet) && packet.length > 0 && typeof packet[0] !== "string" || typeof packet[0] !== "number") {
return;
}
CopyDispatch.call(this, packet);
}
/**
* Docs: https://socket.io/docs/v4/custom-parser/
*/
const Emitter = require("component-emitter");
class Decoder extends Emitter {
/**
* Receive a chunk (string or buffer) and optionally emit a "decoded" event with the reconstructed packet
*/
add(chunk) {
const packet = JSON.parse(chunk);
if (this.isPacketValid(packet)) {
this.emit("decoded", packet);
} else {
throw new Error("invalid format");
}
}
isPacketValid(type, payload) {
const isNamespaceValid = typeof nsp === "string";
const isAckIdValid = id === undefined || Number.isInteger(id);
if (!isNamespaceValid || !isAckIdValid) {
return false;
}
switch (type) {
case 0: / CONNECT:
return typeof payload === "object";
case 1: // DISCONNECT:
return payload === undefined;
case 2: // EVENT:
return (
Array.isArray(payload) &&
(typeof payload[0] === "string" || typeof payload[0] === "number")
);
case 3: // ACK:
return Array.isArray(payload);
case 4: // CONNECT_ERROR
return typeof data === "object";
default:
return false;
}
}
/**
* Clean up internal buffers
*/
destroy() {}
}
class Encoder {
/**
* Encode a packet into a list of strings/buffers
*/
encode(packet) {
return [JSON.stringify(packet)];
}
}
const io = new Server({
parser: {
Decoder,
Encoder
}
}); You can suggest your own options :) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Hi! Thanks for raising this concern 👍 There is also socket.use(([event], next) => {
if (typeof event === "number" || typeof event === "string") {
next();
} else {
socket.disconnect(true);
}
}); Reference: https://socket.io/docs/v4/server-api/#socketusefn
Out of curiosity, what makes you say that? The migration from v3 to v4 should be rather straightforward, as there are just a couple of breaking changes impacting the API on the server side: https://socket.io/docs/v4/migrating-from-3-x-to-4-0/ That being said, if that's really an issue, we could backport the fix in the other branches, like For reference:
|
Beta Was this translation helpful? Give feedback.
Hi! Thanks for raising this concern 👍
There is also
socket.use()
:Reference: https://socket.io/docs/v4/server-api/#socketusefn
Out of curiosity, what makes you say that? The migration from v3 to v4 should be rather straightforward, as there are just a couple of breaking changes impacting the API on the server side: https://socket.io/docs/v4/migrating-from-3-x-to-4-0/
That being said, if that's really an issue, we could backport the fix in the other branches, like
4…