PHP文件包含漏洞核心是用户输入直接拼接进include等函数路径;唯一可靠修复是取消拼接、改用白名单映射(如$pages=['home'=>'pages/home.php']),并辅以realpath校验、open_basedir限制及禁用allow_url_include。

PHP文件包含漏洞的核心问题在于:用户输入直接参与了 include、require 等函数的路径拼接。修复不是“加一层过滤”,而是彻底切断用户输入与文件路径的映射关系。
用白名单映射代替动态拼接
这是唯一被实战验证可靠的修复方式。不要对输入做任何“清理”或“替换”,而是把合法选项固化为数组,仅允许匹配已知值:
- 定义明确的页面映射表,例如:
$pages = ['home' => 'pages/home.php', 'about' => 'pages/about.php']; - 接收参数后只做键存在性判断:
if (!isset($pages[$_GET['page']])) { die('Invalid page'); } - 执行包含时,直接使用白名单中预设的完整路径:
include $pages[$_GET['page']]; - 所有页面文件统一放在独立子目录(如
pages/),不混放配置、日志等敏感文件
路径规范化 + 目录锁定校验
若业务逻辑暂无法完全取消动态路径(如多租户模板加载),必须叠加 realpath 校验:
- 先拼接基础路径与用户输入:
$path = __DIR__ . '/templates/' . basename($_GET['tpl']); - 用
realpath($path)获取真实绝对路径 - 严格比对是否仍在预期目录内:
strpos(realpath($path), __DIR__ . '/templates/') === 0 - 不满足则拒绝,不返回错误详情,避免路径泄露
关闭高危配置与限制运行范围
代码层之外,必须同步收紧 PHP 运行环境:
立即学习“PHP免费学习笔记(深入)”;
- 在
php.ini中设置:allow_url_include = Off(禁用远程包含) - 启用
open_basedir,限定脚本只能访问指定目录,例如:open_basedir = /var/www/html/:/tmp/ - 禁用非必要危险函数:
disable_functions = system, exec, shell_exec, passthru, proc_open - 确保 Web 服务器(如 Nginx/Apache)对
.env、config.php等敏感文件有明确的deny all规则
杜绝伪协议和间接污染
攻击者常通过 php://filter、data://、zip:// 等伪协议绕过常规检查:
- 禁止在包含逻辑中接受任意协议前缀,可强制要求路径以字母开头、不含冒号
- 避免使用
basename()单独处理——它对../../etc/passwd无效,需配合realpath()使用 - 审计代码中是否存在间接引入用户输入的情况,比如:
$file = $config['template'][$_GET['type']] . '.php'; include $file;,这类写法同样危险 - 禁用
allow_url_fopen(除非业务强依赖),减少伪协议利用面



















