[Security] Unauthenticated Socket.IO /trape namespace allows room hijack and command injection
Author: GalaxyncCreated Jul 18, 2026Updated Jul 18, 2026
Severity: CRITICAL
Affected file: core/sockets.py:42-58
Description
The Socket.IO handlers registered on the /trape namespace perform no authentication or authorization:
join(sockets.py:42) callsjoin_room(message['room'])for any client-supplied room name. Victim sessions are keyed by theirvId(a short, 5-character token, seecore/user.py:76/core/utils.py:92), so any client can join any victim's room.my_room_event(sockets.py:50) takes attacker-controlledmessage['data']['type']andmessage['data']['message'], maps the type throughattacks_hook_message(core/user_objects.py:101-111, values includeredirect,execute,jscode,jsscript,alert,talk), and re-emits it viaemit('my_response', ..., room=message['room'])to that room — with no check that the sender is the authenticated operator.
These events are meant to be operator-only attack/command actions against tracked victims, but nothing enforces that on the server.
Reproduction
- Connect a Socket.IO client to
ws://target:port/socket.iowith namespace/trape(no credentials needed). - Emit
joinwith{"room": "<victim_vId>"}— the vId can be enumerated via the unauthenticated/get_dataendpoint or observed on the wire. - Emit
my_room_eventwith{"room": "<victim_vId>", "data": {"type": "jsscript", "message": "<payload>"}}to inject arbitrary JavaScript into that victim's browser, or{"type": "redirect", "message": "http://evil.example"}to redirect them. - Alternatively, just listen for
my_responsebroadcasts to passively intercept operator/victim traffic for any room.
Impact
Any network client that can reach the Socket.IO endpoint can hijack the operator's victim sessions, inject scripts, or eavesdrop on the operator-victim command channel.
Suggested remediation
- Require an authenticated session (established after
/login) before allowingjoin/my_room_event. - Validate that the room name a client asks to join actually belongs to a session it owns or that the caller is the authenticated operator.
Source: jofpin/trape