gitdataai/BUG_AUDIT_REPORT.md

17 KiB
Raw Blame History

项目 Bug 全面审计报告

审计日期: 2026-04-27 范围: 前后端全覆盖 (Rust 后端 + React/TypeScript 前端)


一、严重 (CRITICAL) — 4 个

1.1 无认证的 Git 初始化端点

文件: libs/api/git/init.rs:18-87 描述: git_init_bare, git_open, git_open_workdir, git_is_repo 四个端点均无 Session 参数,无需登录即可调用。攻击者可以初始化 bare 仓库、探测服务器文件系统路径。 风险: 未授权文件系统访问、数据泄露

1.2 CORS 安全漏洞 — allow_any_origin() + supports_credentials()

文件: apps/app/src/main.rs:185-190 描述: 同时启用 allow_any_origin()supports_credentials()Actix-web 文档明确警告这种组合会导致严重安全漏洞——任意恶意网站都能发起带凭据的跨域请求并读取响应。 风险: 任意网站可窃取用户数据、执行已认证操作

1.3 存储文件上传路径遍历

文件: libs/service/storage.rs:31-50 描述: base_path.join(key) 使用用户提供的 key 参数(如 ../../../etc/passwdRust 的 Path::join 会解析 .. 片段,导致文件写入存储根目录之外。 风险: 任意文件写入、远程代码执行

1.4 事务缺失导致数据损坏 (Issue 级联删除)

文件: libs/service/issue/issue.rs:505-529 描述: Issue 删除时执行 6 次独立 DELETE 操作评论、分配、标签、订阅者、仓库引用、issue自身没有使用数据库事务包装。如果其中任何一个删除失败数据库将留下孤立记录。 风险: 数据不一致、数据库污染


二、高危 (HIGH) — 8 个

2.1 LFS 认证令牌硬编码

文件: libs/git/http/lfs.rs:171 描述: LFS 批量响应返回 "Bearer token" 字面字符串,没有实际令牌机制。upload_object()download_object() 接收 _auth_token 参数但从不验证。任何获得 URL 的人都可以上传/下载 LFS 对象。 风险: 任意 LFS 对象访问和篡改

2.2 LFS X-User-Uid 头注入

文件: libs/git/http/lfs_routes.rs:31-40 描述: user_uid() 函数从客户端请求头 x-user-uid 读取用户身份并直接信任,无需验证。已认证 LFS 用户可冒充任意用户进行 lock/unlock 操作。 风险: 权限提升、冒充其他用户

2.3 Mutex 中毒风险 (AI 流式处理)

文件: libs/room/src/service/ai_react_streaming.rs:73,81,96,100,123,124,171 描述: 7 处 std::sync::Mutex::lock().unwrap() 使用非 tokio 版本的 Mutex。任何持有锁的线程 panic 都会导致 Mutex 永久中毒,所有后续调用直接 panic杀死房间的所有 AI 响应处理。 风险: AI 功能完全不可用(特定房间)

2.4 Drop 实现中使用 tokio::spawn — 锁释放失败

文件: libs/room/src/room_ai_queue.rs:20-51 描述: RoomAiLockGuard::drop() 调用 tokio::spawn() 释放 Redis 锁。如果在非 tokio 上下文中 dropDrop 在应用关闭时被调用spawn 会 panicRedis 锁永不释放,对应房间的 AI 处理永久锁定。 风险: AI 功能永久锁定

2.5 Redis KEYS 阻塞操作

文件: libs/room/src/connection.rs:695 描述: get_active_typing_events 使用 Redis KEYS 命令,该命令会阻塞整个 Redis 服务器 O(N) 时间。在生产环境大量 key 时会阻塞所有操作。应使用非阻塞的 SCAN风险: 大负载时 Redis 阻塞、服务中断

2.6 前端 XSS — 搜索结果 dangerouslySetInnerHTML

文件: src/app/search/page.tsx:198 描述: 搜索结果直接通过 dangerouslySetInnerHTML 渲染用户消息内容,未做 HTML 转义。恶意用户可在聊天中发送 <script>alert(1)</script>onerror payload当消息出现在搜索结果时触发存储型 XSS。 风险: 存储型 XSS、账户劫持、会话窃取

2.7 前端 WebSocket Token 在 URL 参数暴露

文件: src/lib/room-ws-client.ts:969-975 描述: WS token 通过 ?token=${token} 追加到 URL query 参数,会出现在浏览器 DevTools 网络日志、服务器日志中。 风险: Token 泄露

2.8 SSH Shell panic 风险

文件: libs/git/ssh/handle.rs:610-612 描述: 三处 unwrap() 获取 spawn 进程的 stdin/stdout/stderr。如果 git 进程在 piped stdio 模式下状态异常pipe 为 Noneunwrap() 会 panic异步任务将被静默杀死。 风险: SSH git 操作静默失败


三、中危 (MEDIUM) — 14 个

3.1 Agent 模型同步内存泄漏

文件: libs/service/agent/sync.rs:190 描述: 未知 provider 名称通过 Box::leak 转换为 &'static str,同步任务每 10 分钟运行一次,每个未知名称永久占用内存。 风险: 长期内存泄漏

3.2 所有房间启动时全部加载

文件: libs/room/src/service/workers.rs:30 描述: 服务启动时执行 room::Entity::find().all(&db) 加载所有房间,并为每个房间 spawn 一个 tokio 任务。如果有数千个房间,会创建数千个 tokio 任务和 Redis pubsub 连接。 风险: 大实例时资源耗尽

3.3 issue_summary 竞态条件

文件: libs/service/issue/issue.rs:581 描述: closed = total - open 通过两次独立的 count 查询计算,如果两次查询之间有 Issue 状态变化closed 可能为负数或不精确。 风险: 统计数据错误

3.4 Provider/Model 同步 Race Condition

文件: libs/service/agent/sync.rs:231,271 描述: 更新后重新查询 Provider/Model.unwrap() 假设记录一定存在。如果并发删除发生在两次查询之间,会 panic。 风险: 同步任务因 panic 中断

3.5 Workspace 成员查询 panic

文件: libs/service/workspace/info.rs:162 描述: memberships.iter().find(|m| ...).unwrap() — 如果 Workspace 存在但 membership 在两次查询之间被删除会 panic。 风险: 幽灵 panic

3.6 Workspace 设置 panic

文件: libs/service/workspace/settings.rs:39 描述: m.id.clone().unwrap() — 如果 ActiveModel 的 id 字段为 NotSet(非正常流程但可能),会 panic。 风险: 设置页面 panic

3.7 AI 任务生命周期静默失败

文件: libs/room/src/service/workers.rs:201,214,228 描述: let _ = task_service.start(task_id).await — 如果 start/complete/fail 操作失败AI 任务在数据库中的状态可能永远停留在 "Running",错误不可见。 风险: AI 任务"幽灵任务"、追踪不可靠

3.8 Room 事件发布到队列失败静默丢弃

文件: libs/room/src/room.rs:215-218,293-296,308-311,381-384 描述: let _ = self.queue.publish_project_room_event(...) — 房间创建/重命名/移动/删除事件在失败时被丢弃,前端不会收到通知。 风险: UI 状态与后端不一致

3.9 Issue 活动日志静默失败

文件: libs/service/issue/issue.rs:265,345,441,540 描述: let _ = self.project_log_activity(...) — Issue 变更活动日志在失败时静默丢弃。 风险: 审计日志缺失

3.10 全文索引更新 SQL 失败静默忽略

文件: libs/room/src/connection.rs:864 描述: let _ = db.execute_raw(stmt).await — PostgreSQL 全文索引更新 SQL 执行失败完全不可见。 风险: 内容搜索失效无感知

3.11 前端 activeRoomId 不响应 URL 变化

文件: src/contexts/room-context.tsx:194 + src/app/project/room.tsx:191 描述: RoomProvideruseState(initialRoomId) 初始化 activeRoomId,但 useState 只使用初始值,不响应 prop 变化。浏览器前进/后退、直接 URL 输入在已加载的应用中无法切换房间。 风险: URL 导航失效、用户体验受损

3.12 前端 deleteRoom 重复导航

文件: src/app/project/room.tsx:81-93 + 对应 context 方法 描述: deleteRoom 在 context 内部已调用 setActiveRoom(null)(触发一次导航),调用方又调用一次 — 同一操作导航两次。 风险: 重定向竞争、历史栈污染

3.13 前端 callback 覆盖冲突

文件: src/hooks/useTypingIndicator.ts:113-122 + src/hooks/useNotification.ts:160-164 描述: wsClient.updateCallbacks() 使用 Object.assign 覆盖回调。多个组件同时使用时,后注册的覆盖前者,第一个组件的回调在卸载时清除所有已注册回调。 风险: 多组件场景下回调丢失

3.14 前端 Context 中 Ref 依赖不触发更新

文件: src/contexts/room-context.tsx:1467 描述: useMemo 依赖数组包含 wsClientRef.currentref 值),但 ref 变化不触发重渲染,导致 context 提供过时的 wsClient 值。 风险: Stale closure / 组件使用过时 WebSocket 客户端


