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

86 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 代码审查报告(第二轮)
## 总体评价
**6.5/10** — 4个安全问题中3个彻底修复1个权限校验部分修复。构建全部通过文件拆分合理。但发现 **3个模块完全缺失权限校验**(🔴 高风险新发现问题)。
---
## 安全修复验证结果
| 问题 | 状态 | 说明 |
|------|------|------|
| **SQL注入** | ✅ 已修复 | `operation_logs.rs``charge_records.rs``energy_stats.rs``device_logs.rs` 全部使用 `.bind()` 参数化查询。`LIMIT/OFFSET` 通过 `i64` 类型转换后绑定。`build_where_clause` 中所有条件值均通过 `.bind()` 传入,无 `format!` 拼接用户输入到 SQL 的问题。 |
| **密码哈希** | ✅ 已修复 | `middleware/auth.rs:230-247` 使用 `argon2` 库实现 `hash_password` / `verify_password``users.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.rs``energy_stats.rs``device_logs.rs``operation_logs.rs` 均已集成。 |
| **权限校验** | ⚠️ 部分修复 | 大部分路由有 `check_permission`,但 **cabinets.rs、projects.rs、organizations.rs 三个模块完全缺失**(详见下方新发现问题)。 |
---
## 代码质量验证结果
| 项目 | 状态 | 说明 |
|------|------|------|
| **文件拆分** | ✅ | 后端 `organizations.rs` 242行≤300`users.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/options``GET /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.rs``list_cabinets` 只按 `project_id` 过滤** — 没有额外验证当前用户是否有权访问该项目。如果用户知道其他项目的 project_id可以绕过组织隔离。
---
## 总结
| 维度 | 结论 |
|------|------|
| SQL注入 | ✅ 已修复,全部使用 `.bind()` 参数化 |
| 密码哈希 | ✅ 已修复argon2 实现正确 |
| 数据隔离 | ✅ 已修复,组织过滤子查询正确 |
| 权限校验 | ⚠️ 部分修复3个模块缺失 |
| 构建 | ✅ 全部通过 |
| 文件拆分 | ✅ 合理,职责清晰 |
| JWT安全 | ✅ 启动时检测默认密钥 |
**核心结论4个安全问题中3个彻底修复1个权限校验需要补充 cabinets.rs / projects.rs / organizations.rs 三个模块。**