Um usuário de baixa prioridade autestificado pode executar o interpretador arbitrário de código Python e ferramentas dentro da sessão autêntica do usuário **outro**. O chamador de eventos Socket.IO (`get_event_call`) entrega os eventos `execute:python` / `execute:tool` a um ** fornecedo pelo cliente** `session_id` após apenas verificar se a sessão está conectada, nunca que pertence ao requerente. Combinado com `ydoc:document:join`, que expõe os ids do socket ao vivo de todos na sala de colaboração de uma nota compartilhada para qualquer participante de acesso à leitura, um atacante pode alvoar a sessão de uma vítima e executar código/ ferramentas do atacante/escolhido no contexto do navegador da vítima. Quando a vítima é um administrador, esse contexto seqüestrado atinge a API Funções somente do administrador, cuja fonte é executada lado servidor, dando execução de código remoto como processo servidor (root no contêiner padrão). ## Componente afetado. - `backend/open_webui/socket/main.py` — `get_event_call()` / `__event_caller__` - `backend/open_webui/main.py` — metadados de conclusão de chat (`session_id` tirados do corpo de solicitação) O evento-chamadar rotas para um identificador de sessão controlado pelo chamador sem cheque de propriedade:.

```python # backend/open_webui/socket/main.py — get_event_call() async def __event_caller__(event_data): session_id = request_info['session_id'] se session_id não estiver em SESSION_POOL: # só verifica que a sessão está conectada devolve {'error': 'Sexão cliente desconectada'. '} devolver aguarde sio.call('events', {...}, to=session_id,...) # entregue para aquele sid ```` `session_id` origina- se do corpo de solicitação e nunca é validado contra o usuário autenticado: ```python # backend/open_webui/main.py metadados = { 'user_id': user.id, # derivado do servidor (confiável) 'session_id': form_data.pop('session_id', Nenhum), # controlado pelo cliente... } ```.

`SESSION_POOL[session_id]` é o registro do usuário de quem possui aquele socket. Como o usuário verifica apenas a adesão (`em SESSION_POOL`), um pedido carregando o `session_id` de outro usuário faz com que `execute:python` / `execute:tool` seja entregue ao navegador do outro usuário. - `execute:python` / `execute:tool` são emitidos a partir do interpreter de código e caminhos de chamada de ferramentas (`utils/middleware.py`, `tools/builtin.py`), todos os encaminhados através de `get_event_call`. - O `session_id' da vítima é revelado a qualquer participante de acesso à leitura de uma nota compartilhada via `ydoc:document:join`. - `POST /api/v 1 O /chat/completions` requer apenas `get_verified_user` (o papel padrão do usuário). O atacante usa sua própria conta e uma conexão direta/ modelo que controla para escolher a carga útil.

- **Qualquer vítima:** autor arbitrário de código Python e execução de ferramentas na sessão autenticada da vítima — o atacante atua com a identidade e origem da vítima (compromesso de sessão/conta completa). - **Vítima de administração:** o contexto de administração sequestrado atinge ` POST / api/v 1 /functions/create`, cuja fonte é `exec()`'d do lado do servidor → execução de código remoto como processo do servidor (root no contêiner padrão). A API Funções é a execução de código do administrador; a vulnerabilidade aqui é a entrega cruzada de usuários que permite que um atacante dirija a sessão de outro usuário — incluindo a de um administrador — para ela. O primitivo é um compromisso de sessão completa mesmo contra vítimas não- administradoras.

O "exploit.py" do repórter reproduzido em `ghcr.io/ open-webui/ open-webui: 0.9.6 ` e uma compilação do ` v 0.9.6 ` tag, confirmando RCE fora de banda do lado cego do servidor (callback retorna `uid= 0 (root)`), usando apenas uma conta de ` usuário` de baixa prioridade que compartilhou uma nota com uma vítima de administrador. Precondições: o intérprete de código ativado; o atacante compartilha uma nota com a vítima; a vítima a abre enquanto está online; a vítima de administrador é necessária para o servidor RCE. `get_event_call` deve verificar que a sessão de alvo pertence ao usuário requerente antes de entregar, não apenas que ele esteja conectado:.

``` sessões de python = SESSION_POOL.get(session_id) se a sessão é Nenhuma ou session.get('id')!= request_info.get('user_id'): retorna {' erro': 'Sessão cliente desconectada'} ```` ` user_id` no pedido de metadados é derivado do servidor do usuário autenticado, por isso é confiável. Restringindo `ydoc:document:join` para que não revele os ids do socket de outros participantes é recomendado como defesa em profundidade.

Afetado / Patched. - Afetado: `< 0.10.0 ` (última versão afetada) 0.9.6 ) - Patched: v 0.10.0. `get_event_call` verifica agora que a sessão de destino pertence ao usuário requerente antes de entregar (`session is Nole or session.get('id')!= request_info.get('user_id')`), usando o servidor derivado `user_id' dos metadados da solicitação. A restrição recomendada `ydoc:document:join` sid- disclosure é de defesa em profundidade e independente desta correção; a verificação da propriedade fecha a entrega entre usuários, independentemente de se o sid da vítima é conhecido. Registro de aconselhamento: GHSA- 74 h 3 - cxq 7 - vc 5 q. Identificadores relacionados: CVE- 2026 - 59216.

Tempo: GitHub Advisory Database publicou este registro em 2026 - 07 - 24 T 17: 01: 53.000 Z e lista a sua última modificação como 2026 - 07 - 24 T 17: 01: 53.000 Z. Severidade: ALTAMENTE. Dados de pontuação publicados: CVSS_V 3: CVSS: 3.1 /AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:N.

Informações sobre software e versão afetadas: Pacote PyPI open-webui — ECOSISTEM: introduzido 0, corrigido 0.10.0. Classificação e evidência: identificadores de fraqueza CWE- 200, CWE- 639, CWE- 862, CWE- 94. O registro contém 6 suporte de referências nestes tipos: WEB, AVISO, EMBALAGAMENTO.