Files
blackbird/docs/security/aibox_SECURITY_AUDIT_20260801.md
T
qing 5fbe3ed5e4 docs(security): 更新全部模块审计报告,添加代码验证记录
逐模块对照实际代码验证审计报告中的问题修复状态,添加代码验证记录、逐条验证结果、修复率统计。合并aibox两份审计报告,删除重复文件。修复率:confs 61% > dnfs 60% > ai_review 50% > smtp 37.5% > db 33% > core 12.5% > gateway 12.5% > pymsg 6.25% > static 5% > captcha/aibox/BotOps 0%
2026-08-03 14:12:45 +08:00

205 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# aibox 模块安全审计报告
**审计日期**: 2026-08-01
**审计范围**: `aibox.py`、`skills/`、WebSocket 服务、任务调度器、数据库
**代码版本**: dev_qing 分支
---
## 代码验证记录
**验证日期**: 2026-08-03
**验证方式**: 逐条对照审计报告与当前代码(`aibox.py` 358KB,关键区域 L3600-3850, L6540-6740, L7071-7160, L8410-8470)
### 验证结果汇总
| 等级 | 总数 | 已修复 | 部分修复 | 未修复 | 修复率 |
|------|------|--------|----------|--------|--------|
| P0 | 2 | 0 | 0 | 2 | 0% |
| P1 | 4 | 0 | 0 | 4 | 0% |
| P2 | 6 | 0 | 0 | 6 | 0% |
| P3 | 5 | 0 | 0 | 5 | 0% |
| **合计** | **17** | **0** | **0** | **17** | **0%** |
> **注意**: 原始审计报告(简化版)将 P0-1/P0-2 标记为"已修复",经代码验证实际均未修复。
### 逐条验证
| 编号 | 状态 | 代码位置 | 验证说明 |
|------|------|----------|----------|
| P0-1 | ❌ | L3664, L3751, L6553, L6715 | `shell=True` 仍在 4 处使用,命令注入未修复 |
| P0-2 | ❌ | L1177, L8423-8426 | 默认 `localhost:8765`(非 `127.0.0.1`),`handle_connection` 无任何认证 |
| P1-1 | ❌ | L3943-3957, L5999-6017 | `check_path_safety` 仅检查文件大小,无 `realpath` 前缀校验 |
| P1-2 | ❌ | L2037, L7365 | `requests.post` 无内网 IP 过滤 |
| P1-3 | ❌ | 系统提示词 | 工具完整参数 schema 仍暴露 |
| P1-4 | ❌ | L8326 | `api_key=None` 默认值,启动时未校验 |
| P2-1 | ❌ | L7823 | `message_count` 仅统计未限流 |
| P2-2 | ⚠️ | L1582, L3580 | `TOOL_MAX_RESULT_LENGTH=100000`,`MAX_OUTPUT_BYTES=1MB`(有缓解) |
| P2-3 | ❌ | SQLite | 对话仍明文存储 |
| P2-4 | ❌ | - | 临时文件清理未验证 |
| P2-5 | ❌ | L4191-4251 | 技能 `.sh`/`.py` 直接加载执行 |
| P2-6 | ❌ | - | 日志脱敏未验证 |
| P3-1 | ❌ | - | 递归深度仍为 `max_recursion_depth=10` |
| P3-2 | ❌ | - | 对话压缩可能丢失工具调用上下文 |
| P3-3 | ❌ | - | 多连接竞争条件未加固 |
| P3-4 | ⚠️ | L1177 | 默认 `localhost`(非 `0.0.0.0` 也非 `127.0.0.1`) |
| P3-5 | ❌ | - | 优雅关闭未验证 |
---
## 🔴 P0 — 严重问题
### P0-1: 命令注入漏洞 ❌
- **位置**: `aibox.py` L3664, L3751, L6553, L6715
- **风险描述**:
```python
# 当前危险实现(4处)
subprocess.Popen(command, shell=True, ...)
subprocess.run(command, shell=True, capture_output=True, text=True)
```
使用 `shell=True` 并通过 f-string 直接拼接用户输入的命令,攻击者(或被诱导的AI)可以构造恶意命令执行任意系统操作:
- `rm -rf /` 删除所有文件
- `cat /etc/shadow` 窃取密码哈希
- 反弹 shell 完全控制系统
- **已有缓解**: `MAX_OUTPUT_BYTES = 1MB` 限制输出大小(L3580)
- **修复建议**:
1. 禁止 `shell=True`,改用 `subprocess.run([...], shell=False)`
2. 将命令拆分为参数列表,使用 `shlex.split()` 解析
3. 添加命令白名单机制,只允许执行预定义的安全命令
4. 限制工作目录,禁止在敏感目录执行命令
### P0-2: WebSocket 无认证机制 ❌
- **位置**: `aibox.py` L8423-8426, L1177
- **风险描述**:
- WebSocket 默认监听 `localhost:8765`(已从 `0.0.0.0` 收敛,但仍非 `127.0.0.1`)
- `handle_connection` 无任何 token、密码或 session 认证
- 任何人连接后可无限制使用 DeepSeek API(消耗费用)
- 结合工具调用漏洞可直接控制服务器
- **修复建议**:
1. **短期方案**: 将监听地址改为 `127.0.0.1`,通过 gateway/WAF 统一接入并认证
2. **长期方案**: WebSocket 握手阶段校验 token(支持 URL query 参数或 Authorization header)
3. 参考现有 gateway 的认证机制(RSA签名/PBKDF2)做统一接入
4. 添加 Origin 校验,防止跨站 WebSocket 劫持
---
## 🟠 P1 — 高危问题
### P1-1: 路径遍历风险 ❌
- **位置**: `aibox.py` L3943-3957(基类), L5999-6017(FileToolBase)
- **风险描述**:
- `check_path_safety` 仅检查文件大小,未做 `realpath` 前缀校验
- 通过 `../../etc/passwd` 可读取系统敏感文件
- 写入工具可覆盖任意文件,破坏系统或植入后门
- **修复建议**:
- 定义允许访问的根目录(如 `~/.aibox/workspace/`)
- 统一实现 `safe_path()` 函数,`realpath` 解析后校验前缀,确保在允许目录内
- 对写入操作添加额外确认或权限控制
### P1-2: SSRF 漏洞风险 ❌
- **位置**: `aibox.py` L2037, L7365
- **风险描述**:
- `requests.post` 未限制可访问的 IP 范围
- 可访问内网服务:`http://127.0.0.1:8443`(gateway)、`http://10.x.x.x` 等
- 可访问云服务商元数据接口(如 `http://169.254.169.254/` 获取临时凭证)
- **修复建议**:
- 禁止访问内网 IP 段:`127.0.0.0/8`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `169.254.0.0/16`
- 禁止访问非 HTTP/HTTPS 协议
- 跟随重定向时重新校验目标地址
### P1-3: 敏感信息暴露 ❌
- **位置**: 系统提示词构建 / `tools_info`
- **风险描述**:
- 系统提示词中包含所有工具的完整参数 schema
- 错误响应可能返回栈追踪等内部信息
- 工具返回的原始错误信息可能泄露路径、代码结构
- **修复建议**:
- 精简工具描述,只暴露必要信息
- 对外返回的错误信息做脱敏处理,仅返回通用错误提示
- 详细错误只记录在服务端日志
### P1-4: API Key 配置校验缺失 ❌
- **位置**: `aibox.py` L8326
- **风险描述**:
- `api_key=None` 默认值,启动时未校验 `DEEPSEEK_API_KEY`
- 可能因配置错误导致空 Key 或使用默认无效 Key
- 没有 Key 时直接启动失败或行为异常
- **修复建议**:
- 启动时强制校验 `DEEPSEEK_API_KEY` 配置
- 未配置有效 Key 时直接拒绝启动并给出明确提示
- 日志中不要打印完整 API Key
---
## 🟡 P2 — 中危问题
| # | 问题 | 位置 | 风险 | 建议 |
|---|------|------|------|------|
| P2-1 | 无请求频率限制 | L7823 | 恶意用户可高频发送请求,导致 API 费用暴涨 | 添加 per-connection 消息频率限制(如每分钟 30 轮) |
| P2-2 | 工具调用结果大小限制 | L1582, L3580 | 已有 `TOOL_MAX_RESULT_LENGTH=100000` 和 `MAX_OUTPUT_BYTES=1MB`,但大文件读取仍可能超限 | 统一工具输出限制,超出截断并提示 |
| P2-3 | 对话历史明文存储 | SQLite | 聊天记录含敏感信息,明文存储易被窃取 | 加密存储或限制数据库文件权限 |
| P2-4 | 临时文件清理不彻底 | 代码执行工具 | 执行代码生成的临时文件未清理,占用磁盘或泄露信息 | 使用 `tempfile.TemporaryDirectory()` 自动清理 |
| P2-5 | 技能加载无沙箱 | L4191-4251 | 可执行技能(`.sh`/`.py`)直接运行,无隔离或校验 | 技能目录权限校验,仅加载可信来源,或沙箱执行 |
| P2-6 | 日志未脱敏 | Logger | API 请求/响应、对话内容可能写入日志,泄露敏感信息 | 日志中脱敏 API Key、密码等敏感字段 |
---
## 🟢 P3 — 低危/健壮性问题
| # | 问题 | 说明 |
|---|------|------|
| P3-1 | 递归深度防护不足 | `max_recursion_depth=10`,复杂工具链仍可能导致栈溢出,建议改用迭代 |
| P3-2 | 对话压缩可能丢失上下文 | 简单截断早期消息,可能丢失工具调用上下文,建议保留工具调用/结果对 |
| P3-3 | 多线程竞争风险 | `messages`/`tools` 等状态在多连接下可能有竞争条件 |
| P3-4 | 监听地址非 `127.0.0.1` | 默认 `localhost`(已从 `0.0.0.0` 收敛,但建议改为 `127.0.0.1`) |
| P3-5 | 缺少优雅关闭 | 关闭时未确保消息队列刷新、数据库连接正确关闭 |
---
## ✅ 已有安全机制
1. ✅ **工具结果清洗**: `_sanitize_tool_result` 过滤控制字符(L7071-7087)
2. ✅ **OOM 防护**: `MAX_OUTPUT_BYTES = 1MB`,`_read_with_limit` 截断输出(L3580-3630)
3. ✅ **工具结果大小限制**: `TOOL_MAX_RESULT_LENGTH=100000` 截断(L1582, L7153-7155)
4. ✅ **三层中断机制**: `_is_cancelled` + `create_task` 异步解耦 + 连接关闭取消 Task(L7106, L8431, L8445)
5. ✅ **fail-closed 设计**: 工具异常时安全返回错误信息,不暴露内部状态(L7127-7130)
6. ✅ **对话自动压缩**: Token/消息数超限自动压缩,防止上下文无限增长(L1700-1740)
7. ✅ **消息回滚机制**: API 失败时 `_rollback_messages` 回滚对话,防止坏消息污染历史
8. ✅ **提示词软约束**: 系统提示词中明确要求 AI 不要执行危险命令(需配合代码层面硬约束)
---
## 🛠️ 修复路线图
### 第一阶段(立即):P0
- [ ] 移除所有 `shell=True`,改用参数列表 `subprocess.run([...])`
- [ ] WebSocket 绑定 `127.0.0.1`,添加 token 认证或通过 gateway 统一接入
### 第二阶段(近期):P1
- [ ] `check_path_safety` 添加 `realpath` 前缀校验,限制工作目录
- [ ] 网络请求添加 SSRF 防护(内网 IP 黑名单)
- [ ] 启动时强制校验 `DEEPSEEK_API_KEY`
- [ ] 错误信息脱敏,详细错误仅记录服务端日志
### 第三阶段(后续版本):P2/P3
- [ ] 添加 per-connection 消息频率限制
- [ ] 日志脱敏、对话加密存储
- [ ] 临时文件自动清理、技能加载沙箱化
- [ ] 多线程安全加固、优雅关闭
---
**审计完成时间**: 2026-08-01
**代码验证时间**: 2026-08-03