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