根治PHP文件包含隐患的关键是切断“动态拼接路径+无校验执行”攻击链:禁用allow_url_include和allow_url_fopen,设置open_basedir限制文件操作范围,强制白名单映射或静态包含,禁止用户输入直接参与include/require调用,并加固上传目录与配置文件权限。

根治PHP文件包含隐患,关键不在堵某一个参数,而在于切断“动态拼接路径+无校验执行”这条攻击链。核心思路是:让include/require无法被用户输入左右,同时让服务器拒绝加载不该加载的内容。
禁用远程包含与危险协议
这是最直接有效的第一道闸门。在php.ini中强制关闭两项:
-
allow_url_include = Off:彻底禁止
include("http://...")或include("php://filter/...")这类远程或伪协议加载 -
allow_url_fopen = Off:连带阻止
file_get_contents()、fopen()等函数读取远程资源,大幅压缩利用面
注意:修改后必须重启Web服务(如Apache或PHP-FPM),否则不生效。
限制文件操作边界(open_basedir)
即使攻击者绕过参数过滤,也得让他“出不了院子”。设置open_basedir可将PHP所有文件操作(包含、读写、包含)限定在指定目录内:
- 推荐值:open_basedir = /var/www/html:/tmp(根据实际Web根目录调整)
- 效果:若攻击者尝试
?page=../../etc/passwd,PHP会直接报错“failed to open stream: Operation not permitted” - 补充:配合
disable_functions禁用chdir等目录切换函数,避免绕过
代码层杜绝动态包含
再强的配置也挡不住硬编码漏洞。所有include/require调用必须满足以下任一条件:
- 文件名完全静态,例如:
include 'header.php'; - 使用白名单映射,例如:
$pages = ['home' => 'home.php', 'about' => 'about.php']; include $pages[$_GET['p']] ?? '404.php'; - 绝对禁止:
include $_GET['file'] . '.php';或require $_POST['module'];
特别提醒:include_once和require_once虽有防重复加载作用,但不解决路径可控问题,该禁还是要禁。
加固敏感目录与文件权限
防止攻击者上传恶意脚本后被包含执行:
- 上传目录(如
/uploads/)在Web服务器中配置为禁止执行PHP:
Nginx示例:location ~* ^/uploads/.*\.php$ { return 403; }
Apache示例:php_flag engine off - 配置文件(如
.env、config.php)设为640权限,属主为root,Web用户仅可读 - Web根目录权限建议
750,非必要不开放写权限
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











