P0 独立漏洞最小兼容方案

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/其他端不改

兼容边界

关键反向测试

未登录/过期Cookie拒绝,不读取文件
../、编码穿越、反斜杠混合拒绝
Unix/Windows/UNC绝对路径、file://拒绝
指向目录外的符号链接realpath边界失败
批量混入一个非法项整批失败,不生成ZIP
单文件响应文件名不含服务器路径
批量ZIP非Web目录生成,下载后删除

实施结果

代码提交faf17cfe0d68455e3a,已推送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增量契约已生成;真实导入待目标目录确认

代码开发完成不等于客户生产漏洞已关闭;以部署和复测证据为准。