Alta

Open WebUI: Cross-user code-interpreter and tool execution via unvalidated Socket.IO event-caller session_id

  • Publicada: 24.07.2026
  • Actualizado: 11.10.2026 14:19

Summary

An authenticated low-privilege user can execute arbitrary code-interpreter Python and tools inside another user's authenticated session. The Socket.IO event-caller (get_event_call) delivers execute:python / execute:tool events to a client-supplied session_id after only checking that the session is connected, never that it belongs to the requester. Combined with ydoc:document:join, which exposes the live socket ids of everyone in a shared note's collaboration room to any read-access participant, an attacker can target a victim's session and run attacker-chosen code/tools in the victim's browser context. When the victim is an administrator, that hijacked context reaches the admin-only Functions API, whose source is executed server-side, yielding remote code execution as the server process (root in the default container).

Affected component

  • backend/open_webui/socket/main.py — get_event_call() / __event_caller__
  • backend/open_webui/main.py — chat-completion metadata (session_id taken from the request body)

Root cause

The event-caller routes to a caller-controlled session id with no ownership check:

python
# backend/open_webui/socket/main.py — get_event_call()
async def __event_caller__(event_data):
    session_id = request_info['session_id']
    if session_id not in SESSION_POOL:                 # only checks the session is connected
        return {'error': 'Client session disconnected.'}
    return await sio.call('events', {...}, to=session_id, ...)   # delivered to that sid

session_id originates from the request body and is never validated against the authenticated user:

python
# backend/open_webui/main.py
metadata = {
    'user_id': user.id,                               # server-derived (trustworthy)
    'session_id': form_data.pop('session_id', None),  # client-controlled
    ...
}

SESSION_POOL[session_id] is the user record of whoever owns that socket. Because the caller checks only membership (in SESSION_POOL), a request carrying another user's session_id causes execute:python / execute:tool to be delivered to that other user's browser.

Reachability

  • execute:python / execute:tool are emitted from the code-interpreter and tool-call paths (utils/middleware.py, tools/builtin.py), all routed through get_event_call.
  • The victim's live session_id is disclosed to any read-access participant of a shared note via ydoc:document:join.
  • POST /api/v1/chat/completions requires only get_verified_user (the default user role). The attacker uses their own account and a model / Direct Connection they control to choose the payload.

Impact

  • Any victim: arbitrary code-interpreter Python and tool execution in the victim's authenticated session — the attacker acts with the victim's identity and origin (full session/account compromise).
  • Admin victim: the hijacked admin context reaches POST /api/v1/functions/create, whose source is exec()'d server-side → remote code execution as the server process (root in the default container).

The Functions API is intended administrator code-execution; the vulnerability here is the cross-user delivery that lets an attacker drive another user's session — including an admin's — into it. The primitive is a full session compromise even against non-admin victims.

Proof of Concept

The reporter's exploit.py reproduced on ghcr.io/open-webui/open-webui:0.9.6 and a build of the v0.9.6 tag, confirming blind server-side RCE out-of-band (callback returns uid=0(root)), using only a low-privilege user account that shared a note with an admin victim. Preconditions: code interpreter enabled; attacker shares a note with the victim; victim opens it while online; admin victim required for server RCE.

Fix

get_event_call must verify the target session belongs to the requesting user before delivering, not merely that it is connected:

python
session = SESSION_POOL.get(session_id)
if session is None or session.get('id') != request_info.get('user_id'):
    return {'error': 'Client session disconnected.'}

user_id in the request metadata is server-derived from the authenticated user, so it is trustworthy. Restricting ydoc:document:join so it does not disclose other participants' socket ids is recommended as defence-in-depth.

Affected / Patched

  • Affected: < 0.10.0 (last affected release 0.9.6)
  • Patched: v0.10.0. get_event_call now verifies the target session belongs to the requesting user before delivering (session is None or session.get('id') != request_info.get('user_id')), using the server-derived user_id from the request metadata. The recommended ydoc:document:join sid-disclosure restriction is defence-in-depth and independent of this fix; the ownership check closes the cross-user delivery regardless of whether the victim's sid is known.

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Python (PyPI) open-webui < 0.10.0 0.10.0

Referencias

Puntuación CVSS 7.7/10
Vector CVSS
CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:N
Debilidad (CWE)
CWE-200, CWE-639, CWE-862, CWE-94
Plataforma
Python (PyPI)
Paquete
open-webui
Publicada
24.07.2026
Actualizado
11.10.2026 14:19

Fuentes y licencias

OSV / GitHub Advisory Database - PYSEC-2026-3592 - PyPA Advisory Database; CC BY 4.0

OSV / GitHub Advisory Database - GHSA-74h3-cxq7-vc5q - CC BY 4.0

Historial de vulnerabilidades: open-webui

Todas las vulnerabilidades publicadas de este paquete (Python (PyPI)), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Todas (161) en el archivo
Entradas en total
161
Primera → última
08.2024 09.2026
Sin corrección
11
Explotada en ataques
0

Distribución por gravedad

  • Crítica 1
  • Alta 77
  • Media 75
  • Baja 8

Divulgaciones por año

  1. 2024: 3
  2. 2025: 21
  3. 2026: 137
Gravedad:
  1. Alta · 7.7 CVE-2026-59221 >= 0.9.6, < 0.10.0 0.10.0
  2. Open WebUI: Cross-user code-interpreter and tool execution via unvalidated Socket.IO event-caller session_id esta entrada
    Alta · 7.7 CVE-2026-59216 < 0.10.0 0.10.0
  3. Alta · 7.3 CVE-2026-59214 < 0.10.0 0.10.0
  4. Alta · 8.7 CVE-2026-54011 < 0.9.6 0.9.6
  5. Alta · 7.1 CVE-2026-45349 < 0.9.0 0.9.0
  6. Alta · 7.7 CVE-2026-45303 < 0.6.5 0.6.5
  7. Alta · 7.1 CVE-2026-44569 < 0.6.19 0.6.19
  8. Alta · 8.1 CVE-2026-44565 < 0.6.10 0.6.10
  9. Alta · 7.3 CVE-2026-44566 < 0.1.124 0.1.124
  10. Alta · 7.3 CVE-2026-44567 < 0.1.124 0.1.124
  11. Alta · 7.3 CVE-2026-44549 < 0.8.0 0.8.0
  12. Crítica · 9.1 CVE-2026-44551 < 0.9.0 0.9.0
  13. Alta · 7.3 CVE-2026-44721 < 0.9.0 0.9.0
Mostrar más (18) Mostrando 60 de 78

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.