能,但前提是配置正确——open_basedir是内核级路径白名单,需每段路径以/结尾、英文冒号分隔、在php.ini或PHP-FPM中设置并重启生效,否则形同虚设。

能,但前提是配置正确——open_basedir 不是“开就有效”的开关,而是内核级路径白名单,设错等于没设。
为什么能挡文件包含?
PHP 的 include、require、fopen、file_get_contents 等所有文件操作函数,在执行前都会被 open_basedir 拦截检查。只要目标文件的绝对路径不在你设定的允许目录树内,PHP 就直接拒绝并报 Warning,不读取、不解析、不执行。
这意味着:即使攻击者通过 ?file=../../etc/passwd 或 ?page=phar://xxx 构造路径穿越或伪协议,只要目标路径超出了 open_basedir 范围,包含行为就根本不会发生。
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
常见配置错误会让它完全失效
- 路径末尾没加斜杠,比如写成
/var/www/html,攻击者可访问/var/www/html_evil/—— 因为 PHP 把它当“前缀匹配”而非“目录精确限定” - 多个路径用空格或中文冒号分隔,导致只生效第一个路径
- 漏掉必要目录:如 session 存储路径
/var/lib/php/sessions/、临时上传目录/tmp/、框架 vendor 目录等,脚本一运行就报错,反而暴露配置问题 - 在 .htaccess 或 PHP 脚本里用
ini_set()设置 —— open_basedir 是PHP_INI_SYSTEM级指令,运行时设置无效,Apache 下用php_admin_value也仅限 mod_php,PHP-FPM 场景下会被忽略
PHP 8.0.25 下必须这样配才真正起效
- 每段路径以
/结尾:/var/www/html/public/:/var/www/html/:/tmp/:/proc/:/var/lib/php/sessions/ - Linux 下用英文冒号
:分隔,中间无空格、无换行、无中文 - 优先在 php.ini 或 PHP-FPM pool 配置中设置(非 .user.ini),确保全局强制生效
- 改完必须重启 PHP-FPM(不是 reload),否则配置不加载
- 用
ini_get('open_basedir')在脚本里输出验证,结果应为非空字符串且内容与你所设一致
它不能单独解决所有问题
open_basedir 挡不住以下情况:
立即学习“PHP免费学习笔记(深入)”;
- 攻击者已获得 WebShell 并在允许目录内写入恶意脚本(需配合禁用
eval、assert、system等函数) - PHP 配置仍开启
allow_url_include = On,可能绕过本地路径限制(务必设为 Off) - 应用层存在未过滤的动态包含逻辑,如
include($_GET['m'] . '.php')—— 即使在白名单内,也可能包含到恶意构造的文件
所以它应作为纵深防御的一环,和输入过滤、白名单包含、禁用危险函数一起使用。


















