# AI Agent 系统安全评审

- **评审日期**：2024-xx-xx  
- **评审范围**：当前开源仓库中的 CLI/Web 入口（`main.py`、`web_server.py`）、核心模块（`core/`, `modules/`）、配置（`config/`）、静态前端（`static/`）及数据目录（`data/`, `users/`）。  
- **评审目标**：识别阻碍产品化落地的安全缺口，明确优先级与改进路径，作为后续全面加固（尤其是“终端隔离 + 多租户环境”）的依据。

---

## 1. 系统与数据现状

### 1.1 主要角色 & 组件
- **CLI 入口 (`main.py`)**：默认启动 Web 模式，直接在宿主机 `DEFAULT_PROJECT_PATH` 内读写文件。
- **Web 服务 (`web_server.py`)**：基于 Flask + Socket.IO，整合登录、文件操作、终端调度、任务工具调用，所有状态保存在单进程内存 + 本地文件夹。
- **用户与工作区 (`modules/user_manager.py`)**：账号、邀请码、工作目录全部持久化到 `./data/*.json`，未引入数据库或权限控制。
- **终端/命令执行 (`modules/terminal_manager.py`, `modules/persistent_terminal.py`)**：调度宿主机 shell 进程，缺乏容器或 cgroup；多用户共享一台机器的真实文件系统。
- ✅ **静态前端 (`static/src/`, `static/dist/`)**：Vite + Vue 3 + Pinia 工程，`static/index.html` 只负责挂载点与全局脚本，构建产物位于 `static/dist/assets/main.{js,css}`；旧版 `app.js`/单文件脚本已迁移到 `static/old_version_backup/` 仅作对照。

### 1.3 第一阶段整改进展
- ✅ **Secrets 与配置**：所有 API key/账号信息已迁移至 `.env`，`config/__init__.py` 启动时自动加载并校验，仓库不再存在明文 key。
- ✅ **终端容器化**：实时终端与 `run_command/run_python` 默认运行在 `my-agent-shell` Docker 容器中，配额为 0.5 vCPU / 1GB 内存，项目目录通过卷挂载；宿主机仅负责持久化。
- ✅ **资源与并发控制**：新增 `PROJECT_MAX_STORAGE_MB`、`MAX_ACTIVE_USER_CONTAINERS` 等限制，写入前会进行配额检查，活跃用户达到上限时提供 `resource_busy` 页面提示。
- ✅ **系统提示**：模型接收的环境信息仅包含容器挂载路径与资源上限，不再暴露宿主机真实路径。

### 1.4 第二阶段增量成果
- ✅ **单用户-单容器 + 文件代理**：每次登录都会启动专属容器（`modules/user_container_manager.py`），CLI/Web 终端、`run_command`、FileManager 读写都通过容器代理完成，宿主机只负责挂载与备份。
- ✅ **容器监控与前端可视化**：`modules/container_monitor.py` 定期采集 `docker stats`/`inspect`，UI 用量面板实时展示 CPU/内存/网络速率与磁盘配额，让管理员能快速审计资源。
- ✅ **联网配置与镜像补强**：Dockerfile 新增 `iputils-ping`，`.env` 默认启用 `bridge` 网络，确保容器在受控环境下具备最小联网能力。

### 1.2 关键数据资产
| 资产 | 存储位置 | 备注 |
| --- | --- | --- |
| 模型/API 密钥 | `config/api.py`, 环境变量（未来） | 目前以明文写在仓库 |
| 管理员凭据 | `config/auth.py` | 包含固定用户名与 PBKDF2 哈希 |
| 用户账号/工作区索引 | `data/users.json`, `data/invite_codes.json`, `users/<uid>/` | JSON 文件无加密、无访问控制 |
| 对话与工具日志 | `data/conversations/*`, `logs/` | 包含终端输出、上传文件、任务上下文 |
| 用户上传文件 | `users/<uid>/project/user_upload` | 与终端共享同一路径 |

---

## 2. 攻击面概览
- **HTTP API**：Flask 路由与 REST 接口缺乏 CSRF、防爆破、速率限制，`CORS(app)` 与 `cors_allowed_origins="*"` 允许任意来源发起请求。
- **WebSocket/Socket.IO**：所有事件透过会话 cookie 鉴权，没有额外的 token 或设备指纹，连接转发逻辑在内存字典 `connection_users` 中维护。
- **文件上传/下载**：`/api/upload`、`/api/gui/files/upload` 接受任意类型文件，未做恶意内容扫描，仅依赖 `MAX_UPLOAD_SIZE=50MB`。
- **终端命令执行**：浏览器或 API 调用可直接在宿主机 shell 运行命令，代码运行结果与项目文件落在真实文件系统。
- **配置与日志**：所有 secrets、日志、备份位于仓库根目录，可被具备 shell 访问权的任意人读取。

---

## 3. 主要安全发现（按严重度排序）

