PHP的mkdir()本身不触发符号链接攻击,但可能被用于攻击链;需重点防护路径解析与权限控制阶段:严格校验用户输入路径,用basename()剥离遍历符,realpath()规范化根目录,is_link()检查目标是否为符号链接,限制操作在open_basedir白名单内,并显式设权限0755、统一umask为022。

PHP 的 mkdir() 本身不直接触发符号链接攻击,但它可能成为攻击链的一环——比如攻击者先用恶意 symlink 替换目标路径的父目录或同名占位目录,再诱导 PHP 调用 mkdir() 时误操作真实系统路径。真正需要防护的是「路径解析阶段」和「权限控制阶段」,而非 mkdir 函数本身。
严格校验并规范化用户输入路径
任何由用户可控参数参与构造的 $pathname,都必须经过过滤与归一化处理:
- 用
basename()提取合法文件夹名,彻底剥离路径遍历符(如../、./)和斜杠 - 拼接前使用
realpath($baseDir)获取安全根目录的绝对路径,避免软链或相对路径干扰 - 创建前调用
is_link($targetPath)检查目标是否已存在且为符号链接;若存在且是 link,应拒绝创建或先清理 - 示例:
$safeBase = realpath('/var/www/uploads');<br>$userDir = basename($_POST['dir']);<br>$target = $safeBase . '/' . $userDir;<br>if (is_link($target)) { die('Target is a symlink — blocked'); }
限制 mkdir 操作范围在可信目录内
不能依赖前端传入的路径“看起来安全”,而要强制约束所有创建行为只发生在预设白名单路径下:
- 禁止动态拼接上级路径,如
mkdir('../config')或mkdir($_GET['path']) - 配置
open_basedir(php.ini 中),例如open_basedir = /var/www/uploads:/tmp,让 PHP 进程无法访问指定目录之外的任何路径 - 结合
chroot环境或容器隔离,从系统层切断越权可能性
避免权限失控与 umask 干扰
错误的权限设置会放大符号链接风险(例如赋予写+执行权限给可被链接覆盖的目录):
立即学习“PHP免费学习笔记(深入)”;
- mkdir 权限参数推荐显式传字符串
'0755',避免 PHP 解析歧义导致权限未生效 - 确保 Web 进程运行用户对目标父目录仅有必要权限(如上传目录设为
0755,禁止执行;配置目录设为0644,禁止写入) - 检查服务器
umask值(如002),它会按位屏蔽 mkdir 设置的权限;生产环境建议统一设为022保证一致性
配合其他函数做二次确认
仅靠 mkdir 不足以防御,需组合判断路径真实性:
- 创建后立即用
realpath($target)获取实际指向路径,并比对是否仍在预期根目录内 - 调用
lstat($target)(注意是小写 L 的 lstat)获取链接本身元信息,检查mode & 0120000是否为真(即是否为 symlink) - 若业务允许,可在创建前用
file_exists($target) && !is_dir($target)排除文件/链接冲突



















