Files
wecom_it_smart_desk/docs/风险跟踪表.md
T

805 lines
26 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.
# IT智能服务台 — 风险跟踪表
**最后更新**: 2026-06-14 18:30
**维护人**: 宋献 + Claude 评审协作
> 📌 2026-06-14 评审新增 13 项(6 P0 + 4 P1 + 3 P2),详见第九节。
> 统计表保持 6-13 数据,**第九节有独立小计**。
---
## 一、风险总览
| 级别 | 数量 | 已处理 | 待处理 | 处理率 |
|------|------|--------|--------|--------|
| 🔴 严重 (Critical) | 4 | 4 | 0 | **100%** |
| 🟠 高 (High) | 6 | 5 | 1 | **83%** |
| 🟡 中 (Medium) | 7 | 4 | 3 | **57%** |
| 🔵 低 (Low) | 5 | 3 | 2 | **60%** |
| **合计** | **22** | **16** | **6** | **73%** |
---
## 二、严重风险 (Critical)
### CR-1`dependencies.py` 覆盖导致依赖注入链断裂
**状态**: ✅ 已验证(无需修复)
**风险级别**: 🔴 严重
**处理难度**: ⚠️ 高
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
当前的 `dependencies.py` 是完全重写的,可能缺少原始文件中的共享服务依赖注入函数。
**验证结果**
经检查,当前 `dependencies.py` 文件已包含所有必要的函数:
- `get_redis()` — Redis 连接池管理
- `dep_redis()` — Redis 客户端依赖注入
- `dep_wecom_service()` — 企微服务依赖注入
- `dep_ai_handler()` — AI 处理器依赖注入
- `dep_wingman_service()` — Wingman 服务依赖注入
- `get_shared_redis()` — 同步获取 Redis
- `get_shared_wecom_service()` — 同步获取企微服务
- `get_shared_ai_handler()` — 同步获取 AI 处理器
- `init_shared_services()` — 应用启动初始化
- `cleanup_shared_services()` — 应用关闭清理
**结论**
文件完整,无需恢复。依赖注入链正常。
---
### CR-2Token 格式不兼容导致认证混乱
**状态**: ✅ 已修复
**风险级别**: 🔴 严重
**处理难度**: ⚠️ 中
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
系统存在三种 Token 格式同时运行,可能导致认证混乱。
**修复方案**
1. `TokenService.get_user_info()` 支持三种格式读取:
- 统一格式:`user:token:{token}` → JSON 对象
- 旧格式1`employee:token:{token}` → employee_id
- 旧格式2`agent:token:{token}` → user_id
2. `TokenService.create_token()` 同时写入统一格式和旧格式:
- 根据 `login_source` 决定写入 `employee:token:``agent:token:`
3. `TokenService.switch_role()` 更新统一格式,旧格式只存储 employee_id 不需要更新
**修改文件**
- `backend/app/services/token_service.py`
---
### CR-3Portal API 使用旧认证中间件
**状态**: ✅ 已修复
**风险级别**: 🔴 严重
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
Portal API 使用 `get_current_agent` 作为认证依赖,不支持新的统一格式。
**修复方案**
1. 修改 `portal.py` 使用 `get_current_user` 替代 `get_current_agent`
2. 修改 `admin_roles.py` 使用 `get_current_user` 替代 `get_current_agent`
3. 更新所有函数签名和参数名(`agent``current_user`
4. 更新所有日志记录(`agent.user_id``current_user.employee_id`
**修改文件**
- `backend/app/api/portal.py`
- `backend/app/api/admin_roles.py`
---
### CR-4:慢启动时 Token 创建失败导致登录异常
**状态**: ✅ 已修复
**风险级别**: 🔴 严重
**处理难度**: ⚠️ 中
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
坐席登录时每次创建新的 Redis 连接,并在 finally 中关闭,可能导致连接泄漏。
**修复方案**
1. 使用共享 Redis 连接(从 `get_redis()` 获取)
2. 移除 finally 中的连接关闭代码(由连接池管理)
3. 简化异常处理逻辑
**修改文件**
- `backend/app/api/agents.py`
---
## 三、高风险 (High)
### H-6:角色映射 SQL 注入风险
**状态**: ✅ 已修复
**风险级别**: 🟠 高
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
`_get_tag_names_by_ids()` 方法直接调用企微 API,没有对返回的 `tag_names` 进行验证。
**修复方案**
1. 添加 `_validate_tag_name()` 方法验证标签名称
2. 验证规则:长度限制 50 字符,过滤禁止的特殊字符
3. 获取标签时过滤不安全的标签名称
**修改文件**
- `backend/app/services/role_mapping_service.py`
---
### H-7:角色分配权限验证不完整
**状态**: ✅ 已修复
**风险级别**: 🟠 高
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
管理员可以给任何人分配任何角色,包括自己。
**修复方案**
1. 禁止管理员给自己分配角色(assign_role 添加检查)
2. 禁止管理员撤销自己的角色(revoke_role 添加检查)
3. 操作审计日志(通过 logger.info 记录)
**修改文件**
- `backend/app/api/admin_roles.py`
---
### H-8:映射规则缺少输入验证
**状态**: ✅ 已修复
**风险级别**: 🟠 高
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
`create_mapping_rule()` 接口没有验证输入参数。
**修复方案**
1. 添加 `source_type` 枚举验证(`wecom_tag`/`ehr_position`
2. 添加 `role_name` 枚举验证(`user`/`agent`/`admin`
3. 添加 `source_value` 特殊字符过滤
4. 限制 `priority` 范围(0-100
**修改文件**
- `backend/app/schemas/role.py`
---
### H-9Token 未绑定 IP/设备
**状态**: ⚠️ 待处理
**风险级别**: 🟠 高
**处理难度**: ⚠️ 中
**发现日期**: 2026-06-13
**问题描述**
Token 没有绑定 IP 地址或设备指纹,任何获取到 Token 的人都可以使用。
**处理建议**
1. 绑定 IP 地址(可选,影响移动场景)
2. 绑定设备指纹(可选,需要前端配合)
3. 敏感操作要求二次验证
**关联开发任务**
- Token 安全加固
---
### H-10:管理端 API 无 IP 白名单
**状态**: ✅ 已修复
**风险级别**: 🟠 高
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
管理端角色管理 API 没有 IP 白名单限制。
**修复方案**
1. 在 Nginx 层添加 IP 白名单(/itadmin/ 和 /api/admin/ 路径)
2. 允许内网网段:10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、10.212.0.0/16
**修改文件**
- `deploy-server/nginx/nginx.conf`
---
### H-11WebSocket Token 通过 URL 参数传递
**状态**: ⚠️ 待处理
**风险级别**: 🟠 高
**处理难度**: ⚠️ 中
**发现日期**: 2026-06-13
**问题描述**
WebSocket 连接的 Token 通过 URL 参数传递,会被记录在访问日志中。
**处理建议**
1. 改为通过 WebSocket 握手头传递
2. 或通过第一条消息传递
3. 在 Nginx 中对 `/ws/` 路径关闭访问日志
**关联开发任务**
- WebSocket 安全加固
---
## 四、中等风险 (Medium)
### M-6:旧 Token 迁移策略缺失
**状态**: ⚠️ 待处理
**风险级别**: 🟡 中
**处理难度**: ⚠️ 中
**发现日期**: 2026-06-13
**问题描述**
没有从旧格式迁移到新格式的策略。
**处理建议**
1. 实现 Token 自动迁移(访问旧格式 Token 时自动转换为新格式)
2. 设置迁移期限(如 30 天后旧 Token 失效)
**关联开发任务**
- Token 迁移工具
---
### M-7:角色缓存策略缺失
**状态**: ⚠️ 待处理
**风险级别**: 🟡 中
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**问题描述**
每次请求都从数据库查询用户角色,没有缓存策略。
**处理建议**
1. 添加 Redis 缓存(TTL 5-10 分钟)
2. 角色变更时主动失效缓存
**关联开发任务**
- 角色缓存实现
---
### M-8:API 速率限制未覆盖所有端点
**状态**: ⚠️ 待处理
**风险级别**: 🟡 中
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**问题描述**
只覆盖了登录端点,其他 API 端点没有速率限制。
**处理建议**
1. 为所有 API 端点添加速率限制
2. 分级限制:登录 10/min,普通 API 60/min,管理 API 30/min
**关联开发任务**
- 速率限制完善
---
### M-9:异常信息泄露
**状态**: ✅ 已修复
**风险级别**: 🟡 中
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
异常处理返回 `f"服务器内部错误: {str(exc)}"`,可能泄露内部信息。
**修复方案**
1. 异常处理器返回通用错误消息:"服务器内部错误,请稍后重试或联系管理员"
2. 中间件返回通用错误消息(同上)
3. 详细异常信息仅记录到日志
**修改文件**
- `backend/app/main.py`
---
### M-10:日志脱敏不足
**状态**: ✅ 已修复
**风险级别**: 🟡 中
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
日志中包含 `user_id``employee_id` 等敏感信息。
**修复方案**
1. 添加 `_mask_sensitive_data()` 脱敏函数
2. 对 employee_id 进行脱敏处理(保留前3位,如 "abc***def"
3. 已处理:role_mapping_service.py、admin_roles.py
**修改文件**
- `backend/app/services/role_mapping_service.py`
- `backend/app/api/admin_roles.py`
---
### M-11:数据库密码弱密码
**状态**: ✅ 已修复
**风险级别**: 🟡 中
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
PostgreSQL 密码使用 `wecom_secret``wecom_secret_2026`,强度不足。
**修复方案**
1. `.env.example` 中使用强密码占位符(`your-strong-postgres-password`
2. 添加注释说明密码要求(≥16位,含大小写字母+数字+特殊字符)
3. 生产环境通过 `.env` 文件注入强密码
**修改文件**
- `.env.example`
---
### M-12Redis 无密码保护
**状态**: ✅ 已修复
**风险级别**: 🟡 中
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
Redis 连接无密码认证。
**修复方案**
1. Docker Compose 中添加 `--requirepass` 参数
2. `.env.example` 中添加 `REDIS_PASSWORD` 配置项
3. 更新 `REDIS_URL` 格式为 `redis://:password@redis:6379/0`
4. 健康检查使用密码认证
**修改文件**
- `deploy-server/docker-compose.yml`
- `.env.example`
---
## 五、低风险 (Low)
### L-5Nginx 缺少 CSP 和 HSTS 安全头
**状态**: ✅ 已修复
**风险级别**: 🔵 低
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**修复方案**
在 Nginx 配置中添加以下安全头:
```nginx
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:;" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
```
**修改文件**
- `deploy-server/nginx/nginx.conf`
---
### L-6CORS 配置过于宽松
**状态**: ✅ 已修复
**风险级别**: 🔵 低
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**修复方案**
```python
allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allow_headers=["Authorization", "Content-Type", "X-Employee-Id"],
```
**修改文件**
- `backend/app/main.py`
---
### L-7:坐席列表 API 无认证
**状态**: ✅ 已修复
**风险级别**: 🔵 低
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**修复日期**: 2026-06-13
**问题描述**
坐席列表 API 没有认证保护,任何人都可以访问。
**修复方案**
1. 导入 `require_role` 依赖
2. 添加 `@require_role("agent", "admin")` 装饰器
**修改文件**
- `backend/app/api/agents.py`
---
### L-8Nginx `client_max_body_size` 过大
**状态**: ⚠️ 待处理
**风险级别**: 🔵 低
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**处理建议**
```nginx
location /api/upload/ {
client_max_body_size 50m;
}
location /api/ {
client_max_body_size 1m;
}
```
**关联开发任务**
- Nginx 配置优化
---
### L-9:前端硬编码配置
**状态**: ⚠️ 待处理
**风险级别**: 🔵 低
**处理难度**: ⚠️ 低
**发现日期**: 2026-06-13
**处理建议**
1. 通过环境变量注入配置
2. 避免在前端代码中硬编码敏感信息
**关联开发任务**
- 前端配置优化
---
## 六、处理计划
### 第一阶段:紧急修复(已完成)
| 序号 | 任务 | 风险项 | 状态 |
|------|------|--------|------|
| 1 | 恢复 `dependencies.py` 并合并新功能 | CR-1 | ✅ 已验证 |
| 2 | 统一 Token 格式并确保向后兼容 | CR-2 | ✅ 已修复 |
| 3 | 修改 Portal API 使用新认证中间件 | CR-3 | ✅ 已修复 |
| 4 | 修复坐席登录的 Redis 连接管理 | CR-4 | ✅ 已修复 |
| 5 | 添加角色分配权限验证 | H-7 | ⚠️ 待处理 |
| 6 | 添加映射规则输入验证 | H-8 | ✅ 已修复 |
### 第二阶段:安全加固(上线后 1 周内)
| 序号 | 任务 | 风险项 | 状态 |
|------|------|--------|------|
| 7 | Token 绑定 IP/设备指纹 | H-9 | ⚠️ 待处理 |
| 8 | 管理端 API 添加 IP 白名单 | H-10 | ⚠️ 待处理 |
| 9 | WebSocket Token 改为头传递 | H-11 | ⚠️ 待处理 |
| 10 | 实现旧 Token 迁移策略 | M-6 | ⚠️ 待处理 |
| 11 | 添加角色缓存 | M-7 | ⚠️ 待处理 |
| 12 | 为所有 API 添加速率限制 | M-8 | ⚠️ 待处理 |
### 第三阶段:纵深防御(上线后 2 周内)
| 序号 | 任务 | 风险项 | 状态 |
|------|------|--------|------|
| 13 | 异常处理不再泄露内部信息 | M-9 | ⚠️ 待处理 |
| 14 | 日志脱敏处理 | M-10 | ⚠️ 待处理 |
| 15 | PostgreSQL 更换强密码 | M-11 | ⚠️ 待处理 |
| 16 | Redis 设置密码 | M-12 | ⚠️ 待处理 |
| 17 | Nginx 添加 CSP/HSTS 安全头 | L-5 | ⚠️ 待处理 |
| 18 | 收紧 CORS 配置 | L-6 | ⚠️ 待处理 |
| 19 | 坐席列表 API 添加认证 | L-7 | ⚠️ 待处理 |
| 20 | Nginx 按路径细分文件大小限制 | L-8 | ⚠️ 待处理 |
---
## 七、风险关联开发任务
以下风险与当前开发任务关联,需要在相关任务完成时一并处理:
| 风险项 | 关联开发任务 | 处理时机 |
|--------|--------------|----------|
| H-6 | 角色映射服务开发 | 实现时添加验证 |
| H-7 | 角色管理 API 完善 | 实现时添加权限检查 |
| H-9 | Token 安全加固 | Token 服务完善时 |
| H-10 | 管理端访问控制 | 部署时配置 |
| H-11 | WebSocket 安全加固 | WS 重构时 |
| M-6 | Token 迁移工具 | 上线前 |
| M-7 | 角色缓存实现 | 性能优化时 |
| M-8 | 速率限制完善 | 安全加固时 |
| M-9 | 异常处理优化 | 代码审查时 |
| M-10 | 日志脱敏实现 | 日志系统优化时 |
| M-11 | 生产环境配置 | 部署时 |
| M-12 | 生产环境配置 | 部署时 |
| L-5~L-9 | Nginx/前端优化 | 部署/优化时 |
---
## 八、维护说明
1. **定期审查**:每月审查一次风险状态,更新处理进度
2. **新风险录入**:发现新风险时及时录入本表
3. **关联开发任务**:开发任务涉及风险项目时,与风险项目一并处理并更新状态
4. **状态更新**:风险处理完成后,更新状态为 ✅ 已修复,并记录修复日期
---
## 九、2026-06-14 workbuddy 推送评审新增
**评审依据**: `docs/评审报告/workbuddy-2026-06-14-消息优化.md`
**评审范围**: workbuddy 6-14 推送 + `IT智能服务台-版本更新说明-20250614.md`
**小计**: 13 项发现(6 P0 + 4 P1 + 3 P2),其中 7 项已修本地代码,6 项待 workbuddy 跟进
---
### 9.1 🔴 严重 (新增 6 项,**全部已修**)
#### CR-5H5 participants 端点无会话参与权限校验 → P0-1
- **状态**: ✅ 已修复(2026-06-14 本地代码)
- **风险级别**: 🔴 严重(数据泄露)
- **位置**: `backend/app/api/h5.py:1107-1145`
- **问题**: 仅校验"用户已登录",未校验"是否属于本会话",任意已登录员工可枚举 conversation_id 读取他会话参与者
- **修复**: 加 is_creator / is_participant 双重校验
#### CR-6recall_message 端点无鉴权 → P0-2
- **状态**: ✅ 已修复
- **风险级别**: 🔴 严重(数据破坏)
- **位置**: `backend/app/api/messages.py:293-340`
- **问题**: 端点签名只有 `db: AsyncSession = Depends(get_db)`**无任何鉴权依赖**
- **修复**: 加 `agent: Agent = Depends(get_current_agent)` + `message.sender_id == agent.user_id` 校验
#### CR-7delete_message 端点无鉴权 → P0-3
- **状态**: ✅ 已修复
- **位置**: `backend/app/api/messages.py:336-365`
- **修复**: 同 CR-6
#### CR-8mark_read 端点无鉴权 + 会话访问未校验 → P0-4
- **状态**: ✅ 已修复
- **位置**: `backend/app/api/messages.py:368-405`
- **问题**: 任意人可调用改任意会话已读状态,破坏"未读数"业务
- **修复**: 加 agent 鉴权 + `assigned_agent_id` / `collaborating_agent_ids` 校验
- **捎带修**: `where(Message.is_read == False)` 改为 `is_(False)`P2-1,原表达式在 SQLAlchemy 静默失效)
#### CR-9upload_image 端点无鉴权 → P0-5
- **状态**: ✅ 已修复
- **位置**: `backend/app/api/messages.py:400-462`
- **问题**: 任意 HTTP 客户端可上传图片占用磁盘(无大小硬限、无频率限制)
- **修复**: 加 `Depends(get_current_agent)`
#### CR-10upload_message_file 端点无鉴权 → P0-6
- **状态**: ✅ 已修复
- **位置**: `backend/app/api/messages.py:458-525`
- **修复**: 同 CR-9
---
### 9.2 🟠 高 (新增 4 项,**全部待 workbuddy 跟进**)
#### H-12upload 路径在容器本地,容器重建即丢失 → P1-1
- **状态**: ⚠️ 待处理
- **风险级别**: 🟠 高(数据丢失)
- **位置**: `backend/app/api/messages.py:434,487`
- **问题**: `media/images/``media/files/` 写容器本地,容器重建或重启丢所有上传
- **处理建议**: 改 volume mount(参考 nginx 静态文件挂载模式,参考 `docker-compose.yml:142-145`
#### H-13SQL 迁移未走 Alembic → P1-2
- **状态**: ⚠️ 待处理
- **风险级别**: 🟠 高(schema 漂移)
- **位置**: `alembic/versions/`(缺)、`models/message.py:190-204`
- **问题**: 模型已有 `status` / `recallable_until` 字段,但**未见对应 Alembic 迁移脚本**;版本文档教用户手动 `ALTER TABLE`(反模式)
- **处理建议**: 跑 `alembic revision --autogenerate -m "add message status and recallable_until"` 自动生成迁移
#### H-14docker-compose backend healthcheck 用 curl → P1-3
- **状态**: ⚠️ 待处理
- **风险级别**: 🟠 高(监控失真)
- **位置**: `docker-compose.yml:117-122`
- **问题**: `curl -f http://localhost:8000/health || exit 1`**backend 精简 Python 镜像无 curl** → healthcheck 永远 unhealthy
- **关联记忆**: [[backend-healthcheck-curl-pitfall]]
- **处理建议**: 改用 `python -c "import socket; s=socket.socket(); s.connect(('localhost',8000))"`Python 镜像必有)
#### H-15ws_manager 文档承诺"消息状态广播"未实现 → P1-4
- **状态**: ⚠️ 待处理
- **风险级别**: 🟠 高(文档与代码不符)
- **位置**: `docs/IT智能服务台-版本更新说明-20250614.md:46` 声称改动 / `backend/app/services/ws_manager.py` 实际无对应方法
- **问题**: ConnectionManager 仅有 `send_to_agent` / `broadcast` / `send_to_employee` / `broadcast_to_employees`**无 `broadcast_message_status(conv_id, msg_id, status)`**
- **处理建议**: 实现该方法 + WebSocket 消息格式
---
### 9.3 🟡 中 (新增 3 项,1 已修,2 待跟进)
#### M-13upload 写文件非原子 → P2-2
- **状态**: ⚠️ 待处理
- **位置**: `backend/app/api/messages.py:440,494`
- **问题**: `with open(file_path, "wb") as f: f.write(content)`,中途崩溃留半文件
- **处理建议**: 先写 `*.tmp``os.rename` 原子化
#### M-14upload 返回原始文件名 → P2-3
- **状态**: ⚠️ 待处理
- **位置**: `backend/app/api/messages.py:501`
- **问题**: `"filename": original_name` 返回原始文件名,可能含中文 / 特殊字符(XSS 风险)
- **处理建议**: URL encode 或服务端做白名单过滤
#### M-15mark_read SQL `== False` 表达式静默失效 → P2-1
- **状态**: ✅ 已修复(捎带在 P0-4 修复中)
- **位置**: `backend/app/api/messages.py:388`(原)
- **问题**: `where(Message.is_read == False)` 在 SQLAlchemy 中不报错但**实际未生效**Python `==` 返回 False → SQLAlchemy 当赋值处理但参数已绑死)
- **修复**: 改为 `is_(False)`,走 SQL `is false` 否定
---
### 9.4 文档本身的 4 处错误(已记录待修订)
| # | 位置 | 错误 | 建议修订 |
|---|------|------|----------|
| D-1 | 版本说明部署步骤 5 | `docker compose -p root up -d` **正是用户 6-14 生产事故的根因** | **删除 `-p root` 标志** |
| D-2 | 版本说明部署步骤 6 | SQL `DEFAULT 'sent'` 引号未转义(shell 语法错) | 改用 Alembic 迁移脚本 |
| D-3 | 版本说明 2.1 ws_manager | 声称"添加消息状态广播"但实际未实现 | 改"规划中"或"本次未实现" |
| D-4 | 版本说明 2.1 docker-compose | "healthcheck 已配置"不准确 | 加注 backend curl 坑 |
---
### 9.5 评审结论与流程建议
- **P0 比例 46% (6/13) 过高** —— workbuddy 后续推送需**强制走评审流程**
- **建议加 pre-commit 检查**: 新增端点无 `Depends(...)` 鉴权依赖时拒绝推送
- **下次推送窗口**: 等 H-12~15 + M-13/14 全部修完再合入,**不在评审未消化前叠加新功能**
---
### 9.6 新增项状态速查
| 编号 | 状态 | 编号 | 状态 |
|------|------|------|------|
| CR-5 (P0-1) | ✅ | H-12 (P1-1) | 🟡 半成品(留 #25) |
| CR-6 (P0-2) | ✅ | H-13 (P1-2) | ✅ |
| CR-7 (P0-3) | ✅ | H-14 (P1-3) | ✅ |
| CR-8 (P0-4) | ✅ | H-15 (P1-4) | ✅ |
| CR-9 (P0-5) | ✅ | M-13 (P2-2) | ⚠️ |
| CR-10 (P0-6) | ✅ | M-14 (P2-3) | ⚠️ |
| | | M-15 (P2-1) | ✅(捎带)|
---
## 第十节: 2026-06-14 P0 安全评估(workbuddy 推送 v2)
**关联 commit**: `3735dc0` — feat(security): P0 安全止血 - WS token 改 header + 坐席本地密码
**主报告**: `docs/评审报告/workbuddy-2026-06-14-P0安全.md`
**评审结论**: 🟡 **部分完成,5 项遗留**(3 项 P0 / 2 项 P1)
**workbuddy 下一轮任务**: #18
> 📌 第十节有独立小计(5 P0 + 2 P1,2 个新维度:WS token 鉴权 + 坐席本地密码)。
### 10.1 小计
| 维度 | 任务 | 真实状态 |
|---|---|---|
| P0-#1 | WECOM_SECRET 集中化 | 🟡 **只规划未实改** (`docs/安全/secret-管理.md`) |
| P0-#2 | SSL 私钥在仓 | 🟢 **8-A 阶段已修**(.gitignore `**` 模式) |
| P0-#3 | Mock login bypass | 🟢 **之前已修** |
| P0-#4 | WS token URL/日志泄露 | 🟡 **半成品**(服务端 OK,前端 ws.ts + nginx access_log 待关) |
| P0-#5 | 坐席本地密码 | 🟡 **半成品**(字段/Schema/端点 OK,类型 bug + 降级放行 + 缺依赖) |
**总评**: 2/5 P0 完成,3 项遗留待 workbuddy 下一轮修。
### 10.2 遗留项追踪(给 workbuddy 任务清单 #18)
| # | 严重度 | 文件 | 项 | 状态 |
|---|---|---|---|---|
| 遗留 1 | 🔴 P0 | `frontend-agent/src/composables/useWebSocket.ts:106-110` | 浏览器 WebSocket API 不支持自定义 header,改 Sec-WebSocket-Protocol | ⚠️ |
| 遗留 2 | 🔴 P0 | `nginx.conf` + `deploy-server/nginx.conf` | `location /ws/ { access_log off; }` | ⚠️ |
| 遗留 3 | 🟡 P1 | `backend/app/models/agent.py:142-148` | `Mapped[str]``Mapped[Optional[str]]` | ⚠️ |
| 遗留 4 | 🟡 P1 | `backend/app/api/agents.py` 降级放行 | 强制 password 验证 | ⚠️ |
| 遗留 5 | 🟡 P1 | `backend/requirements.txt` | 缺 passlib/bcrypt 依赖 | ⚠️ |
### 10.3 评审教训(防再犯)
1. **WebSocket API 边界**: 浏览器 vs Node.js `ws` 库 API 差异
2. **依赖检查**: 改代码必须同步 requirements.txt
3. **配置改动**: plan 写了的 nginx / conf 必须做
4. **类型一致性**: Mapped[T] + nullable=True 必须 Optional
5. **逻辑回归**: 新鉴权必须 review 已有降级路径
### 10.4 推 Gitea 状态
- **本地 commit**: 3735dc0 ✅
- **推 Gitea**: 🔴 **卡 #8**(MariaDB 套件未装)
- **下次**: Gitea 起来后 `git push -u origin main` 一次推送 → 触发 workbuddy 二次评审 → #18 闭环
### 10.5 第十节状态速查
| 编号 | 状态 |
|---|---|
| P0-#1 WECOM_SECRET 集中化 | 🟡 规划中(V1/V2) |
| P0-#2 SSL 私钥 | 🟢 8-A 完成 |
| P0-#3 Mock login | 🟢 完成 |
| P0-#4 WS token | 🟡 遗留 1+2 |
| P0-#5 坐席密码 | 🟡 遗留 3+4+5 |
---
## 第十一节: 2026-06-14 P1 消息优化推送(2 轮)
**来源**: 6-14 workbuddy 消息优化推送遗留 4 P1
**主报告**: `docs/评审报告/workbuddy-2026-06-14-消息优化.md` 9.3 节
**workbuddy 任务清单**: `.workbuddy/memory/2026-06-14-任务-修P1消息.md`
**任务编号**: #23
### 11.1 4 P1 项
| 编号 | 严重度 | 内容 | 状态 |
|---|---|---|---|
| H-12 (P1-1) | 🟡 | upload 路径在容器本地,容器重建即丢失 → 改 volume mount | 🔄 |
| H-13 (P1-2) | 🟡 | SQL 迁移未走 Alembic → 生成 `add message status` 迁移 | 🔄 |
| H-14 (P1-3) | 🟡 | docker-compose backend healthcheck 用 curl → 改 Python 一行 | 🔄 |
| H-15 (P1-4) | 🟡 | ws_manager 没实现"消息状态广播" → 实现 `broadcast_message_status()` | 🔄 |
### 11.2 评审教训(防 workbuddy 再犯)
1. **依赖 docker volume 部署前要先建 host 目录** —— `scripts/deploy.sh` 需加创建逻辑
2. **alembic autogenerate 需人工 review** —— 自动生成的不一定对(可能漏 index / 加了不想要的)
3. **backend 精简镜像没 curl 是已知坑** —— 用 Python 一行替代
4. **文档承诺的 WS 广播必须实做** —— 否则前端靠轮询兜底,实时性不够
### 11.3 第十一节状态速查
| 编号 | 状态 |
|---|---|
| H-12 (P1-1) upload 路径 | 🔄 评审闭环中 |
| H-13 (P1-2) Alembic 迁移 | 🔄 评审闭环中 |
| H-14 (P1-3) healthcheck | 🔄 评审闭环中 |
| H-15 (P1-4) ws 状态广播 | 🔄 评审闭环中 |