Repository navigation
A client receiving an Object with more than 10 binary fields closes the connection #5504
Description
Activity
- addedto triageWaiting to be triaged by a member of the teamWaiting to be triaged by a member of the team
on May 26, 2026 Hi! This behavior was indeed introduced in b25738c (released in
socket.io-parser@4.2.6, included insocket.io@^4.6.0), in order to prevent a malicious user from making the server run out of memory (by buffering a lot binary attachments forever).See also: CVE-2026-33151
The limit is indeed set to 10 binary attachments. It can be increased with a custom
parser:import { Encoder, Decoder } from "socket.io-parser"; const io = new Server({ parser: { Encoder, Decoder: class extends Decoder { constructor() { super({ maxAttachments: 20 }); } } } });
There is no release of the
socket.io-clientpackage with the fix yet, that's why the bundle from the CDN does not show this behavior.- addedquestionFurther information is requestedFurther information is requestedand removedto triageWaiting to be triaged by a member of the teamWaiting to be triaged by a member of the team
on May 28, 2026 I'm not sure to understand.
Actually I need to use a Python server and a browser JS client got from NPM and bundled with Vite.
I can do a variety of server and client combinations among Python, Node.js and browser JS and I think the issue is only caused by using the
socket.io-clientNPM package, but the solution you give involves tweaking the server.Here is also a Python client using python-socketio[asyncio-client] 5.16.2, which also doesn't suffer the issue while communicating with either the Python or Node.js server as described in my first message:
import asyncio import socketio sio = socketio.AsyncClient() @sio.event async def connect(): print('Connected to server') await asyncio.sleep(2) await sio.emit('request_data') @sio.event async def data(data): print('Received data from server') for key, value in data.items(): print(f'{key}: {len(value)} bytes') async def main(): await sio.connect('http://localhost:8000') await sio.wait() if __name__ == '__main__': asyncio.run(main())
OK, I saw the
parseroption is also settable to the client, so this solves the issue:import { io } from 'socket.io-client'; import { Encoder, Decoder } from "socket.io-parser"; const socket = io( `http://localhost:8000`, { parser: { Encoder, Decoder: class extends Decoder { constructor() { super({ maxAttachments: Infinity }); } }, }, }, );
Now I don't understand the security concern addressed.
When I use the Node.js server described in my first message with a Python or browser JS via CDN client, the issue doesn't occur.
So finally the limitation is only in the client, which a malicious end user can tweak as they wish.
Also it would have been convenient if this behavior was documented, because I struggled quite a lot.
I believe CDN bundle is built against an older version of the parser (
socket.io-parser< 4.2.6), thus the difference.
Describe the bug
When the Python or Node.js server sends an
Objectcontaining more than 10 binary fields to a web browser JS client got via NPM, it fails and the connection is interrupted.The issue doesn't happen when the package is got via the CDN.
To Reproduce
Socket.IO server version:
4.8.3Server
In Python with python-socketio 5.16.2 and uvicorn[standard] 0.48.0:
Socket.IO client version:
4.8.3Client
Expected behavior
The message should be transmitted, showing in the browser console (F12), and the transport not disconnected.
Platform:
Additional context
The issue does not happen via CDN: