PHP动态包含用户输入存在任意文件读取和RCE风险,必须禁用allow_url_include、使用白名单映射、路径规范化校验,并优先采用PSR-4自动加载或模板引擎替代。

PHP中动态包含用户输入是高危操作,直接导致任意文件读取或远程代码执行。核心原则只有一条:绝不把未经强约束的用户数据拼进 include、require 及其变体函数中。
强制使用白名单映射
不依赖用户传来的文件名做路径拼接,而是预先定义合法选项与对应路径的映射关系:
- 声明一个关联数组,键为安全标识(如
'dashboard'、'profile'),值为绝对路径(如__DIR__ . '/pages/dashboard.php') - 接收用户参数后,仅将其作为数组键查找,不存在则中止
- 查到后直接
include $whitelist[$key];,不经过任何字符串拼接
禁用远程及危险协议包含
防止攻击者利用 php://filter、data:// 或远程 URL 执行恶意逻辑:
- 在
php.ini中设allow_url_include = Off(必须关闭) - 同时设
allow_url_fopen = Off,避免被间接利用 - 检查是否启用
expect扩展,如有且非必需,应在disable_functions中禁用
路径规范化与范围校验
若业务确需有限度地接受文件名,必须做三层防护:
- 用
basename($_GET['page'])剥离路径符号(../、/etc/passwd等无效) - 正则限制仅允许字母、数字、下划线和
.php后缀,例如:preg_match('/^[a-zA-Z0-9_]+\.php$/', $file) - 拼接基础目录后调用
realpath(),再判断是否仍位于该目录内(如strpos(realpath($full), $base_dir) === 0)
替代方案优先于动态包含
多数场景其实不需要运行时决定包含哪个文件:
- 将页面逻辑封装为类或函数,在入口统一
require_once所有依赖 - 使用 PSR-4 自动加载机制管理类文件,完全规避手动包含
- 模板渲染交给 Twig 或 Blade 等成熟引擎,它们内置路径沙箱,不暴露原始文件系统
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











