PHP 文件访问范围限制:open_basedir 与目录边界

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 允许的目录内