
Yii 2.0.54 本身不直接引入本地文件读取漏洞,但若开发者在代码中不当使用用户输入拼接文件路径(如 file_get_contents()、include、readfile() 或模板渲染路径),就极易触发路径遍历(Path Traversal)类的任意文件读取漏洞。修复核心不是升级 Yii 版本,而是切断“用户输入 → 文件系统路径”的危险映射。
严格校验与约束文件路径参数
所有接收文件名、路径片段的接口(如 /api/download?id=123、/preview?file=report.pdf)必须做三重过滤:
-
白名单校验优先:只允许预定义的合法文件名或 ID,拒绝一切自由路径输入。例如用数据库查出真实文件路径:
$file = FileModel::findOne($id)?->path;,而非$file = $_GET['file']; -
路径规范化 + 目录约束:若必须处理路径参数,先调用
realpath()或yii\helpers\BaseFileHelper::normalizePath(),再检查是否落在授权目录内:strpos($realPath, Yii::getAlias('@webroot/uploads')) === 0 -
禁止双点与特殊编码:用
str_replace(['..', '%2e%2e', '%2E%2E'], '', $input)粗筛后仍需走前两步——因为绕过手段极多,不能依赖简单替换
禁用高危函数与动态包含
彻底移除代码中以下模式:
- 避免
include($_GET['tpl'])、require_once($configDir . '/' . $_POST['env'] . '.php')等动态加载逻辑 - 禁用
phar://、zip://、expect://等协议头,统一在入口层过滤:if (preg_match('/^([a-z][a-z0-9+.-]*):/i', $path)) { throw new BadRequestHttpException(); } - 模板引擎(如 Twig、Smarty)启用沙箱模式,禁用
include、loadTemplate等可读外部路径的指令
文件服务与业务逻辑彻底分离
不要让 Web 层直接操作磁盘路径,改用间接访问机制:
- 静态资源交由 Web 服务器(Nginx/Apache)直接托管,配置
location /uploads/ { alias /var/www/project/web/uploads/; },PHP 完全不参与路径解析 - 动态文件下载改用流式响应 + 内存缓冲:先查数据库确认权限和文件元信息,再用
Yii::$app->response->sendStreamAsFile(fopen($safePath, 'rb'), $filename) - 敏感配置、密钥、日志等文件严禁放在
@webroot可访问目录下;应置于@app/config或@runtime,并通过 Web 服务器规则禁止 HTTP 访问(如 Nginx 中加location ~ /\.(env|log|sql)$ { deny all; })
补充防御与验证手段
最后一道防线要可测量、可审计:
- 在全局中间件或基类控制器中记录所有文件操作请求(含原始参数、规范化路径、执行结果),接入 SIEM 做异常路径聚类告警
- 用自动化工具扫描代码:搜索
file_get_contents\(|fopen\(|include\(|require\(|readfile\(|copy\(|unserialize\(|eval\(|assert\(|system\(|exec\(|shell_exec\(|passthru\(|proc_open\(|popen\(|preg_replace.*\/e/i等高危函数调用 - 验证是否修复:构造
../../../../etc/passwd、%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd、phar://test.jpg/any.php等典型 payload,确认返回 400/403 而非文件内容或堆栈


