| # | 严重度 | 问题 & 证据 | 影响 | 建议 |
| --- | --- | --- | --- | --- |
| 1 | Critical | ✅ **执行环境隔离就绪**：实时终端、`run_command` 与 FileManager 统统绑定用户专属容器，`modules/container_file_proxy.py` 保证写入只发生在 `/workspace`，宿主机仅承载挂载目录。 | Web 用户仅能访问自己容器内的文件/进程；若容器崩溃可在宿主机安全回收。 | 持续关注容器逃逸与 runtime 补丁，下一步考虑 rootless Docker / gVisor 进一步降低宿主暴露面。 |
| 2 | Critical | **明文 API Key / Secret**：`config/api.py:3-25` 存在硬编码模型 key，`config/auth.py:1-7` 暴露管理员用户名 + 哈希。 | 仓库一旦共享即泄漏密钥；攻击者可伪造管理员账户或重放 API 请求。 | 将所有 secrets 挪到环境变量 / Secret Manager，删除仓库中的明文；在启动时校验缺省值并阻止运行。 |
| 3 | High | **Flask SECRET_KEY 固定且公开**：`web_server.py:54-58` 将 `SECRET_KEY='your-secret-key-here'` 写死，且默认启用 `CORS(*)`。 | 攻击者可伪造 session cookie、冒充任意用户、解密/篡改会话。 | 将 SECRET_KEY 存储于环境变量，启用 `SESSION_COOKIE_SECURE/HTTPONLY/SAMESITE`，并限制 CORS 源。 |
| 4 | High | ✅ **鉴权与速率限制补强**：登录/注册/文件等敏感接口统一接入速率限制与失败计数（按 IP/用户维度），Socket.IO 握手改为一次性 token + Session。 | 暴力破解和凭证滥用的窗口被显著压缩，WebSocket 不再能单靠 Cookie 劫持。 | 下一步考虑加入 CAPTCHA/MFA、失败告警以及对 CLI API 的 token 鉴权。 |
| 5 | High | ✅ **多租户容器化 + 读写代理**：UserManager 登录即创建独立容器，FileManager 通过容器内脚本执行 create/read/write/modify，宿主机不再直接接触用户代码。 | 横向越权面大幅收窄：除非容器逃逸，否则无法读写他人目录。 | 下一步需在 API 层加上 workspace ACL 与审计日志，防止管理员 session 滥用。 |
| 6 | Medium | **用户与会话数据存储在本地 JSON**：`modules/user_manager.py:167-195` 将账号、密码哈希、邀请码写入 `data/users.json`，没有备份策略、并发安全或加密。 | 易被本地用户读取/篡改；当并发写入时有数据损坏风险，也无法满足审计/恢复。 | 引入关系型数据库或托管身份服务；对敏感字段做透明加密，提供备份与迁移策略。 |
| 7 | Medium | ✅ **CSRF + 安全头**：所有写操作统一校验 `X-CSRF-Token`（匿名令牌 API + fetch 包装），并启用 `SameSite/HttpOnly/Secure` Cookie 与基础安全响应头。 | 浏览器无法再被第三方站点诱导执行写操作，Cookie 也具备最小暴露。 | 仍需结合 CSP/Referer 限制和子域隔离，防止潜在的 XSS 复合攻击。 |
| 8 | Medium | ✅ **文件上传隔离 + 扫描**：`modules/upload_security.py` 将上传落地到 `.upload_quarantine/<用户>`，先校验后缀/大小，再调用 ClamAV 扫描；通过后才复制到工作区，前端 toast 提示审核结果。 | 恶意文件无法直接进入工作区，命中文件会被拦截并记录审计日志。 | 后续可扩展 MIME/解压炸弹检测与后台审核面板，提高可观测性。 |
| 9 | Medium | **日志/终端信息缺乏审计与脱敏**：`logs/`、`data/conversations/` 中保留所有指令和模型输出，没有访问控制。 | 可能泄漏用户代码、密钥；出现安全事件时也很难追踪。 | 将日志写入集中式系统（ELK/ClickHouse），对敏感字段脱敏，建立查询与保留策略。 |
| 10 | Low | **配置默认值缺乏环境检测**：如 `DEFAULT_PROJECT_PATH="./project"`、`MAX_UPLOAD_SIZE=50MB` 固定写入；`main.py` 未检查当前用户权限。 | 误配置可能导致数据写入到未知磁盘或权限不足引发异常。 | 在启动阶段校验运行环境（磁盘权限、必需目录、环境变量），并提供友好报错与文档。 |

---

## 4. 优先修复路线（建议迭代 0 → 2）

1. **密钥治理与配置基线**  
   - 移除所有硬编码 secrets，提供 `.env.example`；启动脚本在缺失密钥时直接失败。  
   - 配置 Flask session 安全选项、限制 CORS 来源、添加基本安全 HTTP 头。  

2. **执行环境隔离 PoC**  
   - 选定容器技术（Docker/LXC/Firecracker），将 `TerminalManager` 改造为“容器调度器”，所有命令走容器内的 `/workspace` 目录。  
   - 引入任务代理服务（FastAPI + Celery/RabbitMQ）分离 Web API 与执行层，给每个用户/对话绑定独立容器生命周期。  

3. **身份/鉴权与数据持久化升级**  
   - 使用数据库管理用户、会话与权限，加入账号锁定、审计日志、API rate limit。  
   - 为日志、对话、上传文件建立访问控制与加密策略，提供备份/恢复。  

4. **安全运维体系**  
   - 落地集中日志、异常告警、指标监控；在部署脚本中加入 CIS/Baseline 检查。  
   - 定期执行依赖扫描（pip-audit/Dependabot）、容器镜像漏洞检测，并把密钥轮换流程流程化。

---

## 5. 后续工作与协作建议
- 建议在 `docs/` 中维护《安全基线》《运维手册》《应急预案》，并在 PR 模板中新增安全检查项。  
- 组建最小安全清单：每次上线前确认终端隔离、密钥、日志、鉴权、备份五项指标均处于“通过”状态。  
- 在完成 PoC 后，再讨论“前端重写、UI 组件化”等体验向任务，确保基础安全能力可复用到后续版本。

> 本文档会随着重构推进持续更新；若需深入某一条风险（如容器隔离方案、密钥管理流程），可另开文档展开细化设计。
