Files
zclaw_openfang/docs/archive/old-audits/AUDIT_ROUND3_V11.md
iven 2e5f63be32
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
docs: reorganize docs — archive outdated, create brainstorming folder
- Create docs/brainstorming/ with 5 discussion records (Mar 16 - Apr 7)
- Archive ~30 outdated audit reports (V5-V11) to docs/archive/old-audits/
- Archive superseded analysis docs to docs/archive/old-analysis/
- Archive completed session plans to docs/archive/old-plans/
- Archive old test reports/validations to respective archive folders
- Remove empty directories left after moves
- Keep current docs: TRUTH.md, feature docs, deployment, knowledge-base, superpowers
2026-04-07 09:54:30 +08:00

9.8 KiB
Raw Blame History

ZCLAW 第三轮全面审计报告

审计日期: 2026-04-02 基线: V11 全面审计 + 深度二次审计 + Sprint 1-4 修复 方法: 5 维并行审计(前端状态一致性、数据库 Schema、API 契约、并发安全、代码质量) 完成代理: 前端状态一致性1/5其余 4 维因 API 限流由主线程直接执行


1. 前端状态一致性 + 内存泄漏审计(代理完成)

HIGH

ID 问题 文件 描述
AUD3-FE-01 chatStore.sendMessage 无并发保护 chatStore.ts:403-675 isStreaming 仅在 UI 层守卫store 函数本身无互斥。快速双击可在 React re-render 前触发两次发送,导致双重 assistant placeholder + stream 竞态
AUD3-FE-02 SaaS client token refresh 无并发锁 saas-client.ts:217-229 多个并发请求同时收到 401 时,各自独立调用 refreshToken(),导致多次 refresh 请求。应使用 refresh mutex共享 Promise

MEDIUM

ID 问题 文件 描述
AUD3-FE-03 initializeStores 可能被调用 3 次 connectionStore.ts:415,589 + index.ts:99 模块加载 + connect() 双路径,异步操作中切换 client 可能导致请求失败
AUD3-FE-04 window 全局变量存储 interval App.tsx:257-258 @ts-expect-error + window.__ZCLAW_STATS_SYNC_INTERVAL__React StrictMode 双重 mount 时第一个 interval 无法清理
AUD3-FE-05 GatewayClient mixin 25+ 处 as any gateway-heartbeat.ts prototype 动态方法通过 as any 绕过类型检查,属性名拼写错误无编译时报警
AUD3-FE-06 PropertyPanel 17 处 as any 访问联合类型 PropertyPanel.tsx:100-276 WorkflowNodeData 联合类型的字段直接 as any 访问,节点类型不匹配时 undefined

LOW

ID 问题 文件
AUD3-FE-07 offlineStore 全局变量存储 timer多次调用可能泄漏 offlineStore.ts:87-88
AUD3-FE-08 agentStore 一次性读取 chatStore 可能读到中间态 agentStore.ts:254
AUD3-FE-09 retryAllMessages 无并发锁,可能重复发送 offlineStore.ts:188-233

POSITIVE FINDINGS做得好的地方

  • 无 Store 循环依赖: 依赖方向是单向树状结构
  • 事件监听器清理完善: classroomStore、useAutomationEvents、chatStore 的 listen 全部有 cleanup
  • React useEffect cleanup 规范: ConnectionStatus、HandApprovalModal、SaaSStatus 全部正确清理

2. 数据库 Schema + Migration 审计(主线程执行)

Migration 文件清单13 个)

编号 文件 内容
20260329-001 initial_schema.sql 21 个核心表
20260329-002 seed_data.sql 种子数据
20260330-001 scheduled_tasks.sql 定时任务表
20260331-001 accounts_llm_routing.sql LLM 路由字段
20260331-002 agent_templates_extensions.sql 模板扩展
20260401-001 provider_keys_last_used.sql key 最近使用时间
20260401-002 remove_quota_reset_interval.sql 移除配额重置
20260401-003 models_is_embedding.sql embedding 标记
20260401-004 accounts_password_version.sql 密码版本
20260401-005 rate_limit_events.sql 限流事件
20260402-001 billing_tables.sql 计费 5 表
20260402-002 knowledge_base.sql 知识库 5 表
20260402-003 scheduled_task_results.sql 任务结果列

MEDIUM

ID 问题 描述
AUD3-DB-01 无 down migration 所有 migration 只有 UP无回滚脚本。生产环境需要回滚时只能手动操作
AUD3-DB-02 agent_template/service.rs:136 format! 构建 SQL format!("SELECT COUNT(*) FROM agent_templates {}", where_clause)where_clause 虽然是硬编码常量(非用户输入),但模式本身违反防御原则

POSITIVE FINDINGS

  • 编号连续无冲突: 13 个 migration 编号连续
  • 无 DELETE/UPDATE 缺少 WHERE: 全量扫描确认所有写操作都有 WHERE 子句
  • 仅 2 处 format! SQL: agent_template/service.rsdb.rs,两者 where_clause/table 均为硬编码
  • zclaw-growth 和 zclaw-memory 无 migration 目录: 使用代码内 schema 初始化SQLite

3. API 契约 + 错误恢复审计(主线程执行)

HIGH

