Componente Afectado
Cache Redis de servidores de herramientas y terminales:
backend/open_webui/utils/tools.py(línea 841, SET de tool_servers)backend/open_webui/utils/tools.py(línea 850, GET de tool_servers)backend/open_webui/utils/tools.py(línea 976, SET de terminal_servers)backend/open_webui/utils/tools.py(línea 986, GET de terminal_servers)
Versiones Afectadas
Rama principal actual (commit 6fdd19bf1) y probablemente todas las versiones desde que se introdujo la cache Redis para servidores de herramientas y terminales.
Descripción
Open WebUI utiliza un REDIS_KEY_PREFIX (por defecto open-webui) para crear espacios de nombres en las claves Redis, permitiendo que múltiples instancias compartan de forma segura un backend Redis único. Todas las claves Redis en el código base utilizan este prefijo, excepto las claves tool_servers y terminal_servers en utils/tools.py, que usan nombres de clave sin prefijo.
Cuando dos o más instancias de Open WebUI comparten una base de datos Redis (un patrón de despliegue soportado y documentado, por ejemplo, para despliegues multi-región, configuraciones blue-green, o topologías de clúster), las claves sin prefijo colisionan. Un administrador en la Instancia A escribiendo en tool_servers sobrescribe el valor leído por la Instancia B, causando que los usuarios de la Instancia B reciban la configuración de servidor de herramientas de la Instancia A.
python
utils/tools.py — claves sin prefijo (problema)
await request.app.state.redis.set('tool_servers', ...) # línea 841 json.loads(await request.app.state.redis.get('tool_servers')) # línea 850 await request.app.state.redis.set('terminal_servers', ...) # línea 976 json.loads(await request.app.state.redis.get('terminal_servers')) # línea 986
Todas las demás claves Redis en el código base — con prefijo (patrón correcto)
f'{REDIS_KEY_PREFIX}:auth:token:{jti}:revoked' f'{REDIS_KEY_PREFIX}:ratelimit:{email}:{bucket}' f'{REDIS_KEY_PREFIX}:tasks:commands'
Escenario de Ataque
Dos instancias de Open WebUI (A y B) comparten un backend Redis, un despliegue soportado para configuraciones multi-región, despliegues blue-green, o hot-standby. Ambas instancias tienen sus propias cuentas de administrador; el Redis compartido fue elegido para manejo coordinado de sesiones, limitación de velocidad y gestión de tareas.
- El atacante es un administrador en la Instancia A (un administrador legítimamente aprovisionado, o uno que escaló a través de cualquier ruta disponible incluyendo los hallazgos de contraseña vacía LDAP o rol de administrador obsoleto).
- El atacante en la Instancia A configura un servidor de herramientas apuntando a
https://attacker-controlled.example.com/openapi.json. Esto activautils/tools.py:841para escribir la nueva lista de servidores de herramientas bajo la clave sin prefijotool_servers. - Los usuarios de la Instancia B consultan herramientas. La Instancia B lee desde
tool_servers(línea 850) y obtiene la lista envenenada de la Instancia A, que ahora incluye el servidor del atacante junto con o en lugar de los servidores de herramientas legítimos de la Instancia B. - Los usuarios de la Instancia B invocan herramientas a través del contexto del modelo. El servidor del atacante recibe cargas útiles de llamadas de herramientas que contienen: contenido de chat, identidad del usuario, tokens OAuth con alcance al servidor de herramientas (si el usuario ha vinculado su cuenta externa), y contexto de conversación en curso.
- El servidor del atacante devuelve respuestas de herramientas arbitrarias, que se alimentan de vuelta al contexto LLM de la Instancia B como "salida de herramienta confiable", habilitando inyección de prompts, entrega de desinformación y cascadas adicionales de exfiltración de datos.
El mismo envenenamiento entre instancias se aplica a terminal_servers.
Impacto
- Envenenamiento de cache entre instancias: un administrador en una instancia afecta a todos los usuarios de otra instancia que comparte el backend Redis
- Exfiltración de datos: las cargas útiles de llamadas de herramientas contienen contenido de chat e identidad del usuario, entregadas al servidor del atacante
- Entrega de inyección de prompts: las respuestas de herramientas devueltas por el atacante entran al contexto LLM de la instancia víctima como datos confiables
- Socava la garantía de aislamiento multi-instancia que
REDIS_KEY_PREFIXfue introducido para proporcionar - Modo de falla silenciosa: no se genera error; la instancia víctima ve una entrada de cache válida y firmada y no tiene forma de detectar que vino de una instancia diferente
Precondiciones
- Múltiples instancias de Open WebUI comparten un único backend Redis (un despliegue soportado y documentado)
- El atacante tiene acceso de administrador en una de las instancias (o escala a administrador a través de cualquier ruta disponible)
