Files
zclaw_openfang/docs/features/SECURITY_PENETRATION_TEST_V1.md
iven e3b93ff96d fix(security): implement all 15 security fixes from penetration test V1
Security audit (2026-03-31): 5 HIGH + 10 MEDIUM issues, all fixed.

HIGH:
- H1: JWT password_version mechanism (pwv in Claims, middleware verification,
  auto-increment on password change)
- H2: Docker saas port bound to 127.0.0.1
- H3: TOTP encryption key decoupled from JWT secret (production bailout)
- H4+H5: Tauri CSP hardened (removed unsafe-inline, restricted connect-src)

MEDIUM:
- M1: Persistent rate limiting (PostgreSQL rate_limit_events table)
- M2: Account lockout (5 failures -> 15min lock)
- M3: RFC 5322 email validation with regex
- M4: Device registration typed struct with length limits
- M5: Provider URL validation on create/update (SSRF prevention)
- M6: Legacy TOTP secret migration (fixed nonce -> random nonce)
- M7: Legacy frontend crypto migration (static salt -> random salt)
- M8+M9: Admin frontend: removed JS token storage, HttpOnly cookie only
- M10: Pipeline debug log sanitization (keys only, 100-char truncation)

Also: fixed CLAUDE.md Section 12 (was corrupted), added title.rs middleware
skeleton, fixed RegisterDeviceRequest visibility.
2026-04-01 08:38:37 +08:00

126 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 引用示例 | 文档说明即可 |