PHP 文件访问范围限制:open_basedir 与目录边界
问题:PHP 靠什么限制"可访问的目录范围"? 答案:三层限制,核心是
open_basedir。
三层限制结构
① open_basedir(PHP 配置层 —— 主角)
php.ini / .user.ini / 虚拟主机配置:
open_basedir = /var/www/html:/tmp
- 作用:限制 PHP 所有文件操作能访问的目录范围
- 受影响的函数:
fopen、file_get_contents、include、require、readfile等
- 受影响的函数:
- 超出范围的路径访问 → 直接报错拒绝(即使系统权限允许)
- ⚠️ 它是目录前缀匹配,不是精确限制 → 存在绕过手法(见下)
② 系统文件权限(OS 层)
- PHP 以什么用户运行(
www-data/nobody),能读哪些目录由 Linux 文件权限决定 - 即使没配 open_basedir,www-data 也读不了 root 的文件
③ Web 服务器根目录(服务层)
- Apache/Nginx 的 DocumentRoot 决定 URL 能访问哪些目录
- web 根之外的目录通过 URL 访问不到(但 PHP 在 open_basedir 允许时仍可读)
顺带分清:disable_functions
disable_functions = system,exec,passthru,shell_exec
- 不是限制目录,是禁用危险函数
- 与 open_basedir 常一起考察:
- open_basedir → 管"能碰哪"(文件范围)
- disable_functions → 管"能执行啥"(函数权限)
open_basedir 绕过(CTF/比赛高频考点)
常见思路:
/proc/self/root/<真实路径>等价路径访问- 符号链接(symlink)绕过前缀匹配
- 配合软链接目录跳转
- 通过其他语言/扩展(如 FFI、iconv、glob 等)间接读写
遇到具体题目再针对性分析,先记住"它是前缀匹配,有绕过空间"这个概念。
一句话总结
PHP 限制可访问目录 =
open_basedir(PHP 层)+ 系统文件权限(OS 层)+ DocumentRoot(Web 层),open_basedir是最常考的 PHP 专属限制,绕它是高频题。
相关联想
- 探针/tz.php:信息泄露 → 配合绝对路径利用
- 文件包含 + open_basedir:读 web 根之外文件会被拦
- 写 shell 时目标路径必须落在 open_basedir 允许的目录内