PHP 8.2.35 不修复 open_basedir 绕过漏洞,因其属逻辑限制失效问题,需组合配置路径、禁用危险函数及Web服务器层锁定才有效。

PHP 8.2.35 本身不修复 open_basedir 绕过漏洞——它只是堵住了 CVE-2026-109618/109619 这类运行时 RCE 漏洞,而 open_basedir 绕过属于逻辑限制失效问题,靠升级 PHP 版本无法根治。
为什么 upgrade 到 8.2.35 后 open_basedir 还能被绕过
open_basedir 是 PHP 的路径白名单机制,不是沙箱。它的校验发生在文件 I/O 函数(如 fopen、file_get_contents、include)入口处,但不覆盖所有路径解析场景。只要函数内部没做二次校验,攻击者就能利用协议、迭代器或工作目录切换绕开限制。
-
DirectoryIterator("glob:///*")在 PHP 5.3+ 中完全无视open_basedir,Linux 下可直接列根目录 -
chdir()+ 多次ini_set('open_basedir', '..')可逐步扩大范围,最终设为'/'或空字符串 -
phar://、zip://、data://等流包装器在某些 PHP 版本中绕过路径检查(尤其配合unserialize时) -
include和file_get_contents对协议处理逻辑不同:input://在前者中可执行代码,在后者中仅返回原始内容
真正有效的 open_basedir 防护配置方式
不能只依赖单点配置,必须组合使用且路径定义要精确。重点不是“设了没”,而是“设得对不对”。
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
- 路径末尾加
/:写成/var/www/html/而非/var/www/html,避免/var/www/html_evil被误匹配 - 显式包含必需临时路径:
open_basedir = "/var/www/html/:/tmp/:/var/lib/php/sessions/",漏掉 session 目录会导致登录失败 - 禁用危险协议:在
php.ini中设置disable_functions = "glob,scandir,apache_get_modules"(注意glob是关键) - Web 服务器级兜底:Nginx 中用
fastcgi_param PHP_ADMIN_VALUE "open_basedir=/var/www/html/:/tmp/;",比php.ini更难被ini_set动态覆盖 - 避免使用
ini_set('open_basedir', ...):动态设置可被后续代码覆盖,且无法限制子进程(如exec)
检测当前环境是否已被绕过
别只看 ini_get('open_basedir') 返回值——它可能被重设过,也不代表实际生效。要实测边界行为:
立即学习“PHP免费学习笔记(深入)”;
- 执行
print_r(glob('/etc/*'));,若返回非空数组,说明glob未受控 - 尝试
new DirectoryIterator('glob:///etc/');,成功构造即存在目录遍历风险 - 运行
chdir('/'); ini_set('open_basedir', '/'); echo file_get_contents('/etc/passwd');,若不报错则已绕过 - 检查错误日志里是否有
open_basedir restriction in effect字样——没有不代表安全,只代表没触发校验路径
最易被忽略的是:即使你用了 PHP 8.2.35,只要没关掉 glob、没禁用 DirectoryIterator 对 glob:// 的支持、也没在 Web 服务器层锁定 PHP_ADMIN_VALUE,攻击者仍能用三行代码列完整个服务器的目录结构。


















