6.4 KiB
系统全面审计报告 — 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.admin 和 plugin.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/users 时 display_name 字段可以存储 <script>alert(1)</script>,API 返回原样值。
评估: React 框架自动转义防止了前端 XSS。但数据库中存储了原始 HTML,如果有其他客户端(如邮件、导出 PDF 等)不转义渲染,仍存在风险。
建议: 后端入库时 strip HTML tags 或 escape。
6. 重复用户名检测缺失
现象: POST /api/v1/users 用 audit_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/users 带 display_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 警告
Drawer的width属性已废弃Modal的destroyOnClose已废弃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 文档端点
下一步工作建议
- P0-1: 修复插件权限自动分配给 admin 角色
- P0-2: 修复 CRM 插件 on_init 中 inventory_item 表不存在的问题
- P0-3: 修复首页统计卡片数据加载
- P1-5: 后端 display_name HTML 过滤
- P1-6: 用户名唯一性约束
- P1-9: 修复 roles/permissions 路由冲突
- 更新所有相关文档(wiki/插件系统文档)