关键在于切断“用户可控输入→协议解析→危险操作”链,需关闭allow_url_fopen和allow_url_include、设置open_basedir限制路径、采用白名单映射文件、严格过滤输入参数并防范日志/上传文件被包含。

堵住伪协议导致的文件包含漏洞,关键不是禁掉所有协议,而是切断“用户可控输入 → 协议解析 → 危险操作”这条链。核心思路是:限制协议能力、约束文件路径、关闭高危配置。
关掉两个危险开关
PHP.ini 中有两个配置项直接决定伪协议能否被用于攻击:
- allow_url_fopen = Off:禁止通过协议(如 http://、php://、data://)打开远程或特殊流资源。多数场景下可安全关闭,不影响常规文件读写
- allow_url_include = Off(必须关):这是最危险的一项。只要它为 On,攻击者就能用 php://input、data:// 等协议把任意内容当 PHP 代码执行。生产环境应始终为 Off
限制文件包含的路径范围
即使协议可用,也要让 include/require 只能访问白名单内的目录:
本套教程,以一个真实的学校教学管理系统为案例,手把手教会您如何在一张白纸上,从零开始,一步一步的用ThinkPHP5框架快速开发出一个商业项目,让您快速入门TP5项目开发。
- 设置 open_basedir,例如:
open_basedir = /var/www/html:/tmp。超出该范围的 file://、php://filter/resource=… 都会失败 - 避免使用用户输入拼接路径,改用数组映射或 ID 查表方式加载固定文件,例如:
$files = ['home' => 'home.php', 'about' => 'about.php']; include $files[$_GET['page']] ?? 'home.php';
过滤和校验输入参数
对传入文件名的参数做严格处理:
- 去掉点号(.)、斜杠(/、\)、冒号(:)等路径控制字符,或直接用 basename() 提取文件名部分
- 检查扩展名是否在允许列表中(如 .php、.inc),但注意不能只靠后缀过滤——php://filter 不受扩展名限制
- 对路径遍历符号(
../、..\)做多次替换或正则清除,防止绕过
日志与临时文件场景要额外防
攻击者常利用访问日志、错误日志、临时上传文件等作为包含目标:
- 确保 Web 服务器日志路径不在 Web 可访问目录下(如不要放在 /var/www/html/logs/)
- 禁用 PHP 解析日志文件所在目录的 .php 扩展(如 Apache 中用
RemoveHandler .php) - 上传文件后重命名,不保留原始文件名,且不存放在可被 include 直接引用的路径

















