# 游戏小组管理系统后端项目 - 问题评估报告 ## 📋 报告概述 **项目名称**: GameGroup Backend **评估日期**: 2026-01-28 **评估范围**: 项目架构、实现方式、操作逻辑、防呆措施、安全性 **总体评价**: ⚠️ 项目基础架构良好(NestJS模块化),但在安全性(尤其是认证、加密和隐私保护)和并发处理方面存在高危漏洞,必须在上线前修复。 --- ## 🔴 严重问题(高危 - 必须修复) ### 1. 用户隐私严重泄露 (IDOR) ⚠️⚠️⚠️ **位置**: [src/modules/users/users.controller.ts](src/modules/users/users.controller.ts:23-28) **问题描述**: - `UsersController.findOne` 接口允许任意已登录用户通过 ID 查询其他用户的详细信息。 - `UsersService.findOne` 返回的数据包含 `email`、`phone` 等敏感个人隐私信息。 **安全风险**: - 恶意用户可以遍历 ID 窃取所有用户的手机号和邮箱。 - 违反隐私保护法规(如 GDPR/PIPL)。 **修复建议**: 1. `findOne` 接口仅返回非敏感公开信息(如昵称、头像、ID)。 2. 敏感信息的查询应仅限于 `me` 接口或管理员权限接口。 ### 2. JWT密钥配置存在严重安全隐患 ⚠️⚠️⚠️ **位置**: [src/config/jwt.config.ts](src/config/jwt.config.ts:4-6) **问题描述**: ```typescript secret: process.env.JWT_SECRET || 'default-secret', refreshSecret: process.env.JWT_REFRESH_SECRET || 'default-refresh-secret', ``` - 使用了硬编码的默认密钥作为 fallback。 - 生产环境若忘记配置环境变量,系统将极易被攻破。 **安全风险**: - 攻击者可使用默认密钥伪造任意身份(包括管理员)的 Token,完全接管系统。 **修复建议**: 1. 移除默认密钥 fallback,强制要求环境变量存在,否则启动失败。 2. 启动时检查密钥强度(长度至少32字符)。 ### 3. 资产账号凭据加密实现不安全 ⚠️⚠️⚠️ **位置**: [src/modules/assets/assets.service.ts](src/modules/assets/assets.service.ts:20-58) **问题描述**: - 使用 `padEnd(32, '0')` 进行密钥派生,极其脆弱。 - 使用硬编码默认密钥 `default-key-change-in-production`。 - 缺乏 HMAC 完整性校验。 **安全风险**: - 存储的游戏账号密码等资产凭据极易被破解泄露。 **修复建议**: 1. 移除默认密钥,强制环境变量。 2. 使用安全的密钥派生函数(PBKDF2/Argon2)或直接使用 32 字节强随机密钥。 3. 增加 HMAC 校验或使用 AES-GCM 模式。 ### 4. CORS 配置过于宽松且缺乏 CSRF 保护 ⚠️⚠️⚠️ **位置**: [src/main.ts](src/main.ts:30-66) **问题描述**: ```typescript if (!origin || corsOrigin === '*') { callback(null, true); } // ... credentials: true ``` - 允许 `credentials: true` 的同时,逻辑上允许了任意 Origin(虽然标准禁止 `*` 与 credentials 共用,但代码通过反射 Origin 绕过了限制)。 - 未启用 CSRF Token 保护。 **安全风险**: - 如果前端使用 Cookie 存储 Token,将面临严重的 CSRF 攻击风险。 - 即使使用 Bearer Token,宽松的 CORS 也增加了其他跨域攻击面的风险。 **修复建议**: 1. 生产环境严格限制 `corsOrigin` 为特定域名白名单。 2. 如果使用 Cookie,必须引入 `csurf` 中间件或类似机制。 --- ## 🟠 重要问题(中危 - 建议修复) ### 5. 竞猜下注存在并发 Race Condition ⚠️⚠️ **位置**: [src/modules/bets/bets.service.ts](src/modules/bets/bets.service.ts:64-100) **问题描述**: - 余额检查与扣款之间存在时间差(Check-Then-Act)。 - 虽然使用了事务,但未见显式的悲观锁(`FOR UPDATE`)或乐观锁机制。 **风险**: - 高并发下可能导致用户余额扣减成负数,或超出余额下注。 **修复建议**: 1. 查询余额时使用 `setLock('pessimistic_write')`。 2. 或在扣款 SQL 中增加条件 `WHERE balance >= :amount`。 ### 6. 缺少暴力破解防护机制 ⚠️⚠️ **位置**: [src/modules/auth/auth.controller.ts](src/modules/auth/auth.controller.ts) **问题描述**: - 登录、注册接口无速率限制(Rate Limiting)。 - 无验证码机制。 **风险**: - 账号密码易被暴力破解。 - 短信/邮件接口(如果有)可能被刷量。 **修复建议**: 1. 引入 `@nestjs/throttler` 进行接口限流。 2. 登录失败多次后暂时锁定账号。 ### 7. Refresh Token 缺乏撤销机制 ⚠️⚠️ **位置**: [src/modules/auth/auth.service.ts](src/modules/auth/auth.service.ts) **问题描述**: - 刷新 Token 后旧 Token 仍可能有效(取决于实现,但通常无黑名单)。 - 用户登出仅在前端清除,后端无状态无法强制登出。 **修复建议**: 1. 引入 Redis 存储 Refresh Token 白名单或黑名单。 2. 实现 Token Rotation(刷新即作废旧 Token)。 --- ## 🟡 优化建议(低危/代码质量) ### 8. 权限检查分散且依赖手动调用 **问题描述**: - 权限逻辑分散在各个 Service 的方法内部(如 `groups.service.ts` 的 `checkPermission`),而非通过统一的 Guard 或 Decorator 处理。 - 容易在新增接口时遗漏权限检查。 **修复建议**: - 实现基于 Casl 或自定义 Guard 的统一权限控制系统。 - 使用自定义装饰器(如 `@RequirePermission(Role.ADMIN)`)标记在 Controller 层。 ### 9. 数据库事务管理 **问题描述**: - 手动使用 `QueryRunner` 管理事务(如 `bets.service.ts`)代码冗余且易出错(忘记 release)。 **修复建议**: - 使用 TypeORM 的 `manager.transaction` 回调风格,或使用 `nestjs-cls` + Transactional 装饰器来简化事务管理。