本文目录导读:

本地文件包含(LFI)是一种常见的Web安全漏洞,攻击者通过操纵文件路径参数,使服务器加载并执行非预期的本地文件(如配置文件、日志文件等),进而可能导致信息泄露、代码执行甚至服务器沦陷,防御LFI需要从输入验证、服务器配置、代码逻辑三个层面综合施策。
以下是具体的防御措施:
严格验证用户输入(最核心)
- 白名单机制:不要直接使用用户输入作为文件路径,最佳实践是维护一个允许访问的文件白名单(如
page=home,page=about),然后在后端通过映射(switch-case 或 map)来加载对应的真实文件路径。- 错误做法:
include($_GET['page'] . '.php'); - 正确做法:
if ($_GET['page'] == 'home') { include('pages/home.php'); }
- 错误做法:
- 过滤特殊字符:如果必须使用动态路径,请严格过滤危险字符。
- 禁止 (路径遍历)。
- 禁止绝对路径: 如
/etc/passwd、C:\boot.ini。 - 禁止空字节
%00(用于截断早期PHP版本的文件名)。 - 禁止协议关键字: 如
php://、file://、data://、phar://(用于PHP伪协议利用)。
- 限制文件后缀:如果应用要求加载
.php文件,强制只允许include具有该后缀的文件,并禁止通过%00或 截断实现绕过。
合理配置服务器与应用
- 禁用危险PHP配置(php.ini):
allow_url_fopen = Off: 禁止远程文件包含(RFI)。allow_url_include = Off: 禁止远程文件包含。disable_functions: 可考虑禁用exec、system、popen等危险执行函数,防止攻击者利用包含进的文件执行命令。
- 文件上传安全:防止用户上传恶意脚本(如 Webshell)到服务器上,然后通过LFI包含它。
- 将用户上传的文件存放在 Web根目录之外(
/var/www/uploads/放在/var/www/html/之外)。 - 重命名文件: 上传后强制修改文件名(例如使用
uniqid()+ 随机串 + 无意义的扩展名如.tmp),使攻击者无法预测路径。 - 不允许执行: 在存放上传文件的目录中,配置
.htaccess或 Nginx 规则禁止执行PHP(RemoveHandler .php或location ~ \.php$ { deny all; })。
- 将用户上传的文件存放在 Web根目录之外(
- 最小化文件权限:Web服务器(如 www-data)对系统敏感文件(如
/etc/passwd、日志目录)应具有最低权限,最好为只读或不可读。
代码层面的防御技巧
- 使用
basename()和realpath(): 如果必须处理路径,可以使用realpath()解析出文件的真实绝对路径,然后检查该路径是否以允许的基路径开头。$baseDir = '/var/www/html/pages/'; $userInput = $_GET['file']; // 获取用户输入对应的绝对路径 $realPath = realpath($baseDir . $userInput); // 检查:路径必须存在,且以允许的基目录开头 if ($realPath !== false && strpos($realPath, $realBaseDir) === 0) { include($realPath); } else { // 拒绝访问 } - 关闭错误显示:在生产环境中关闭
display_errors,防止攻击者通过错误信息推断文件路径或系统结构。 - 设置 Open_basedir:在 PHP 配置中设置
open_basedir指令,限制PHP只能访问指定目录内的文件,超出范围的文件(如/etc/passwd)访问会被拒绝。
其他关键措施
- 日志文件包含的防护:攻击者常通过修改
User-Agent写入恶意代码到日志文件,然后包含日志,除了上述措施外,建议:- 日志文件不要放在Web可访问目录下。
- 在包含前对日志内容进行编码或过滤。
- 会话文件包含的防护:如果session文件路径可预测且内容可控(如用户头像URL存入session),同样需要严格验证session数据。
- 监控与WAF:部署Web应用防火墙(WAF),配置规则拦截常见的 、、
php://input、data://等攻击模式。
防御优先级
- 首选:永远不要直接使用用户输入决定文件路径。 使用白名单最安全。
- 次选:如果要使用用户输入,必须对真实路径进行验证 (结合
realpath检查前缀)。 - 底线:服务器配置 (禁用危险函数、限制目录范围、文件权限最小化)。
通过组合以上措施,可以显著降低本地文件包含漏洞被成功利用的风险。