Files
bishe-STM32/docs/05_项目审查问题清单.md
T
2026-05-01 20:29:02 +08:00

8.1 KiB

项目审查问题清单

审查日期: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:已完成主链路安全修复;旧版备用服务端与测试脚本已清理,避免误部署非鉴权接口。