3.3 KiB
3.3 KiB
代码 Review 记录(2026-08-20,推送 git.awaioi.com 前)
范围:server/(Go)、client/core/(Go)、apps/web(React)、client/ui+desktop(WinUI3/Electron,静态)。 结论:基线全绿(go build/vet/test -race、tsc --noEmit、pnpm build、desktop JS 语法)。本次修复 7 处,均在提交前落地。
验证基线(全绿)
- server:
go build ./...✓ ·go vet ./...✓ ·go test -race ./...✓(api/auth/task/ws) - client/core:
go build/vet/test -race ./...✓(device/exec/bilibili/cdp/localserver/vault/wsclient) - apps/web:
tsc --noEmit✓(0 错误)·pnpm build✓(仅 >500KiB chunk 告警,非错误) - client/desktop:
node --check3 文件语法 ✓
已修复(本次)
| 级别 | 位置 | 问题 | 修复 |
|---|---|---|---|
| HIGH | server/internal/ws/hub.go | send on closed channel panic:连接注销时 close(send) 与 SendToAgent/广播并发竞态 |
Conn 增加 mu+closed 标记,统一经 sendRaw 发送并在关闭前检查;加回归测试(含 -race) |
| MED | server/internal/ws/dispatcher.go | 轮询 WHERE 缺括号:status=? AND schedule_at is null OR schedule_at<=? 优先级错误 |
显式括号 (schedule_at is null or schedule_at <= ?) |
| MED | server/internal/api/handlers/agent.go | 配对码非原子占用:并发可配出多台设备 | 事务内 UPDATE ... WHERE used=false 并以 RowsAffected==1 判定占用 |
| MED | server/internal/api/handlers/material.go | 上传无体积上限(磁盘 DoS) | http.MaxBytesReader + 配置 MAX_UPLOAD_BYTES(默认 2GiB) |
| MED | server/internal/ws/hub.go | RegisterAgent 在 hub 锁内做网络 Close | 关闭动作移出锁外;旧连接 ws 关闭加 nil 保护 |
| CRIT | server/internal/config/config.go | JWT_SECRET 默认值可被伪造令牌(admin 提权) | 默认/过短密钥时打印醒目安全告警 |
| LOW | client/core/internal/localserver/localserver.go | token 比较非常数时间 + 支持 URL query 传递 | 仅接受请求头 + subtle.ConstantTimeCompare |
审查确认无问题的关键点
- 认证:Argon2id(OWASP 基线参数)+ 常数时间比较;JWT HS256 + 签名方法校验(拒绝 alg 混淆)+ refresh 轮换(Redis jti 吊销)。
- 密码/保险库:client/core vault 用 AES-256-GCM,随机 nonce、GCM 认证、master.key/vault.enc 0600、目录 0700。
- 设备握手:Ed25519 hello 验签、坏签名/未知设备/已吊销设备均拒绝。
- 素材直链:签名 token 一次性 + 10min 过期 + path 前缀校验(storageKey 服务端生成)。
- 前端:无 dangerouslySetInnerHTML / innerHTML(无 XSS 注入点);401 刷新单飞;WS 重连;登出清理令牌。
- 任务状态机:转移表完整(草稿→审核→排队→下发→执行→成功/失败→重试/取消/挂起)。
遗留(低优先级,未阻塞)
- 前端 JWT 存 localStorage(当下无 XSS 向量可接受;二期可改 httpOnly Cookie)。
- WSS
InsecureSkipVerify: true(内网部署 + token 鉴权下可接受;公网需收紧 Origin 校验)。 - buildPush 每次下发失败会遗留未清理的 TransferToken(10min 过期自愈)。
- 素材 Delete 先删文件再删库,DB 失败会留悬空行(极小概率)。
- 前端 bundle 单 chunk >500KiB(可 code-split 优化)。