docs(workbuddy): 推 P0 安全评审 5 遗留任务清单
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
# workbuddy 任务 — 修 P0 安全评审遗留 5 项
|
||||
|
||||
**触发日期**: 2026-06-14
|
||||
**来源**: Claude 评审(主报告: `docs/评审报告/workbuddy-2026-06-14-P0安全.md`)
|
||||
**Gitea 仓**: `http://100.85.152.112:8418/simon/wecom_it_smart_desk`
|
||||
**当前 HEAD**: `3735dc0`
|
||||
**workbuddy token**: 见 `.workbuddy/config.json` 的 `gitea.token`(用户已配)
|
||||
|
||||
---
|
||||
|
||||
## ▶▶▶ 任务清单(按严重度,5 项)起
|
||||
|
||||
### 🔴 1. [P0] 修 ws.ts:用 Sec-WebSocket-Protocol 携带 token
|
||||
|
||||
**文件**: `frontend-agent/src/composables/useWebSocket.ts:106-110`
|
||||
|
||||
**问题**: 当前代码:
|
||||
```ts
|
||||
ws = new WebSocket(wsUrl, [], {
|
||||
headers: { Authorization: `Bearer ${agentStore.token}` }
|
||||
})
|
||||
```
|
||||
浏览器原生 WebSocket API 第 3 参数 options 没有 `headers` 字段。**Chromium / Firefox / Safari 全部忽略**。token 实际**未发送**。
|
||||
|
||||
**修复**:
|
||||
1. 前端改成:
|
||||
```ts
|
||||
ws = new WebSocket(wsUrl, [`bearer.${agentStore.token}`])
|
||||
```
|
||||
2. 服务端 `backend/app/api/ws.py` 改:
|
||||
```python
|
||||
# 优先从 subprotocol 取
|
||||
subprotocol = websocket.headers.get("sec-websocket-protocol", "")
|
||||
if subprotocol.startswith("bearer."):
|
||||
token = subprotocol[7:]
|
||||
else:
|
||||
auth_header = request.headers.get("Authorization", "")
|
||||
if auth_header.startswith("Bearer "):
|
||||
token = auth_header[7:]
|
||||
else:
|
||||
token = request.query_params.get("token", "")
|
||||
```
|
||||
3. H5 端 `h5_websocket_endpoint` 同改
|
||||
|
||||
### 🔴 2. [P0] 加 nginx access_log 关闭
|
||||
|
||||
**文件**:
|
||||
- `nginx.conf`(根目录)
|
||||
- `deploy-server/nginx.conf`
|
||||
|
||||
**修复**: 找 `location /api/` 段,在前后加:
|
||||
```nginx
|
||||
location /ws/ {
|
||||
access_log off;
|
||||
}
|
||||
```
|
||||
|
||||
### 🟡 3. [P1] 修 model `Mapped[str]` 类型 bug
|
||||
|
||||
**文件**: `backend/app/models/agent.py:142-148`
|
||||
|
||||
**问题**: `Mapped[str]` + `nullable=True` + `default=None` 严格模式下 `None` 赋值会报错。
|
||||
|
||||
**修复**:
|
||||
```python
|
||||
from typing import Optional
|
||||
...
|
||||
password_hash: Mapped[Optional[str]] = mapped_column(
|
||||
String(128),
|
||||
nullable=True,
|
||||
default=None,
|
||||
comment="本地密码哈希(bcrypt)",
|
||||
)
|
||||
```
|
||||
|
||||
### 🟡 4. [P1] 修降级放行必须 password 验证
|
||||
|
||||
**文件**: `backend/app/api/agents.py` `agent_login` 函数(企微 API 不可达分支)
|
||||
|
||||
**问题**: 走 "已注册坐席降级放行" 路径时,**不强制 password 验证**。P0-#5 加的 password 字段被绕过。
|
||||
|
||||
**修复**: 在降级放行分支检测:
|
||||
```python
|
||||
# 已有 agent 且 password_hash 存在 → 必须走 password 验证
|
||||
if agent and agent.password_hash:
|
||||
if not body.password:
|
||||
raise AppException(1011, "请输入本地密码")
|
||||
if not bcrypt.verify(body.password, agent.password_hash):
|
||||
raise AppException(1011, "本地密码错误")
|
||||
# 通过后放行
|
||||
```
|
||||
|
||||
### 🟡 5. [P1] requirements.txt 缺 passlib 依赖
|
||||
|
||||
**文件**: `backend/requirements.txt`
|
||||
|
||||
**问题**: `agents.py` 用了 `from passlib.hash import bcrypt`,但 requirements.txt **没加**。生产部署会 ImportError。
|
||||
|
||||
**修复**: 加一行:
|
||||
```
|
||||
passlib[bcrypt]==1.7.4
|
||||
```
|
||||
或(推荐,passlib 2024 停维护):
|
||||
```
|
||||
bcrypt==4.1.2
|
||||
```
|
||||
后者需同步改 `agents.py`:
|
||||
```python
|
||||
import bcrypt
|
||||
# 哈希
|
||||
bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
|
||||
# 验证
|
||||
bcrypt.checkpw(password.encode('utf-8'), agent.password_hash.encode('utf-8'))
|
||||
```
|
||||
|
||||
## ▼▼▼ 任务清单止
|
||||
|
||||
---
|
||||
|
||||
## 🔄 工作流(等 workbuddy 修完 5 项后)
|
||||
|
||||
1. workbuddy 修完 → 提交 commit 到 Gitea
|
||||
2. 通知 Claude 评审
|
||||
3. Claude 评审(2/5 改成 5/5 完成)
|
||||
4. 合并 + 推 main
|
||||
5. 关 #18
|
||||
|
||||
## 🔴 token 状态(用户已配)
|
||||
|
||||
- 用户给 Claude 的 token: `255eeaf88b...`(已撤销请用户)
|
||||
- workbuddy 自己的 token: `workbuddy-claude`(在 `.workbuddy/config.json`)
|
||||
- 推 Gitea 走 HTTPS(SSH 2222 不可达 + .ssh 权限锁)
|
||||
|
||||
## 关联
|
||||
|
||||
- 评审主报告: `docs/评审报告/workbuddy-2026-06-14-P0安全.md`
|
||||
- 风险跟踪表: 第十节(5 项遗留追踪)
|
||||
- Claude 记忆: `review-p0-security-2026-06-14.md`
|
||||
- Gitea 仓: `http://100.85.152.112:8418/simon/wecom_it_smart_desk`
|
||||
Reference in New Issue
Block a user