定义
- 因为相同代码重复出现在不同文件中会 产生代码冗余
- 所以出现了文件包含函数,让代码更为高效
- 需要用到这部分代码就会去调用,且被包含的文件会被当做PHP代码执行
- 而且忽略后缀本身
注意:文件包含并不是漏洞,但是被包含的文件能够被攻击者控制就是漏洞
分类
文件包含分为
- 本地包含(LFI)
- 远程包含(RFI) 【远程包含默认不开启 allow_url_include = Off】
注意:他们可以转换,本地文件包含并不代表无法包含远程文件(SMB服务)
函数解析
include()
- 引用外部文件
- 只有代码执行到include代码段时,调用的外部文件才会被引用并读取
- 当引用的文件发生错误时,系统只会给出警告错误,而整个php文件会继续执行
include_once()
include()函数的区别是:
- 会在导入文件前先检测文件是否在该页面的其他部分被引用过,如果有,程序只能引用一次
- 如果导入的文件中存在自定义函数,那么在同一程序中重复导入该文件,在第二次导入时会发生错误
- 因为PHP不允许相同名称的函数重复声明
require()
- 引用外部文件
- 在PHP文件被执行之前,会先去把被包含文件的内容提取出来然后整合成新的php一起执行
- 当引用文件发生错误时,系统会报错,并停止执行下面代码
require_once()
与require()函数唯一区别是
- 会在导入文件前先检测文件是否在该页面的其他部分被引用过,如果有,程序只能引用一次
防范措施
- 无需情况下设置allow_url_include和allow_url_fopen为关闭
- 对可以包含的文件进行限制,可以使用白名单的方式,或者设置可以包含的目录,如open_basedir
- 建议 假定所有输入都是可疑的,尝试对所有输入提交可能包含的文件地址,包括服务器本地文件及远程文件,进行严格的检查,参数中不允许出现…/之类的目录跳转符
- 严格检查include类的文件包含函数中的参数是否外界可控
举个栗子
# 1.txt
<?php echo "efg";?>
include()
引用外部文件
# 1.php
<?php
echo "abc <br />";
include("1.txt");
echo "<br /> abc <br />";
include("1.txt");
echo "<br /> abc <br />";
?>
执行结果:
引用不存在的[错误的]外部文件
# 1.php
<?php
echo "abc <br />";
include("1.jpg"); //引用不存在的1.jpg
echo "<br /> abc <br />";
include("1.txt");
echo "<br /> abc <br />";
?>
运行结果
include_once()
引用外部文件
# 1.php
<?php
echo "abc <br />";
include_once("1.txt");
echo "<br /> abc <br />";
include_once("1.txt");
echo "<br /> abc <br />";
?>
运行结果
引用不存在的[错误的]外部文件
# 1.php
<?php
echo "abc <br />";
include_once("1.jpg"); //不存在的1.jpg
echo "<br /> abc <br />";
include_once("1.txt");
echo "<br /> abc <br />";
?>
运行结果
require()
引用存在的外部文件
#1.php
<?php
echo "abc <br />";
require("1.txt");
echo "<br /> abc <br />";
require("1.txt");
echo "<br /> abc <br />";
?>
运行结果
引用不存在的[错误的]外部文件
# 1.php
<?php
echo "abc <br />";
require("1.jpg"); //不存在的1.jpg
echo "<br /> abc <br />";
require("1.txt");
echo "<br /> abc <br />";
?>
运行结果
require_once()
引用存在的外部文件
#1.php
<?php
echo "abc <br />";
require_once("1.txt");
echo "<br /> abc <br />";
require_once("1.txt");
echo "<br /> abc <br />";
?>
运行结果
引用不存在的[错误的]外部文件
# 1.php
<?php
echo "abc <br />";
require_once("1.jpg");//不存在的1.jpg
echo "<br /> abc <br />";
require_once("1.txt");
echo "<br /> abc <br />";
?>
运行结果