ID 问题 文件 描述
AUD3-API-01 SaaS token refresh 并发竞态 saas-client.ts:217-229 多个并发请求同时收到 401各自独立调用 refreshToken()。无 _refreshPromise 或 mutex。refresh token 可能被第一个请求消耗,后续 refresh 请求失败(单次使用 token

MEDIUM

ID 问题 描述
AUD3-API-02 前端错误处理不统一 部分 invoke() 调用用 try/catch + log静默部分直接 throw用户看到错误部分 fallback 默认值。无全局错误提示机制
AUD3-API-03 37 处 as any 类型断言 前端大量绕过类型检查,重构时容易引入运行时错误

POSITIVE FINDINGS

  • AbortController 使用规范: request-helper.ts 有完整的 AbortController 管理Map<string, AbortController>),支持请求取消
  • 认证端点跳过 refresh: _isAuthEndpoint() 正确避免 login/register 端点的无限 refresh 循环
  • timeout 配置: 所有 fetch 调用使用 AbortSignal.timeout()

4. 并发安全 + 资源管理审计(主线程执行)

MEDIUM

ID 问题 文件 描述
AUD3-CONC-01 kernel_commands 每个命令单独获取 kernel_lock kernel_commands/*.rs 每个 Tauri 命令独立 state.lock().await,无嵌套锁获取。设计安全但串行化所有命令执行
AUD3-CONC-02 ~15 处 fire-and-forget tokio::spawn main.rs:108-151, relay/handlers.rs:389, scheduler.rs:62-140 无 JoinHandle无优雅停机。shutdown 时运行中的任务可能被截断
AUD3-CONC-03 approval polling 循环持有 kernel_lock approval.rs:96 kernel_state.lock().await 在 sleep 循环中反复获取,每次循环释放后重新获取。设计安全但增加锁竞争

POSITIVE FINDINGS

  • 无嵌套锁获取: 每个 kernel_command 只获取一个 MutexLock不存在 ABBA 死锁风险
  • DashMap 操作规范: 所有 RefMut 在 .await 前释放(已确认)
  • CancellationToken 用于 SSE: relay 的 SSE 流有取消机制

5. 代码质量审计(主线程执行)

统计数据

指标 数值
Rust 测试总数 584
前端测试 0 (desktop) + 322 (admin-v2)
as any 使用 37 处
@ts-expect-error 3 处
未使用 Cargo 依赖 0已清理 hmac/sha1
Feature gate 一致性 正确
编译警告 1 (private_interfaces) + 1 (sqlx future-incompat)

6. 综合发现汇总

新增 HIGH需立即修复

ID 问题 影响
AUD3-FE-01 chatStore.sendMessage 无并发保护 快速双击导致双重发送 + stream 竞态
AUD3-FE-02 / AUD3-API-01 SaaS token refresh 无并发锁 并发 401 → 多次 refresh → refresh token 被消耗 → 后续请求全部失败

新增 MEDIUM

ID 问题 影响
AUD3-FE-03 initializeStores 可能调用 3 次 异步操作中 client 切换
AUD3-FE-04 window 全局变量存 interval StrictMode 泄漏
AUD3-FE-05 25+ 处 mixin as any 类型安全缺口
AUD3-FE-06 PropertyPanel 17 处 as any 联合类型不安全
AUD3-DB-01 无 down migration 生产回滚困难
AUD3-DB-02 format! SQL硬编码安全但模式差 防御性编程
AUD3-API-02 前端错误处理不统一 用户体验不一致
AUD3-CONC-02 ~15 处 fire-and-forget spawn 优雅停机问题

新增 LOW

ID 问题
AUD3-FE-07 offlineStore 全局变量存储 timer
AUD3-FE-08 agentStore 读取中间态
AUD3-FE-09 retryAllMessages 无并发锁
AUD3-CONC-03 approval polling 增加锁竞争

7. 三轮审计累计发现总览

来源 P0 HIGH/P1 MEDIUM/P2 LOW/P3/P4
V11 初次审计 0 3 14 13
V11 深度二次 2 9 13 3
V11 第三轮 0 2 8 4
合计(去重后) 2 14 35 20

已修复 vs 未修复

状态 数量
已修复 132 P0 + 8 P1 + 3 P2
未修复 40

未修复中按优先级排序的 TOP 10

  1. AUD3-FE-01: chatStore.sendMessage 并发保护HIGH
  2. AUD3-FE-02/API-01: token refresh mutexHIGH
  3. SEC2-P1-01: FactStore trait 零实现P1
  4. SEC2-P1-08: Desktop 前端零测试P1
  5. AUD3-FE-03: initializeStores 重复调用MEDIUM
  6. AUD3-FE-05: mixin 模式类型安全MEDIUM
  7. SEC2-P2-03: sqlx-postgres 未来兼容性P2
  8. SEC2-P2-05: ~10 处 tokio::spawn 未绑定P2
  9. AUD3-DB-01: 无 down migrationMEDIUM
  10. SEC2-P1-01: FactStore trait 零实现P1

8. 积极发现总结

三轮审计确认以下方面设计良好、实现规范

  1. 无 Store 循环依赖 — 单向树状依赖结构
  2. 事件监听器全部有 cleanup — listen/unlisten 配对完整
  3. 认证中间件全覆盖 — 公共/受保护/Relay 三层路由无遗漏
  4. SQL 参数化规范 — 除 2 处硬编码 format! 外全部使用 bind()
  5. Lock ordering 安全 — 无嵌套锁获取
  6. Feature gate 一致 — 传播链正确
  7. Admin API 100% 对齐 — 前后端路由完全匹配
  8. 编译通过 — cargo check 仅 1 warning
  9. 密码安全 — Argon2id + password_version + JWT 失效
  10. SSE 背压设计 — 有界 channel + 信号量 + CancellationToken