根因:app/utils/sendFile.js:36 的路径穿越防护用全 ASCII 白名单 /^[A-Za-z0-9_.\/-]+$/,把合法中文文件名(如 测试.xlsx)误判为非法 路径 ⇒ 400「非法文件路径」。该正则与同文件 :88 的 RFC 5987 (filename*=UTF-8''…)中文名支持自相矛盾 —— 中文名本是设计内支持。 影响面:sendFile 是统一文件出口,materials(备赛资料,磁盘保留原始 中文/全角名)/ exam(Word 模板)/ admin(作品·导出)三通道,其中 materials 重度受影响(选手侧直接可见);works 通道磁盘名 ASCII 化 (work_<ts>_<rand>.<ext>)不受影响。 修法:把安全判据从「字符集白名单」换成「危险形态黑名单(控制字符/ 反斜杠/绝对路径/.. 段)+ path.resolve 归一化后前缀校验(必须落在 app/public 内)」双层防护,不误伤 Unicode,且防穿越更硬。 验证:端到端(真后端 7001 + 真 DB)PASS=9/FAIL=0(中文名 200、 字节==磁盘 size、X-File-Size 哨兵一致);sendFile 守卫判别力自证 PASS=9/FAIL=0(5 类危险形态全 400、3 类合法 Unicode 放行); 既有门禁 verify_upload_download.py 16/16 通过。
6.9 KiB
6.9 KiB