php目录遍历漏洞源于用户输入路径未经规范化和白名单校验即用于文件操作;修复需三重防护:realpath()路径标准化+根目录前缀校验、映射表替代动态拼接、扩展名与协议双重白名单,并辅以web服务器层禁目录浏览和上传目录禁php执行。

PHP目录遍历漏洞的核心问题在于:用户可控的路径参数未经严格校验,就被拼接到文件操作函数中(如 include、file_get_contents、fopen 或 opendir),导致攻击者用 ../、%2e%2e%2f 等方式跳出业务目录,读取甚至执行敏感文件。修复不是加一层过滤那么简单,而是要从输入、路径解析、文件访问三个环节同时设防。
强制路径规范化 + 根目录白名单校验
不能只用 str_replace 过滤 ../,因为绕过方式太多(URL编码、双字节、多斜杠等)。正确做法是:先用 realpath() 解析完整路径,再判断是否落在预期安全根目录内。
- 示例代码:
php
$user_input = $_GET['file'] ?? '';
$base_dir = realpath(APP_PATH . 'uploads/'); // 你允许访问的真实根目录
$target = realpath($base_dir . '/' . $user_input);
if ($target === false || strpos($target, $base_dir) !== 0) {
die('非法路径');
}
// 安全地使用 $target
?> - 关键点:必须用
realpath(),且比较时用strpos($target, $base_dir) === 0,不能用===或==直接比字符串,避免因末尾斜杠或大小写引发误判
禁用动态拼接,改用映射表或ID查表
凡是涉及模板加载、语言包切换、附件预览等场景,避免 include($_GET['tpl']) 这类写法。把用户输入转为不可篡改的标识,再查表还原真实路径。
- 例如:
$map = [
'report' => 'report_v2.php',
'dashboard' => 'dashboard_new.html'
];
$key = $_GET['view'] ?? '';
if (!isset($map[$key])) die('不支持的视图');
include TPL_PATH . $map[$key]; - 优势:完全规避路径构造,连后缀都不用担心被绕过;也便于做权限控制(比如某些模板只对管理员开放)
后缀与协议双重白名单硬校验
即使路径合法,也要防止攻击者上传恶意文件(如 shell.jpg.php)再通过遍历调用执行。所有文件操作前,必须提取扩展名并限制范围,并禁止远程协议。
- 检查扩展名:
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (!in_array($ext, ['pdf', 'jpg', 'png', 'txt', 'csv'], true)) {
die('不支持的文件类型');
} - 禁止远程包含:
确保php.ini中allow_url_fopen = Off且allow_url_include = Off;代码里也别用include('http://...')这类写法
Web服务器层基础防护不可少
应用层加固是核心,但服务器配置是第一道防线。很多漏洞其实根本不用走到PHP逻辑里就被拦下了。
- 关闭目录浏览:Apache 配置中去掉
Indexes,Nginx 设置autoindex off;敏感目录(如config/、runtime/、data/)加deny all - 限制PHP执行权限:在 Nginx/Apache 中,对上传目录禁用
php执行(如location ~ ^/uploads/.*\.php$ { deny all; }) - 生产环境关闭调试:确认
APP_DEBUG = false,防止错误页面泄露物理路径
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











