用浏览器打开 /wp-config.php.bak,页面直接吐出 DB_PASSWORD 那一行,状态码 200。换成 /.env 一样能下,里面还带着 Redis 密码和几个 AUTH_KEY。乍看像缓存或者权限的锅,追下去往往不是。

location ~* /\.(?!well-known/) { deny all; }
location ~* \.(bak|old|sql|env|swp)$ { deny all; }

追下去是这么回事:nginx 只把 .php 交给 PHP 处理,.bak 和 .env 都当静态文件原样返回。编辑器保存生成的备份、部署脚本留下的环境文件,路径只要猜得到就能读。

碰到「配置文件可下载」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。

能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。报错里带路径的,先去看那个路径在不在、权限对不对。

具体做法是,在 server 块里加正则 location,把点开头的隐藏文件和 .bak/.old/.sql/.env 一起拒掉;这条规则要放在 PHP 的 location 之前,正则 location 的匹配顺序才够;顺手扫一遍 web 根目录,把编辑器备份和临时文件清干净。

验收就看一点,再访问 /wp-config.php.bak 和 /.env 都返回 403,根目录里也搜不到 .bak 文件。

作者 9823189