排查伪静态引发的文件包含漏洞,核心是确认重写规则是否将未经校验的用户输入传给include/require函数;需重点审计PATH_INFO等变量的路径拼接逻辑,验证URL编码与多点绕过是否可控,并在PHP 8.1环境下检查cgi.fix_pathinfo、open_basedir等配置对路径归一化的影响。

排查伪静态引发的文件包含漏洞,核心不是看“URL是否好看”,而是确认重写规则是否把用户输入未经校验地传给了 include 或 require 类函数。PHP 8.1 对路径解析更严格,但伪静态恰恰容易掩盖参数污染路径的真实流向,导致漏洞藏得更深、更难识别。
一、先定位伪静态是否真在“传参”
很多开发者以为用了 nginx try_files 或 Apache RewriteRule 就安全了,其实不然。关键要看重写后的 PHP 脚本如何解析原始 URL 中的路径段。
- 检查入口脚本(如
index.php)是否用$_SERVER['PATH_INFO']、$_SERVER['REQUEST_URI']或自定义路由解析逻辑提取路径参数 - 重点盯住类似
$page = trim($_SERVER['PATH_INFO'], '/');→include 'pages/' . $page . '.php';这类写法 - PHP 8.1 默认启用
cgi.fix_pathinfo=1(尤其在 CGI/FPM 模式下),它会主动拆解/index.php/../../../etc/passwd并把后半段塞进PATH_INFO——这就是伪静态下路径穿越的温床
二、验证路径是否可控且未过滤
不要只测 ?page=,要主动构造带斜杠的路径型参数试探真实行为:
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
- 访问
/article/test→ 观察是否触发include('pages/test.php') - 尝试
/article/..%2f..%2f..%2fetc%2fpasswd(URL 编码绕过)或/article/....//....//....//etc/passwd(多点绕过) - 若返回
Warning: include(pages/...)类错误,说明路径被拼接且未拦截;若直接 404 或 500,可能有白名单或正则过滤,需进一步 fuzz
三、检查 PHP 8.1 特有解析行为是否放大风险
PHP 8.1 加强了对空字节、编码歧义和协议头的处理,但某些旧式伪静态逻辑反而因此失效或产生意外结果:
立即学习“PHP免费学习笔记(深入)”;
-
open_basedir在伪静态路径中可能被绕过:若配置为/var/www/html,但include拼出的是/var/www/html/../etc/passwd,PHP 8.1 默认会先归一化路径再校验——需确认是否启用了realpath_cache_size=0等干扰项 - 若使用
mbstring.http_input或default_charset非 UTF-8(如 GBK),仍可能触发双写绕过,尤其在 Windows + IIS 环境下 - PHP 8.1 不再隐式忽略末尾
%00,但若代码里手动做了urldecode()再拼接,就又回到危险区
四、快速验证与加固建议
不依赖工具扫描,用最小动作确认风险是否存在:
- 临时在入口脚本顶部加:
error_log('PATH_INFO: ' . $_SERVER['PATH_INFO'], 4);,访问几个伪静态路径,看日志是否输出攻击载荷 - 把疑似拼接路径的变量用
basename($page)或白名单数组校验:in_array($page, ['home', 'about', 'contact']) - 禁用高危配置:
php.ini中设cgi.fix_pathinfo=0(Nginx 推荐)、allow_url_include=Off、open_basedir=/var/www/html - 改用绝对路径加载:
include __DIR__ . '/pages/' . $safe_page . '.php';,避免相对路径解析歧义


















