PHP 7.3无内置漏洞扫描功能,需借助静态分析工具(如PHPStan、PHP_CodeSniffer、RIPS)或人工审计识别动态文件包含漏洞,重点检查用户输入是否未经校验直接用于include/require类函数。

PHP 7.3 本身不提供内置的漏洞扫描功能,发现文件包含漏洞(如 include()、require()、include_once()、require_once() 的动态路径未校验)需借助静态分析工具或人工代码审计。重点在于识别用户可控输入(如 $_GET、$_POST、$_REQUEST)被直接拼接到包含函数中。
识别高危代码模式
文件包含漏洞常见于以下写法:
-
include($_GET['page'] . '.php');—— 未过滤、未白名单、未限制路径 -
require($config_dir . $_POST['lang'] . '/strings.php');—— 变量拼接且输入未归一化 -
include_once('templates/' . $_COOKIE['theme'] . '/layout.php');—— 来源不可信,无扩展名/路径限制
关键判断点:是否对输入做了 白名单校验、路径规范化(如 realpath + strpos 检查是否在允许目录内)、禁止点号和斜杠(防止目录遍历)、强制固定后缀(如 .inc.php)。
使用 PHPStan 或 PHP_CodeSniffer 配合自定义规则
PHPStan(v1.0+ 支持 PHP 7.3)可配合自定义扩展检测危险函数调用;PHP_CodeSniffer 更适合编写 sniff 规则。例如,在 squizlabs/php_codesniffer 中新增一个 sniff,匹配:
- 函数名为
include、include_once、require、require_once - 参数为变量或表达式(非字符串字面量)
- 该变量来源于
$_GET、$_POST、$_REQUEST、$_COOKIE、$_SERVER等超全局数组
配置示例(ruleset.xml)可启用 SlevomatCodingStandard.Security.DisallowDynamicFunctionCall 类似逻辑,并扩展其检查范围至包含函数。
用 RIPS 或 PhpScan 进行轻量级自动化扫描
RIPS(开源版支持 PHP 7.3)能解析 PHP 语法树,标记潜在的动态包含点。部署方式简单:
- 下载 RIPS 0.55(最后兼容 PHP 7.3 的稳定版)
- 将项目代码放入
rips/scan/目录,通过 Web 访问/rips/启动扫描 - 关注报告中 “File Inclusion” 分类下的 “Dynamic include()”、“Untrusted input in require” 等条目
注意:RIPS 不执行代码,仅做静态分析,结果需人工复核——例如确认变量是否在包含前被赋值、是否经过 basename() 或白名单 in_array() 校验。
手动验证与加固建议
发现疑似点后,不要只看代码表面,要模拟请求验证是否真可利用:
- 尝试传参
?page=../../etc/passwd%00(PHP 7.3 默认关闭magic_quotes_gpc,但需确认是否开启NULL字节截断) - 测试
?page=data://text/plain,<?php phpinfo(); ?>(检查是否允许伪协议) - 检查
allow_url_include=Off是否生效(PHP 7.3 默认为 Off,但需确认 php.ini 配置)
修复原则:不用用户输入拼路径;必须用时,限定目录范围 + 白名单 + 去除特殊字符 + 强制后缀。例如:
$allowed = ['home', 'about', 'contact'];
$page = $_GET['page'] ?? 'home';
$page = basename($page); // 去掉路径
if (!in_array($page, $allowed)) {
die('Invalid page');
}
include("pages/{$page}.php");php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