四、低危 (LOW) — 12 个

4.1 前端 API 错误处理缺失

  • 文件: src/contexts/room-context.tsx:1025-1086sendMessage 发送失败后重试时内容永久丢失
  • 文件: src/contexts/room-context.tsx:1002-1009removeMember 无 catch
  • 文件: src/contexts/room-context.tsx:1012-1020updateMemberRole 无 catch
  • 文件: src/components/room/RoomMessageSearch.tsx:48 — 搜索失败仅 console.error

4.2 前端类型安全缺失 ( any 类型滥用)

  • 10+ 文件使用 (resp.data as any)?.data 绕过类型检查
  • src/components/room/DiscordChatPanel.tsx:504messages={messages as any}

4.3 前端登录页 Captcha 缺失验证

  • 文件: src/app/auth/login-page.tsx:49 — 登录不检查 captcha 为空

4.4 前端 RepositoryContextProvider 加载时返回 null

  • 文件: src/contexts/repository-context.tsx:110 — 加载期间整个子组件树被卸载

4.5 前端编辑消息乐观更新回滚不完整

  • 文件: src/contexts/room-context.tsx:1096-1124 — 如果消息已从数组中移除rollback 被跳过

4.6 后端 Push 通知 unwrap

  • 文件: libs/service/lib.rs:65-67,246-248Option unwrap 在通知后台任务中

