CODE-04 下载接口任意文件读取
VWCG-1239 · store/master_patch · 客户非Docker部署
根因去重结论:CODE-01、CODE-02、CODE-03都不能堵住本漏洞。Download控制器绕过登录并直接读取客户端路径,必须独立修改后端。
为什么前序修复无效
| 整改项 | 结论 | 原因 |
|---|---|---|
| CODE-01强密码 | 无效 | Download主动清空登录校验,匿名可调用。 |
| CODE-02上传白名单 | 无效 | 不需要上传文件,直接提交服务器现有路径。 |
| Nginx上传禁执行 | 无效 | 只禁止脚本执行,不阻止PHP应用读取文件。 |
| CODE-03脚本清理/轮换 | 无效 | 不改变Download接口的路径读取逻辑。 |
当前攻击链
匿名请求 /p/download/zip
→ beforeActionList = []
→ 手工解析 QUERY_STRING + urldecode
→ file_exists(客户端路径)
→ fopen / ZipArchive::addFile
→ 读取应用账号可访问的任意文件
最小改法
1. 恢复登录
只启用checkLogin,不贸然启用全部菜单权限校验;现有window.open会携带_token Cookie。
2. 安全路径
Request读取file_array,realpath后只允许public/static/upload内普通文件。
3. 安全文件流
单文件名只用basename,不回显服务器路径;错误统一脱敏。
4. 非Web临时ZIP
使用系统临时目录,归档不含绝对路径,完成或异常均清理。
修改范围
| 文件/对象 | 动作 |
|---|---|
application/p/controller/Download.php | 登录、参数解析、realpath边界、文件流、ZIP清理、ossZip对象键边界。 |
selectionTestForm.vue | 单文件路径encodeURIComponent,交互不变。 |
trainingExperience.vue | 单文件和批量每个路径分别编码,参数名不变。 |
| 安全/HTTP测试 | 合法、未登录、穿越、绝对路径、符号链接、批量非法项、临时ZIP清理。 |
| Apifox/OpenAPI | 改为PC登录Cookie认证、file_array必填、成功为二进制文件流。 |
| 路由/DB/SQL/Nginx/其他端 | 不改 |
兼容边界
- 保留
GET /p/download/zip。 - 保留
file_array和批量file_array[index]格式。 - 只允许现有页面传递的
static/upload/...路径,可兼容一个开头斜杠。 - 选材测试附件、训练经历单文件/批量下载必须正常。
- PC只修改两个调用点的URL编码;小程序、数据库、路由和客户Nginx不改。
关键反向测试
| 未登录/过期Cookie | 拒绝,不读取文件 |
| ../、编码穿越、反斜杠混合 | 拒绝 |
| Unix/Windows/UNC绝对路径、file:// | 拒绝 |
| 指向目录外的符号链接 | realpath边界失败 |
| 批量混入一个非法项 | 整批失败,不生成ZIP |
| 单文件响应 | 文件名不含服务器路径 |
| 批量ZIP | 非Web目录生成,下载后删除 |
实施结果
| 代码提交 | faf17cfe0、d68455e3a,已推送master_patch |
| 安全回归 | 41 tests / 134 assertions;下载专项10 tests / 18 assertions |
| HTTP回归 | 登录、二次校验、权限、密码/脱敏、下载路径5组场景通过 |
| 真实匿名请求 | 报告路径返回code=100“您尚未登录”,未读取文件 |
| PC构建 | Build complete |
| 证据包 | tests/reports/dengbao/20260818-VWCG-1239/总体passed |
尚需确认
| 批量上限 | 当前按50实现,确认训练经历实际最大文件数 |
| OSS | 新吴区是否启用及ossZip是否有调用 |
| 权限粒度 | 当前完成登录+目录边界,是否还要求绑定附件记录/人员权限 |
| 生产 | 客户非Docker部署、合法附件实页回归、PHP-FPM临时目录权限 |
| Apifox | 增量契约已生成;真实导入待目标目录确认 |
代码开发完成不等于客户生产漏洞已关闭;以部署和复测证据为准。