PHP怎么保护文件夹不被删除_PHP防止文件夹误删【技巧】

2次阅读

锁定父目录写权限是最直接有效的防删方式,因删除文件夹需父目录有写权限;chmod 755 或 750 父目录、路径白名单校验、chattr +a/+i 内核级防护及 –dry-run 机制共同构成多层防护。

PHP怎么保护文件夹不被删除_PHP防止文件夹误删【技巧】

chmod 锁定父目录权限是最直接有效的方式

文件夹本身删不掉,本质是因为操作系统需要对它的**父目录**有写权限——只要父目录不可写,哪怕文件夹是 777,你也删不掉它。
常见误操作是只改文件夹权限,结果没用;真正起作用的是上一级目录的 w 位。

实操建议:

立即学习PHP免费学习笔记(深入)”;

  • 确认目标文件夹路径,比如 /var/www/uploads,那关键就是 /var/www 这个父目录
  • 执行 chmod 755 /var/www(去掉组和其他人的写权限),或更保守地用 chmod 750 /var/www(仅所有者可写)
  • 避免用 chmod -R 直接套用到整个树,否则可能误锁子目录里本该可写的临时文件位置
  • 如果用 www-data 运行 php,确保该用户仍是父目录的所有者,否则会连创建文件都失败

PHP 代码里调用 unlink()rmdir() 前必须校验路径白名单

靠系统权限只能防手动误删,防不住代码逻辑出错或被注入后主动删目录。很多 CMS 插件、上传模块、缓存清理脚本一不留神就递归删了 ../ 上去。

实操建议:

立即学习PHP免费学习笔记(深入)”;

  • 所有涉及 rmdir()unlink()exec("rm -rf") 的地方,先做路径规范化和白名单比对
  • realpath($path) 获取绝对路径,再判断是否以允许的根目录开头,例如:if (strpos(realpath($path), '/var/www/public') !== 0) { die("非法路径"); }
  • 禁用 allow_url_fopenallow_url_include,防止通过 URL 参数注入任意路径
  • 不要依赖 $_GET['dir']$_POST['path'] 直接拼进文件操作函数,哪怕加了 basename() 也不够——它不防 ../

linux 下用 chattr +a+i 是终极保险,但慎用

chattr 是内核级防护,比 chmod 更硬。但 PHP 进程通常没权限执行它,且一旦设错容易把自己也锁死。

实操建议:

立即学习PHP免费学习笔记(深入)”;

  • chattr +a 允许追加但禁止删除/重命名,适合日志目录,不影响 PHP 写入
  • chattr +i 真·不可删不可改,连 root 都要先 chattr -i 才能动——除非你真准备永久冻结这个目录,否则别轻易上
  • PHP 无法直接调用 chattr,必须由运维在部署时用 shell 设置,且需确认文件系统支持(ext4/xfs 可,某些容器环境或 NFS 可能不认)
  • 设置后用 lsattr /path 检查,别设完就忘——下次更新配置想删旧目录时会卡住

误删后恢复难,所以重点得放在“删之前拦住”

Linux 删除是直接 unlink,没回收站。extundeletephotorec 成功率低、耗时长、还可能覆盖原数据。与其事后抢救,不如让删除动作本身变困难。

实操建议:

立即学习PHP免费学习笔记(深入)”;

  • 把敏感目录移到非 Web 根目录下,比如 /srv/app-data,和代码分离,降低被猜中路径的概率
  • 开发环境默认启用 disable_functions = rmdir,unlink,exec,passthru,上线前按需放开,但保留对关键目录的限制
  • 写个轻量钩子脚本监控 /var/log/auth.logauditd 日志,发现异常批量删除行为立刻告警
  • 最实在的一条:所有自动化清理任务,强制加 --dry-run 开关,默认只打印要删什么,人工确认后再跑真实版

权限、路径校验、内核属性这三层不是叠加越多越安全,而是得看谁在操作、在哪操作、删的代价有多大。一个被 PHP 脚本反复读写的上传目录,设 +i 就等于自废武功;而一个只存配置模板的 /etc/myapp/templateschattr +i 几乎零成本。

text=ZqhQzanResources