charging-cabinet/tasks/review-round-2-report.md
2026-07-02 05:38:01 +08:00

5.6 KiB
Raw Blame History

代码审查报告(第二轮)

总体评价

6.5/10 — 4个安全问题中3个彻底修复1个权限校验部分修复。构建全部通过文件拆分合理。但发现 3个模块完全缺失权限校验🔴 高风险新发现问题)。


安全修复验证结果

问题 状态 说明
SQL注入 已修复 operation_logs.rscharge_records.rsenergy_stats.rsdevice_logs.rs 全部使用 .bind() 参数化查询。LIMIT/OFFSET 通过 i64 类型转换后绑定。build_where_clause 中所有条件值均通过 .bind() 传入,无 format! 拼接用户输入到 SQL 的问题。
密码哈希 已修复 middleware/auth.rs:230-247 使用 argon2 库实现 hash_password / verify_passwordusers.rs:249 创建用户时哈希,users.rs:384 重置密码时哈希,auth.rs:51 登录时验证。argon2 哈希字符串长度约 97 字符,远小于 VARCHAR(255)。
数据隔离 已修复 CurrentUser 包含 organization_id: Option<i64>org_condition()org_condition_for_logs() 在非总管理员时自动附加组织过滤子查询。总管理员跳过过滤。无组织用户返回 AND 1=0(空结果)。charge_records.rsenergy_stats.rsdevice_logs.rsoperation_logs.rs 均已集成。
权限校验 ⚠️ 部分修复 大部分路由有 check_permission,但 cabinets.rs、projects.rs、organizations.rs 三个模块完全缺失(详见下方新发现问题)。

代码质量验证结果

项目 状态 说明
文件拆分 后端 organizations.rs 242行≤300users.rs 497行职责集中可接受。前端 devices/index.tsx 359行 → 已拆分为 OrganizationTree.tsx(182行)、CabinetGrid.tsx(79行)、AddCabinetModal.tsx(134行),职责清晰。
构建检查 cargo check 通过(零报错零警告)。cargo clippy 通过(零报错零警告)。tsc --noEmit 通过(零报错零警告)。vite build 成功1045 modules1.3MB JS / 570KB CSS1.16s)。
JWT安全 config.rs:45-47 启动时检测默认密钥并打印 tracing::warn!middleware/auth.rs:33 定义了 JWT_SECRET_DEFAULT

🔴 新引入问题3处权限校验缺失

问题 1设备管理模块cabinets.rs— 全部 8 个端点无权限校验

路由 风险 建议
GET /api/projects/:project_id/cabinets 可查看任意项目下的柜子 check_permission("device:view")
POST /api/cabinets 可任意添加设备 check_permission("device:create")
PUT /api/cabinets/:id 可修改任意设备 check_permission("device:edit")
DELETE /api/cabinets/:id 可删除任意设备 check_permission("device:delete")
POST /api/cabinets/:id/regenerate-auth 可篡改设备安全码 check_permission("device:edit")
GET /api/cabinets/:id 可查看任意设备详情 check_permission("device:view")
GET /api/cabinets/options 可枚举所有设备 check_permission("device:view")
GET /api/cabin-boards/optionsGET /api/compartments/options 同上 check_permission("device:view")

问题 2项目管理模块projects.rs— 全部 4 个端点无权限校验

路由 风险 建议
GET /api/organizations/:org_id/projects 可查看任意项目 check_permission("project:view")
POST /api/organizations/:org_id/projects 可创建任意项目 check_permission("project:create")
PUT /api/projects/:id 可修改任意项目 check_permission("project:edit")
DELETE /api/projects/:id 可删除任意项目 check_permission("project:delete")

问题 3组织管理模块organizations.rs— 全部 4 个端点无权限校验

路由 风险 建议
GET /api/organizations 可枚举所有组织 check_permission("org:view")
POST /api/organizations 可创建组织 check_permission("org:create")
PUT /api/organizations/:id 可修改组织 check_permission("org:edit")
DELETE /api/organizations/:id 可删除组织 check_permission("org:delete")

其他观察(非阻塞)

  1. organizations.rs 缺少 CurrentUser 参数 — 三个模块的 handler 签名都是 State + Path/Json,没有提取 CurrentUser,所以无法做权限校验。这是结构性问题,需要在函数签名中加上 user: CurrentUser
  2. users.rs 用户列表查询缺少组织隔离list_users 返回所有用户,不受 CurrentUser.organization_id 限制。企业管理员可以看到其他组织的用户。
  3. cabinets.rslist_cabinets 只按 project_id 过滤 — 没有额外验证当前用户是否有权访问该项目。如果用户知道其他项目的 project_id可以绕过组织隔离。

总结

维度 结论
SQL注入 已修复,全部使用 .bind() 参数化
密码哈希 已修复argon2 实现正确
数据隔离 已修复,组织过滤子查询正确
权限校验 ⚠️ 部分修复3个模块缺失
构建 全部通过
文件拆分 合理,职责清晰
JWT安全 启动时检测默认密钥

核心结论4个安全问题中3个彻底修复1个权限校验需要补充 cabinets.rs / projects.rs / organizations.rs 三个模块。