phpMyAdmin 5.0 的安全加固,关键不在“多装几个防护项”,而在先避开默认配置里那些最容易踩的坑。只要在 5 分钟内把 config.inc.php 和容器启动参数这两处改到位,常见攻击里 90% 的入口基本就能直接封住:禁用 UploadDir/Sa veDir、关闭 AllowNoPassword、在 Nginx 反向袋里层面对 IP 做硬限制、强制设置 32 位 blowfish_secret,同时把文件权限收紧管严。

说到底,phpMyAdmin 5.0 的安全加固,关键从来不只是“用了哪个版本”,而是有没有避开那套默认配置里埋着的坑。5.0 的确已经清掉了一部分老漏洞,比如 CVE-2018-12613,但默认状态下,危险功能依旧开着,权限控制依然偏弱,访问路径也还是明文暴露。真正有效的做法,其实很直接:改好 config.inc.php,再调整容器启动参数,通常 5 分钟左右,就能封住 90% 的常见攻击入口。
禁用 UploadDir/Sa veDir 防止 RCE 和 SSRF
phpMyAdmin 5.0 默认保留 $cfg['UploadDir'] 和 $cfg['Sa veDir'],即使你没挂载目录,攻击者仍可能利用空值触发路径解析异常或配合 LOAD DATA INFILE 实现文件写入。
- 必须显式设为空字符串:
$cfg['UploadDir'] = '';和$cfg['Sa veDir'] = '';—— 不能只注释掉,phpMyAdmin 会 fallback 到默认值 - 如果确需上传 SQL 文件,应单独建一个受限目录(如
/tmp/pma-upload),并确保该路径不在 Web 可访问范围内 - 检查
$cfg['TempDir']是否也指向非 Web 目录;若仍为./tmp,需同步修改并验证 Web 进程无写权限
关闭 AllowNoPassword 并强制密码认证
phpMyAdmin 5.0 仍默认允许 $cfg['Servers'][$i]['AllowNoPassword'] = true;,哪怕你传了环境变量密码,这条也会让空密码登录绕过验证——这是多数“配置了密码却仍能空密码登录”的根本原因。
- 在
config.inc.php中全局搜索并删除或注释所有AllowNoPassword行 - 确认认证方式为
cookie或http,不要用config模式(密码明文写死) - 若使用 Docker,通过
-e PMA_ARBITRARY=1启动时,必须配套禁用AllowNoPassword,否则任意服务器连接页仍可跳过密码
限制 IP 访问必须用 Nginx 反代而非 Apache .htaccess
phpMyAdmin 5.0 最新镜像基于 Apache,但容器内 .htaccess 默认不生效(AllowOverride None),且 块在 --network=host 或自定义网络下常被忽略。硬编码 IP 控制必须前置。
- 起一个
nginx:alpine容器作为反代,只暴露 443 端口 - Nginx 配置中用
allow 203.0.113.0/24;+deny all;,别信geo模块或环境变量注入 - 禁止访问敏感路径:
location ~ ^/(setup|libraries|templates|readme.php|changelog.php) { return 403; } - 别在 phpMyAdmin 容器内改 Apache 配置——改了也大概率不加载,还增加维护负担
blowfish_secret 必须手动生成 32 字符随机串
phpMyAdmin 5.0 的 cookie 加密依赖 $cfg['blowfish_secret'],留空或用默认值会导致加密降级,登录态可被伪造。这不是“建议”,而是 5.0+ 版本的强制要求。
- 用
openssl rand -base64 32生成字符串,粘贴进config.inc.php,覆盖原值 - 该密钥不能出现在任何日志、环境变量或 Git 历史中;若用 Ansible/Terraform 部署,需用 vault 加密存储
- 验证是否生效:登录后查看响应头
Set-Cookie中的phpMyAdmin_*cookie 是否含加密字段,而非明文 session ID
真正容易被忽略的是文件所有权——把 config.inc.php 的 owner 设成 root、group 设成 www-data、权限 640,比单纯调 chmod 更关键;否则 web 进程读取时,攻击者通过任意文件读取漏洞照样能拿到密钥。
