# ZCLAW 安全渗透测试报告 V1.0 > 审计日期: 2026-03-31 > 审计范围: zclaw-saas 后端、desktop Tauri 应用、admin-v2 管理面板 > 审计方法: 白盒代码审计 + 灰盒攻击面分析 > 整体评级: **B+** (良好) --- ## 一、执行摘要 对 ZCLAW 项目三大子系统进行了全面安全审计,覆盖 12 个安全领域、80+ API 端点、~80 个 Tauri IPC 命令。 **核心结论**: 未发现 Critical 级漏洞。项目安全架构设计良好(Argon2id、参数化 SQL、AES-256-GCM、RBAC),但在 JWT 生命周期管理、CSP 策略、密钥隔离方面存在改进空间。 共发现 **5 项 HIGH** + **10 项 MEDIUM** + **7 项 LOW** 级问题,全部已修复(HIGH + MEDIUM)或记录(LOW)。 --- ## 二、已修复漏洞清单 ### HIGH 级 (5 项 — 全部已修复) | # | 漏洞 | 影响 | 修复方案 | |---|------|------|----------| | H1 | 密码修改后 JWT 不失效 | 攻击者窃取 JWT 后密码修改仍可使用 24h | `password_version` 机制: JWT claims 加入 pwv,中间件比对 DB 值,密码修改时递增 | | H2 | Docker SaaS 端口绑定所有接口 | 生产环境 SaaS 直接暴露公网 | 改为 `127.0.0.1` 绑定,仅通过 nginx 反代访问 | | H3 | TOTP 加密密钥与 JWT 密钥耦合 | JWT 泄露 → 所有加密数据同时泄露 | 生产环境强制独立 `ZCLAW_TOTP_ENCRYPTION_KEY`,缺失时拒绝启动 | | H4 | Tauri CSP `connect-src http://*` | XSS 后可向任意 HTTP 端点外泄数据 | 收紧为 `http://localhost:* https://*` | | H5 | Tauri CSP `unsafe-inline` 脚本 | 允许内联脚本执行,削弱 XSS 防护 | 移除 `script-src 'unsafe-inline'` | ### MEDIUM 级 (10 项 — 全部已修复) | # | 漏洞 | 修复方案 | |---|------|----------| | M1 | 限流仅内存存储 | PostgreSQL `rate_limit_events` 表持久化 | | M2 | 无账户锁定机制 | 5 次失败锁定 15 分钟,DB 字段追踪 | | M3 | 弱邮箱验证 | RFC 5322 regex + 254 字符长度限制 | | M4 | 设备注册无输入约束 | typed struct + 字段长度限制 | | M5 | Provider URL 仅执行时验证 SSRF | 创建/更新时即验证 URL,拒绝私有 IP | | M6 | Legacy 固定 Nonce TOTP 加密 | 启动时自动迁移到随机 Nonce 格式 | | M7 | Legacy 静态 Salt 前端加密 | v1→v2 自动迁移,随机 salt | | M8 | Token 存储 JS 内存 | 移除 Zustand 中的 token 字段,仅用 HttpOnly Cookie | | M9 | Refresh Token 重复传递 Header | 移除 Authorization Bearer 回退 | | M10 | Pipeline 日志含用户数据 | 截断到 100 字符,敏感值替换为 [REDACTED] | --- ## 三、已确认安全区域 | 领域 | 评级 | 证据 | |------|------|------| | **SQL 注入** | 安全 | 全量参数化查询 (sqlx `.bind()`),无字符串拼接 | | **命令注入** | 安全 | `Command::new` 不用 shell,参数均为编译时常量 | | **路径遍历** | 安全 | 文件操作用硬编码路径,pipeline_id 严格过滤 | | **密码存储** | 安全 | Argon2id + OsRng 随机盐 + spawn_blocking | | **加密实现** | 安全 | AES-256-GCM + 随机 12 字节 Nonce | | **错误泄露** | 安全 | 内部错误统一返回 "服务内部错误" | | **JWT 基础** | 安全 | audience 验证、JTI 唯一、refresh 单次 rotation | | **RBAC** | 安全 | 自我角色提升阻断、Token 权限范围限制 | | **SSRF** | 安全 | 全面的 URL 验证 (私有 IP/DNS/混淆) | | **CORS** | 安全 | 生产强制白名单,缺失拒绝启动 | | **Cookie** | 安全 | HttpOnly + Secure + SameSite=Strict | | **XFF** | 安全 | 仅信任配置代理 IP | --- ## 四、涉及修改的文件 ### 数据库迁移 (新增) - `migrations/20260401000004_accounts_password_version.sql` - `migrations/20260401000005_rate_limit_events.sql` ### Rust 后端 (修改) - `crates/zclaw-saas/src/auth/jwt.rs` — Claims pwv 字段 - `crates/zclaw-saas/src/auth/handlers.rs` — 登录锁定 + 邮箱验证 + pwv - `crates/zclaw-saas/src/auth/mod.rs` — 中间件 pwv 验证 - `crates/zclaw-saas/src/config.rs` — TOTP 密钥强制独立 - `crates/zclaw-saas/src/state.rs` — AppCache 字段 - `crates/zclaw-saas/src/lib.rs` — cache 模块注册 - `crates/zclaw-saas/src/models/account.rs` — AccountLoginRow 字段 - `crates/zclaw-saas/src/cache.rs` — 已存在,注册到 lib - `crates/zclaw-saas/src/crypto.rs` — Legacy TOTP 迁移函数 - `crates/zclaw-saas/src/main.rs` — 调用迁移 - `crates/zclaw-saas/src/middleware.rs` — 持久化限流 - `crates/zclaw-saas/src/account/handlers.rs` — 设备注册约束 - `crates/zclaw-saas/src/model_config/handlers.rs` — Provider URL 验证 - `crates/zclaw-pipeline/src/executor.rs` — 日志脱敏 - `crates/zclaw-pipeline/src/actions/mod.rs` — 日志脱敏 ### 前端 (修改) - `desktop/src-tauri/tauri.conf.json` — CSP 加固 - `desktop/src/lib/crypto-utils.ts` — Legacy 加密迁移 - `admin-v2/src/stores/authStore.ts` — 移除 token 存储 - `admin-v2/src/services/request.ts` — 移除 Bearer header - `admin-v2/src/router/AuthGuard.tsx` — isAuthenticated 检查 - `admin-v2/src/pages/Login.tsx` — login 调用更新 ### 配置 (修改) - `docker-compose.yml` — 端口绑定 + env_file --- ## 五、验证结果 | 检查项 | 结果 | |--------|------| | `cargo check -p zclaw-saas` | ✅ 通过 | | `cargo test -p zclaw-saas --lib` | ✅ 17/17 通过 | | `npx tsc --noEmit` (admin-v2) | ✅ 零错误 | | 安全扫描 | 建议: `cargo audit` + `pnpm audit` + `trivy` | --- ## 六、LOW 级监控项 (暂不修复) | # | 项目 | 说明 | |---|------|------| | L1 | Dev JWT fallback 密钥 | `#[cfg(debug_assertions)]` 保护 | | L2 | Demo API Key 种子数据 | 显然假值 | | L3 | 浏览器自动化 eval | 设计如此 | | L4 | 自定义 Markdown 渲染器 | 已用 DOMPurify 缓解 | | L5 | Console 日志引用 Token | 不记录值 | | L6 | format!() 用于表名 | 编译时常量 | | L7 | docker-compose env_file 引用示例 | 文档说明即可 |