文件包含漏洞的核心成因是用户可控输入直接参与include/require路径拼接,需同时满足路径可控与内容可控;有效防御须切断输入到路径的映射,采用绝对路径白名单、realpath校验、禁用危险配置及避免动态包含。

文件包含漏洞在PHP代码审计中高频出现,核心成因是把“加载哪个文件”这个本该静态决定的行为,交给了用户可控的输入。只要include、require及其_once变体的参数直接或间接拼接了$_GET、$_POST、$_COOKIE等外部数据,且未做结构化约束,漏洞链就已形成。
漏洞成立的两个硬性条件
缺一不可:
-
路径可控:文件路径由用户输入决定,例如
$page = $_GET['page']; include($page . '.php'); - 内容可控:被包含的文件内容可被攻击者影响或构造,比如上传的图片马、写入的访问日志、生成的Session文件、临时缓存等
常见误判与绕过陷阱
很多团队修复时只做表面过滤,结果很快被绕过:
- 仅过滤
../?攻击者可用....//、URL编码%2e%2e%2f、双写..%2f..%2f绕过 - 加
.php后缀就安全?空字节截断%00(旧环境)、伪协议php://filter完全不依赖后缀 - 用
basename()提取文件名?若先拼接再取名,攻击者可传about.php%00../../etc/passwd,截断后仍生效 - 白名单只校验文件名?没限定绝对路径,攻击者可通过软链接指向任意位置
真正有效的防御方式
不是加一层过滤,而是切断“用户输入 → 文件路径”的映射关系:
-
白名单必须绑定绝对路径:用关联数组明确映射,如
$whitelist = ['home' => '/var/www/html/pages/home.php'],参数仅作键名查表,不参与任何字符串拼接 -
所有白名单路径预校验:对每个值调用
realpath(),确保它落在预期根目录下,同时拒绝符号链接指向外部路径 -
禁用危险配置:在
php.ini中设allow_url_include = Off、open_basedir限制可访问范围、disable_functions = ... , include, require(需配合自动加载机制) -
代码层彻底避免动态包含:模板渲染改用
switch分支或路由分发;配置加载统一走parse_ini_file()并校验格式;公共函数抽成独立类,由自动加载器管理
审计时重点关注的代码模式
看到以下写法,应立即标记高风险:
-
include($_GET['file']);或require($_POST['template'] . '.inc'); - 虽有
file_exists()判断,但判断和包含用的是不同路径逻辑 - 使用
glob()、scandir()枚举文件后让用户选择再包含 - 路径拼接中混用
$_SERVER['DOCUMENT_ROOT']、__DIR__等动态常量
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