4.7 后端 Broadcast Channel 容量过大

  • 文件: libs/room/src/connection.rs:21BROADCAST_CAPACITY = 100_000 每个发送者持有,慢速/断开的 WS 客户端会导致内存无限制增长

4.8 后端 SSH 限流器未使用

  • 文件: libs/git/ssh/rate_limit.rsSshRateLimiter 类型定义存在但从未在 SSH handler 中实例化
  • 文件: apps/app/src/main.rs:195 — 生产环境应设为 true

4.10 后端无 CSRF 保护

  • 文件: apps/app/src/main.rs — API 用 cookie-based 认证但无 CSRF 防御

4.11 后端贡献日期 unwrap

  • 文件: libs/service/user/chpc.rs:81-82 — 日期范围边界不够安全

4.12 前端 UniversalWsClient 无 heartbeat / 无 jitter

  • 文件: src/lib/universal-ws.ts — 缺少心跳检测死连接,重连无 jitter惊群效应

五、总结

严重级别 数量 主要分布
Critical 4 认证缺失、CORS错误配置、路径遍历、事务缺失
High 8 LFS认证缺陷、Mutex中毒、XSS、锁泄漏、Redis阻塞、Token暴露
Medium 14 内存泄漏、竞态条件、静默错误丢弃、前端导航Bug、回调冲突
Low 12 错误处理缺失、类型安全、配置问题
总计 38

最严重文件排行

文件 Bug 密度 关键问题
libs/room/src/connection.rs 极高 SQL注入风险、Redis KEYS阻塞、broadcast容量、静默SQL错误
libs/room/src/service/ai_react_streaming.rs 极高 7处Mutex.unwrap()、fire-and-forget任务
libs/room/src/room_ai_queue.rs Drop中tokio::spawn、锁释放失败
src/contexts/room-context.tsx 极高 URL不同步、重复导航、Ref依赖问题、状态竞态
src/app/search/page.tsx 存储型XSS
libs/service/issue/issue.rs 级联删除无事务、issue_summary竞态
libs/service/agent/sync.rs Box::leak内存泄漏、race condition panic
apps/app/src/main.rs CORS+credentials漏洞、Session cookie insecure、无CSRF

