Files
erp/docs/audits/audit-2026-04-18.md
iven 841766b168
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled
fix(用户管理): 修复用户列表页面加载失败问题
修复用户列表页面加载失败导致测试超时的问题,确保页面元素正确渲染
2026-04-19 08:46:28 +08:00

6.4 KiB
Raw Blame History

系统全面审计报告 — 2026-04-18

审计环境

项目
PostgreSQL 18 (原生安装 D:\postgreSQL), 端口 5432
Redis 未安装/未运行 (限流改为 fail-open 降级)
后端 Axum 0.8, 端口 3000
前端 Vite 8, 端口 5174
操作系统 Windows 11 Pro

P0 — 严重问题(必须立即修复)

1. CRM 插件数据 403 Forbidden — 已修复

现象: 所有 CRM 数据页面(客户、联系人、沟通记录等)返回 403 错误,页面显示"加载数据失败"。

根因: CRM 插件在安装时正确注册了 9 条权限到 permissions 表(erp-crm.customer.list 等),但 没有自动将这些权限分配给 admin 角色。导致 JWT 中只有 plugin.adminplugin.list,缺少 erp-crm.* 权限。

修复: 在 erp-plugin/src/service.rs 中新增 grant_permissions_to_admin() 函数,在 install()enable() 中自动调用。修复后 CRM 客户列表 API 正常返回数据。

2. CRM 插件启动恢复失败 — 已修复

现象: 后端日志 Failed to recover plugin (initialize): 数据库错误: 关系 "plugin_erp_crm_inventory_item" 不存在

根因: CRM 插件的 on_init 回调尝试创建 inventory_item 实体的种子数据,但该表不存在。可能是 CRM 插件 WASM 代码中的实体定义与数据库迁移不匹配。

影响: 服务器重启后 CRM 插件恢复失败,Plugins recovered: 0

修复: 通过升级 API 重新上传正确的 CRM WASM 二进制22KB 替换错误的 110KB 测试插件)。修复后插件正常恢复并运行。

3. 首页统计数据卡片永久 Loading

现象: 工作台首页 4 个统计卡片(用户总数、角色数量、流程实例、未读消息)显示 loading 状态(busy 属性),数字不显示。

根因: 首页统计卡片使用 useCountUp 动画但依赖数据加载,数据加载可能失败或 API 返回格式不匹配。

4. 插件 API 路由不支持字符串 ID

现象: /api/v1/plugins/erp-crm/customer 返回 UUID parsing failed

根因: 后端路由定义 Path<(Uuid, String)>,要求 plugin_id 必须是 UUID 格式。但插件的 manifest ID 是字符串(如 erp-crm)。

影响: 直接用 manifest ID 调用 API 不行,必须先查 UUID。前端已绕过此问题使用 UUID但 API 设计不够友好。

P1 — 高优先级问题

5. XSS: 显示名未转义存储

现象: POST /api/v1/usersdisplay_name 字段可以存储 <script>alert(1)</script>API 返回原样值。

评估: React 框架自动转义防止了前端 XSS。但数据库中存储了原始 HTML如果有其他客户端如邮件、导出 PDF 等)不转义渲染,仍存在风险。

建议: 后端入库时 strip HTML tags 或 escape。

6. 重复用户名检测缺失

现象: POST /api/v1/usersaudit_test_user 创建两次,第二次也返回 success: true,没有报重复错误。

评估: 第二次创建返回的 id 不同但 username 相同,说明用户名唯一性约束可能没生效。

7. 消息模板 API 返回空

现象: GET /api/v1/messages/templates 返回空 body非 JSON

根因: 可能数据库无模板数据,且空列表情况下序列化异常。

8. 主题 API 返回空

现象: GET /api/v1/config/theme 返回空 body。

9. roles/permissions 路由冲突 — 已修复

现象: GET /api/v1/roles/permissions 返回 UUID 解析错误。

根因: 路由 GET /roles/{id}permissions 当成 UUID 解析了。

修复: 在 erp-auth/src/module.rs 中,在 /roles/{id} 之前注册 /roles/permissions 精确匹配路由。修复后返回 64 条权限数据。

P2 — 中优先级问题

10. CRM 插件恢复后 Plugin recovered: 0

后端日志显示插件加载成功但 recovery 报 0。on_init 失败导致插件状态变为 error但实际插件 WASM 已加载到内存。

11. 创建用户时中文 display_name 解析失败

POST /api/v1/usersdisplay_name 含中文字符时,返回 invalid unicode code point。可能与 curl 的编码有关而非后端 bug需要进一步验证。

12. 菜单数据为空

GET /api/v1/config/menus 返回空数组。系统侧边栏菜单是前端硬编码的,后端菜单配置未使用。

13. 数据字典为空

GET /api/v1/config/dictionaries 返回空。这是正常的(未创建字典数据)。

P3 — 低优先级 / 代码质量

14. 前端死代码

  • src/pages/plugins/graph/ 6 个文件完全未使用
  • src/hooks/ 下 4 个 Hook 未被任何组件引用useDarkMode, useDebouncedValue, usePaginatedData, useApiRequest
  • useCountUp 在 3 处重复定义

15. i18n 已配置但完全未使用

i18next 已初始化,翻译文件有 30 个 key但所有页面组件硬编码中文。

16. 暗色模式检测逻辑重复 20+ 次

const isDark = token.colorBgContainer === '#111827' 在 20+ 组件中重复,已有 useDarkMode Hook 但未使用。

17. antd 废弃 API 警告

  • Drawerwidth 属性已废弃
  • ModaldestroyOnClose 已废弃
  • message 静态方法无法消费 context

安全测试结果

测试项 结果
无 token 访问 401 Unauthorized
错误 token 401 Unauthorized
错误密码登录 401 Unauthorized
空请求体登录 反序列化错误(非 500
短密码验证 400 Bad Request + 详细验证信息
SQL 注入(用户名) JSON 解析失败(被拦截)
XSS(显示名) 存储了原始 HTML需后端过滤
权限不足操作 403 Forbidden

正常工作的功能

  • 登录/登出/Token 刷新
  • 用户 CRUD创建/列表/删除)
  • 角色 CRUD + 权限查看
  • 组织架构三栏管理
  • 工作流定义列表/待办任务
  • 消息列表/已读/未读计数
  • 审计日志记录
  • 插件管理(上传/启用/停用)
  • 系统设置 Tab 页(字典/语言/菜单/编号/主题/参数/审计/密码)
  • OpenAPI 文档端点

下一步工作建议

  1. P0-1: 修复插件权限自动分配给 admin 角色
  2. P0-2: 修复 CRM 插件 on_init 中 inventory_item 表不存在的问题
  3. P0-3: 修复首页统计卡片数据加载
  4. P1-5: 后端 display_name HTML 过滤
  5. P1-6: 用户名唯一性约束
  6. P1-9: 修复 roles/permissions 路由冲突
  7. 更新所有相关文档wiki/插件系统文档)