143 lines
8.1 KiB
Markdown
143 lines
8.1 KiB
Markdown
# 项目审查问题清单
|
|
|
|
审查日期:2026-05-01
|
|
|
|
本文档用于记录当前项目中已发现的高风险问题,并作为后续逐项修复的跟踪清单。状态说明:
|
|
|
|
- `待处理`:尚未开始修复。
|
|
- `处理中`:已经开始改动或验证。
|
|
- `已修复`:代码已修复并通过基本验证。
|
|
- `暂缓`:因演示环境、硬件依赖或其他原因暂不处理。
|
|
|
|
## 1. 优先级概览
|
|
|
|
| 编号 | 优先级 | 状态 | 模块 | 问题 |
|
|
| --- | --- | --- | --- | --- |
|
|
| R-001 | P0 | 已修复 | 服务端 | 公网接口无鉴权且允许任意来源 |
|
|
| R-002 | P0 | 部分修复 | 全项目 | 明文密钥和凭据已进入项目文件 |
|
|
| R-003 | P1 | 已修复 | 服务端 | `face_id` 可造成路径穿越写读删文件 |
|
|
| R-004 | P1 | 已修复 | 服务端 | 大请求体会被静默截断 |
|
|
| R-005 | P1 | 已修复 | 服务端 / Qt | CSV/JSON 没有转义会破坏数据和响应 |
|
|
| R-006 | P1 | 已修复 | STM32 固件 | `sscanf` 未限制宽度,UART 输入可溢出栈缓冲 |
|
|
| R-007 | P2 | 已修复 | 服务端 | 多个 `std::stoi` 可被非法参数打崩服务线程 |
|
|
| R-008 | P2 | 已修复 | Qt 管理端 | 删除人脸 URL 未编码 |
|
|
|
|
## 2. 详细问题
|
|
|
|
### R-001 公网接口无鉴权且允许任意来源
|
|
|
|
- 优先级:P0
|
|
- 状态:已修复
|
|
- 位置:`server/server_encrypted.cpp:1666`
|
|
- 影响:服务端暴露清空记录、删除人脸、上传映射、上传照片等写操作,但没有鉴权;响应固定允许任意跨域来源。只要端口可访问,外部请求就可能改写或删除考勤数据。
|
|
- 建议处理:
|
|
1. 给所有写接口增加 API Token 或签名校验。
|
|
2. 按部署环境限制 CORS 来源,不再使用通配符。
|
|
3. 公网部署时使用 HTTPS 和反向代理鉴权。
|
|
4. 将管理类接口与设备上传接口区分权限。
|
|
- 本次处理:主服务端 `server/server_encrypted.cpp` 已增加 `X-Api-Token` 校验,健康检查和 OPTIONS 预检除外;CORS 来源改为 `ATTENDANCE_CORS_ORIGIN` 配置,默认仅本地来源。Qt、STM32、K210 请求均已补 `X-Api-Token`。
|
|
|
|
### R-002 明文密钥和凭据已进入项目文件
|
|
|
|
- 优先级:P0
|
|
- 状态:部分修复
|
|
- 位置:`k210/main.py:34`、`User/main.c:23`、`QT/qml/Main.qml:2725`、`server/attendance.log`
|
|
- 影响:项目文件中包含 WiFi 密码、公网服务地址、固定 AES Key/IV、查看账号密码、日志中的疑似 API Key 等敏感信息。泄露后即使代码修复,旧凭据仍可能被继续使用。
|
|
- 建议处理:
|
|
1. 立即轮换已暴露的 WiFi 密码、API Key、演示账号密码和 AES Key/IV。
|
|
2. 将服务地址、WiFi、Token 等改为外部配置文件或烧录参数。
|
|
3. 日志输出中屏蔽敏感请求头。
|
|
4. 清理已有日志文件中的敏感内容。
|
|
- 本次处理:主链路代码和文档中的 WiFi 密码、公网地址改为占位配置;日志中的疑似 API Key 已脱敏;Qt 默认服务地址改为本机地址。仍需在真实环境中轮换已暴露的 WiFi、API Key、演示账号和 AES Key/IV。
|
|
|
|
### R-003 `face_id` 可造成路径穿越写读删文件
|
|
|
|
- 优先级:P1
|
|
- 状态:已修复
|
|
- 位置:`server/server_encrypted.cpp:837`
|
|
- 影响:`face_id` 直接来自 URL 并拼接成 `faces/<face_id>.jpg`,用于写入、读取和删除。包含路径分隔符或 `..` 时,可能越过 `faces` 目录操作其他文件。
|
|
- 建议处理:
|
|
1. 增加 `face_id` 白名单校验,只允许数字、字母、下划线、短横线等明确字符。
|
|
2. 对最终路径做规范化检查,确认仍位于 `faces` 目录下。
|
|
3. 所有照片读写删入口共用同一个安全路径构造函数。
|
|
- 本次处理:主服务端已增加 `isSafeId` 与 `buildFacePhotoPath`,照片读写删和重命名路径统一走安全 ID 校验。
|
|
|
|
### R-004 大请求体会被静默截断
|
|
|
|
- 优先级:P1
|
|
- 状态:已修复
|
|
- 位置:`server/server_encrypted.cpp:1228`
|
|
- 影响:读取 POST body 时,如果剩余数据超过约 40KB,循环不会继续读取,导致照片或配置内容被截断。K210 JPEG 上传很容易触发该问题。
|
|
- 建议处理:
|
|
1. 按 `Content-Length` 循环读取完整 body。
|
|
2. 设置明确最大请求大小,例如照片接口单独允许更大上限。
|
|
3. 超限时返回 HTTP 413。
|
|
4. 对读取不足的请求返回 400,不保存半截文件。
|
|
- 本次处理:主服务端按 `Content-Length` 读取完整请求体,普通 JSON 请求限制 64KB,照片请求限制 512KB,超限返回 413,读取不足返回 400。
|
|
|
|
### R-005 CSV/JSON 没有转义会破坏数据和响应
|
|
|
|
- 优先级:P1
|
|
- 状态:已修复
|
|
- 位置:`server/server_encrypted.cpp:459`、`QT/src/AppController.cpp:284`、`QT/src/AppController.cpp:317`
|
|
- 影响:签到记录直接用逗号拼 CSV,读取时也直接按逗号拆,再手写 JSON 字符串。姓名、状态、班级等字段包含逗号、引号、换行或反斜杠时,会导致 CSV 列错位、JSON 非法或 Qt 解析失败。
|
|
- 建议处理:
|
|
1. 服务端增加 CSV 字段转义和解析函数。
|
|
2. 服务端 JSON 响应统一经过 JSON 转义函数。
|
|
3. Qt 导出 CSV 时对每个字段做标准 CSV 转义。
|
|
4. 使用 SQLite 替代 CSV/多 JSON 文件,减少数据状态不一致。
|
|
- 本次处理:主服务端增加 CSV 解析/转义和 JSON 转义;Qt 导出 CSV 已对字段做标准转义;后端主存储已迁移到 `attendance.db`,旧 CSV/JSON 仅作为首次导入来源。
|
|
|
|
### R-006 `sscanf` 未限制宽度,UART 输入可溢出栈缓冲
|
|
|
|
- 优先级:P1
|
|
- 状态:已修复
|
|
- 位置:`Hardware/K210_USART.c:80`
|
|
- 影响:`%[^,]` 没有宽度限制,但目标缓冲只有 `id[20]` 和 `name[32]`。串口收到异常长字段时可能覆盖栈内存,造成固件异常。
|
|
- 建议处理:
|
|
1. 将格式改为 `%19[^,]`、`%31[^,]`。
|
|
2. 对接收缓冲做最大帧长、换行结束符和字段合法性校验。
|
|
3. 异常帧直接丢弃并清空缓冲。
|
|
- 本次处理:`Hardware/K210_USART.c` 和示例文件中的 `sscanf` 已增加字段宽度限制。
|
|
|
|
### R-007 多个 `std::stoi` 可被非法参数打崩服务线程
|
|
|
|
- 优先级:P2
|
|
- 状态:已修复
|
|
- 位置:`server/server_encrypted.cpp:1310`
|
|
- 影响:`limit`、`offset`、时间段参数直接调用 `std::stoi`,没有异常捕获和范围校验。非法请求参数可能让请求处理线程异常终止。
|
|
- 建议处理:
|
|
1. 增加安全整数解析函数。
|
|
2. 参数非法时返回 400。
|
|
3. 限制 `limit`、`offset` 和时间范围。
|
|
4. 所有 URL 参数统一走校验函数。
|
|
- 本次处理:主服务端已增加安全整数和时间解析,`limit`、`offset`、时间段和记录时间解析不再直接裸用 `std::stoi`。
|
|
|
|
### R-008 删除人脸 URL 未编码
|
|
|
|
- 优先级:P2
|
|
- 状态:已修复
|
|
- 位置:`QT/src/ApiClient.cpp:453`
|
|
- 影响:Qt 端删除人脸时直接把 `studentId` 拼进路径。如果学号包含空格、`#`、`?`、`/` 或中文,URL 会被截断或路由错乱。
|
|
- 建议处理:
|
|
1. 使用 `QUrl::toPercentEncoding` 编码路径段。
|
|
2. 服务端接收后进行 URL 解码和 ID 校验。
|
|
3. 为删除人脸接口补充异常 ID 的测试用例。
|
|
- 本次处理:Qt 删除人脸路径段已使用 `QUrl::toPercentEncoding` 编码。
|
|
|
|
## 3. 建议修复顺序
|
|
|
|
1. 处理 R-002:轮换凭据,清理敏感日志,避免继续泄露。
|
|
2. 处理 R-001:服务端写接口增加鉴权,限制跨域来源。
|
|
3. 处理 R-003、R-004:修复文件路径安全和请求体读取,防止文件被覆盖或照片损坏。
|
|
4. 处理 R-006:修复固件串口解析溢出风险。
|
|
5. 处理 R-005:统一 CSV/JSON 转义,避免数据格式破坏。
|
|
6. 处理 R-007、R-008:增强参数健壮性和 Qt URL 构造。
|
|
|
|
## 4. 验证记录
|
|
|
|
- `k210/main.py`、`k210/view_attendance.py` 已通过普通 Python 语法检查;MaixPy 运行时仍需上板验证。
|
|
- `server/server_encrypted.cpp` 因当前本机缺少 OpenSSL 头文件,未完成语法编译验证。
|
|
- 现有 Keil 构建日志显示固件旧构建为 `0 Error(s), 0 Warning(s)`,但尚未在本次审查中重新编译固件。
|
|
- 2026-05-01:已完成主链路安全修复;旧版备用服务端与测试脚本已清理,避免误部署非鉴权接口。
|