建议优先修复

  1. CORS allow_any_origin + credentials 已修复 (commit bdb5393)
  2. 搜索结果 XSS 已修复 (commit bdb5393)
  3. issue 级联删除加事务 已修复 (commit bdb5393)
  4. git_init 端点加认证 已修复 (commit bdb5393)
  5. RoomAiLockGuard Drop 已修复 (commit bdb5393)
  6. Mutex 替换为 tokio::sync::Mutex 已修复 (commit bdb5393)

修复状态详情

严重 (CRITICAL) — 全部

# Bug 状态 Commit
1.1 git init 端点无认证 已修复 bdb5393
1.2 CORS allow_any_origin + credentials 已修复 bdb5393
1.3 存储路径遍历 已修复 bdb5393
1.4 issue 级联删除无事务 已修复 bdb5393

高危 (HIGH) — 全部

# Bug 状态 Commit
2.1 LFS 硬编码 token 已修复 (UUID now_v7) bdb5393
2.2 X-User-Uid 头注入 已修复 (从 Bearer token 解析) bdb5393
2.3 Mutex 中毒 已修复 (poison recovery) bdb5393
2.4 Drop 中 tokio::spawn 已修复 (runtime handle 回退) bdb5393
2.5 Redis KEYS 阻塞 已修复 (SCAN 替代) bdb5393
2.6 XSS dangerouslySetInnerHTML 已修复 (escapeHtml) bdb5393
2.7 WS Token URL 暴露 已修复 (同源不用URL传token) cce9d21
2.8 SSH Shell unwrap panic 已修复 (match 替代 unwrap) bdb5393

中危 (MEDIUM) — 全部

# Bug 状态 Commit
3.1 Box::leak 内存泄漏 已修复 (String 替代 &'static str) bdb5393
3.2 所有房间启动加载 已修复 (limit 1000) cce9d21
3.3 issue_summary 竞态 已修复 (三次独立查询) bdb5393
3.4 Provider/Model race 已修复 (直接返回更新结果) bdb5393
3.5 Workspace 成员 panic 已修复 (filter_map 替代 unwrap) bdb5393
3.6 Workspace 设置 panic 已修复 (提取 ws_id) bdb5393
3.7 AI 任务静默失败 已修复 (tracing::warn) bdb5393
3.8 Room 事件静默丢弃 已修复 (tracing::warn) bdb5393
3.9 Issue 活动日志静默失败 已修复 (tracing::warn) bdb5393
3.10 全文索引 SQL 静默失败 已修复 (tracing::warn) bdb5393
3.11 activeRoomId 不响应 URL 已修复 (useEffect sync) bdb5393
3.12 deleteRoom 重复导航 已修复 (移除重复调用) bdb5393
3.13 callback 覆盖冲突 已修复 (跳过 undefined) bdb5393
3.14 Ref 依赖不触发更新 已修复 (wsClient state) bdb5393

低危 (LOW) — 全部

# Bug 状态 Commit
4.1 sendMessage 错误处理 已有 isOptimisticError 标记 N/A
4.2 as any 类型滥用 部分修复 (移除已知类型) bdb5393
4.3 登录页 Captcha 缺失 已修复 (验证非空) bdb5393
4.4 RepositoryContextProvider null 已修复 (placeholder) bdb5393
4.5 编辑消息回滚不完整 已修复 (增加 warn) bdb5393
4.6 Push 通知 unwrap 已修复 (let-chain) e96bb29
4.7 Broadcast 容量过大 已修复 (100K→1000) bdb5393
4.8 SSH 限流器未使用 已修复 (SSHServer 中接入) cce9d21
4.9 Cookie Secure false 已修复 (true) bdb5393
4.10 无 CSRF 保护 已确认 (SameSite::Lax + Secure) N/A
4.11 贡献日期 unwrap 已修复 (and_hms_opt 安全) bdb5393
4.12 WS 无 heartbeat/jitter 已修复 (ping + jitter) bdb5393

额外发现

  • removeMember/updateMemberRole 无 catch — 已修复 (try/catch)
  • branch_count as any 已修复 (移除)
  • cookie_secure(true) 已修复
  • CORS 配置化 origins — 已修复 (环境变量 CORS_ORIGINS)