System_Management/docs/audit-checklist.md
liuyun bb7c79b981 docs: 审计清单 H8/M21 完成 + guide 修正 JWT_SECRET
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 16:29:19 +08:00

6.8 KiB
Raw Blame History

脚手架审计整改清单

状态标记:⬜ 待处理 · 🔶 需讨论 · ✅ 已决定 · ✔ 已完成 顺序按批次(P0 安全堵漏 → P1 RBAC 闭环 → P2 会话加固 → P3 工程化契约)推进,序号即处理顺序,可调。

P0 安全越权堵漏

  • C1 跨租户越权 —— Tenant 表无租户过滤,任意租户超管可管全平台租户。✔ 已完成:super_admin=平台超管(保留)、tenant_super_admin=租户顶层(保留),tenant:* 仅平台租户可授予(constants.ts + roles.service 保留码校验 + 平台级权限剥离)
  • H1 软删与唯一约束冲突 —— 删后无法重建同名 → P2002 → 500。✔ 已完成:方案 B(BaseCrudService.softRemove 改名回收 #id,按列长截断)+ P2002→409
  • H2 删除角色不清理关联与缓存 —— user_role/role_resource/role_org 残留,聚合不校验已删角色。✔ 已完成:removeRole 级联清理 + 清缓存 + 保留角色禁删 + resolveAuth 过滤已删角色
  • H3 权限聚合缺 status 过滤 —— 停用资源仍被授权。✔ 已完成:resolveAuth 资源查询补 status='enabled'
  • H4 用户停用/删除后旧 token 仍可用 —— 守卫不查用户状态,缓存 TTL=7 天。✔ 已完成:方案 A(tokenVersion)+ JwtAuthGuard 每请求校验 + Redis 用户状态缓存
  • H5 重置密码不吊销会话 —— refresh token 不撤销。✔ 已完成:并入 H4,resetPassword/停用/删除 → invalidateSessions(tokenVersion++ + 删 refresh + 清缓存)
  • H6 角色资源树半选回显导致权限放大 —— 半选父节点被持久化 + 回显级联全选。✔ 已完成:只保存叶子键 getCheckedKeys(true) + 回显 setCheckedKeys(assigned, true)
  • H10 401 自动刷新无限循环 —— login/refresh 自身 401 也进刷新重放。✔ 已完成:_retry 标记 + 排除 login/refresh + 失败 reject
  • H11 data_scope self 语义错误 —— self 等同本部门;详情接口无数据权限。✔ 已完成:self 按 userId 过滤 + 详情 assertCanView 403
  • H13 seed 幂等副作用 —— 重跑重置管理员密码/启用账号。✔ 已完成:update 分支剥离 password/status
  • M1 日志脱敏不含 phone/email —— 违反 spec 安全红线。✔ 已完成:mask.ts 补充 phone/mobile/email
  • M6 JWT 密钥默认兜底值 —— 生产忘配置即可伪造 token。✔ 已完成:缺失/生产弱密钥直接拒绝启动
  • M8 pageSize 无上限 —— 可拉全表。✔ 已完成:@Max(200)
  • M9 DTO 枚举缺校验 —— status 裸 @IsString。✔ 已完成:全 DTO 加 @IsIn(UserStatus/CommonStatus/DataScope/ResourceType)
  • M10 Prisma 错误未映射 —— P2002/P2025 原文泄漏且 500。✔ 已完成:P2002→409、P2025→404、未知异常不泄漏内部细节
  • M11 assignResources 非事务 + 不校验 + :id 语义混淆 —— ✔ 已完成:事务化 + 角色存在性校验(:id 实为 roleCode,已注释说明)
  • M22 super_admin 可被租户自建 —— ✔ 已完成:并入 C1,RESERVED_ROLE_CODES 校验(super_admin / tenant_super_admin)
  • M4 组织树可成环 —— collectDescendants 死循环。✔ 已完成:create/update 防环校验 + collectDescendants visited 集合

P1 RBAC 闭环

  • H7 用户-角色分配缺失 —— 无端点/DTO/UI。✔ 已完成:GET/PUT /users/:id/roles + DTO + 前端分配角色表单 + 用户页入口
  • H9 按钮级权限未实现 —— 无下发接口/指令,导出按钮不存在。✔ 核心已完成:/auth/permissions 下发 + permission store + v-permission 指令 + ty-crud 权限过滤 + 用户页导出演示(role/audit/login-log 3 个导出按钮为同模式,待补)
  • M18 前端无路由级权限过滤 + 403 页 —— ✔ 已完成:路由守卫按可访问菜单 path 过滤 + 403 页(/403)
  • M21 数据权限覆盖面过窄 —— 仅用户列表。✔ 已完成(方案 A):组织树按可见部门过滤 + 审计/登录日志按操作人部门过滤;角色/字典/配置保持租户级
  • H8 注册/忘记密码是假功能 —— mock 假成功。✔ 已完成:注册真实化(POST /auth/register),注册/忘记密码默认隐藏(showRegister/showForgetPassword=false,fork 可开启)
  • M17 租户 onboarding 断裂 —— 新建租户不可用、删除留孤儿。方案:建租户初始化管理员+根组织+资源/字典模板
  • 新增 用户自助修改密码/个人资料 —— 缺失清单。方案:补端点 + 前端个人中心

P2 会话与安全加固

  • M5 登录安全基线缺失 —— 无锁定/后端验证码/密码策略。方案:先锁定+密码策略,验证码后置
  • M7 Swagger 无鉴权 + CORS 全开 + 无 helmet/限流 —— 方案:/docs 收口 + CORS 白名单 + helmet + 限流
  • M12 RefreshToken 哈希未校验 + 无清理 —— 方案:校验 hash + 过期清理任务
  • M14 401 强退后 authStore 失真 —— 方案:handler 里同步重置 authStore
  • M15 dictStore loaded 守卫无法刷新 —— 方案:fetch 加 force 参数
  • M20 登录租户写死 touyun —— 方案:恢复可配置租户输入框(🔶 需讨论,见 D5)
  • M3 created_by 全项目零写入 —— 方案:BaseCrudService.create 注入 created_by
  • L5 登出审计 username 写 null —— 方案:写入真实 username
  • L7 useRequest loading 竞态 + ty-crud 重复请求 —— 方案:请求序号/去重
  • L8 审计/登录日志、refresh_token 无清理任务 —— 方案:定时清理任务

P3 工程化契约

  • H12 e2e 必然失败 + 无业务测试 —— 方案:修 e2e + 补核心链路用例
  • M2 时间字段 ISO vs Unix 毫秒 —— 方案:API 层转 Unix 毫秒(🔶 需讨论,见 D4)
  • M16 vite olldownOptions 拼写错误 —— 方案:改 rolldownOptions
  • M19 前端 .env/.env.dev 入库 + .env.example 带像真密码 —— 方案:gitignore + 模板脱敏
  • L1 模板残留/无 LICENSE/stats.html 入库 —— 方案:清理 + 补 LICENSE
  • L2 启动 console.log 噪音 —— 方案:移除
  • L3 docs/requirements 空目录 + config/menu.ts 死代码 —— 方案:清理
  • L4 README 克隆命令与子模块风格不一致 —— 方案:统一
  • L6 ty-crud 取消确认 rejection 未捕获 —— 方案:catch
  • L9 @nestjs/mau 非常规依赖 —— 方案:核实来源/用途
  • L10 无 CI/Dockerfile/compose 部署编排 —— 方案:补 CI + 部署物料
  • 新增 spec 覆盖补全 —— users/roles/orgs/tenants/configs 与前端多页无 spec 锚点。方案:补主 spec