Files
wecom_it_smart_desk/.workbuddy/memory/2026-06-14-任务-修遗留.md
T

3.9 KiB
Raw Blame History

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.jsongitea.token(用户已配)


▶▶▶ 任务清单(按严重度,5 项)起

🔴 1. [P0] 修 ws.ts:用 Sec-WebSocket-Protocol 携带 token

文件: frontend-agent/src/composables/useWebSocket.ts:106-110

问题: 当前代码:

ws = new WebSocket(wsUrl, [], {
  headers: { Authorization: `Bearer ${agentStore.token}` }
})

浏览器原生 WebSocket API 第 3 参数 options 没有 headers 字段。Chromium / Firefox / Safari 全部忽略。token 实际未发送

修复:

  1. 前端改成:
    ws = new WebSocket(wsUrl, [`bearer.${agentStore.token}`])
    
  2. 服务端 backend/app/api/ws.py 改:
    # 优先从 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/ 段,在前后加:

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 赋值会报错。

修复:

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 字段被绕过。

修复: 在降级放行分支检测:

# 已有 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:

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