PHP 安全科普 · 防御向
PHP 文件包含(LFI/RFI):是什么,怎么修
include 和 require 会执行传给它们的任何文件。如果路径的一部分来自请求,那就是访客在决定运行什么。
最近更新
这是什么
本地文件包含(LFI)让请求把 include 或 require 指向服务器上已有的文件,比如配置文件或日志;配合上传或日志写入,可能变成代码执行。远程文件包含(RFI)会从别的服务器加载代码,只有在开启 allow_url_include 时才有效,php.net 文档说明它默认关闭。MITRE 把它归为 CWE-98。
怎么发现
- 搜索参数里含变量的
include、require、include_once、require_once,并把变量追溯到请求数据。 - 运行
php -i,确认allow_url_include为 Off,以及是否设置了open_basedir。 - 检查 Web 服务器日志里参数含
../、php://、data:的请求;这说明有人在探测,但不能证明已被入侵。
怎么修
- 不要用输入拼接包含路径,而是把允许的键映射到固定文件名,见下方示例。
- 保持
allow_url_include = Off;如果应用不需要远程读取,可考虑allow_url_fopen = Off。 - 把
open_basedir设为站点目录,PHP 就打不开其他位置的文件。 - 上传文件存放在网站根目录之外,绝不 include 它们。
只读检查与安全写法
# Find include/require with a variable path (read-only)
grep -rnE "(include|require)(_once)?\s*\(?\s*\$" --include=*.php . | grep -v /vendor/
php -i | grep -E "allow_url_include|allow_url_fopen|open_basedir"
; php.ini hardening
allow_url_include = Off
open_basedir = /var/www/example:/tmp
// Map user choices to fixed files instead of building paths
$pages = ['home' => 'home.php', 'about' => 'about.php'];
require __DIR__ . '/pages/' . ($pages[$_GET['p'] ?? 'home'] ?? 'home.php');用 basename() 处理后 include 就安全了吗?
它去掉了目录部分,但访客仍能选择该目录里的任意文件。明确的白名单更安全。
现代 PHP 里 RFI 还有风险吗?
只有在开启 allow_url_include 时才有。LFI 不需要特殊设置,所以仍然常见。
其他常见 PHP 漏洞类型
- PHP 对象注入:是什么,怎么修当用户可控的输入进入 unserialize() 时就会发生 PHP 对象注入,它可以实例化对象,并通过魔术方法执行攻击者选定的逻辑。
- PHP 中的 SSRF:是什么,怎么修当 PHP 应用请求一个由用户控制的 URL 时就会发生服务端请求伪造(SSRF),攻击者可以借你的服务器访问内网服务或云元数据接口。
- PHP 中的 XSS:是什么,怎么防当 PHP 页面把用户可控的数据不经转义输出到 HTML 时就会发生跨站脚本(XSS),攻击者的脚本会在其他访客的浏览器里运行。
- phpinfo() 暴露:为什么重要,怎么修公开的 phpinfo() 页面会泄露精确的 PHP 版本、已加载模块、文件路径,常常还有环境变量或密钥,帮攻击者瞄准 PHP2Shell 这类漏洞。
来源
出站链接将离开本站。本站不托管利用代码。
- CWE-98: PHP Remote File Inclusion — MITRE CWE
- Testing for Local File Inclusion — OWASP Web Security Testing Guide
- Filesystem runtime configuration (allow_url_fopen, allow_url_include) — PHP Manual
- Core php.ini directives (open_basedir, expose_php) — PHP Manual