如何设置phpMyAdmin禁止普通用户执行DROP和TRUNCATE高危SQL命令?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1032个文字,预计阅读时间需要5分钟。
相关专题:
phpMyAdmin 里普通用户还能执行 DROP/TRUNCATE?那是权限没关严
默认安装的 phpmyadmin 不会主动禁用高危 sql,它只是个前端界面——真正起作用的是 mysql 的用户权限。只要数据库账号本身有 drop 或 create 权限,点“sql”标签页敲 drop table 就能成功。phpmyadmin 本身不校验语句内容,也不拦截关键词。
所以核心动作不是改 phpMyAdmin 配置,而是收缩数据库账号权限:
- 给普通用户只授
SELECT、INSERT、UPDATE、DELETE(按需),绝对不给DROP、CREATE、ALTER、INDEX - 用
REVOKE DROP ON `db_name`.* FROM 'user'@'%';主动回收已有权限 - 确认权限已生效:登录该账号后执行
SHOW GRANTS;,检查输出里不含DROP
想让 phpMyAdmin 界面直接隐藏“删除表”按钮?靠 $cfg['AllowUserDropDatabase'] 不够
phpMyAdmin 提供了 $cfg['AllowUserDropDatabase'] = false;,但它只控制「数据库」层级的删除(即 DROP DATABASE),对单张表的 DROP TABLE 或 TRUNCATE TABLE 完全无效。
真正影响表级操作可见性的配置是 $cfg['ShowSQLQuery'] 和界面逻辑本身——但 phpMyAdmin 没提供开关来隐藏“SQL”输入框或“Drop table”链接。强行删前端 HTML 或 JS 属于 hack 行为,升级后必丢。
更实际的做法:
立即学习“PHP免费学习笔记(深入)”;
- 把
$cfg['AllowUserDropDatabase'] = false;设为false(虽不防表,但至少防库) - 禁用
$cfg['ShowSQLQuery'] = false;—— 这会让所有 SQL 执行入口消失,包括“SQL”标签页和表结构页的“DROP”链接 - 注意:
$cfg['ShowSQLQuery'] = false同时也会屏蔽SELECT查询,普通用户只能用图形化操作(如浏览、搜索)
误删补救难,所以得在 MySQL 层加硬限制:启用 sql_safe_updates + 只读账号
权限控制失守时,sql_safe_updates 是最后一道缓冲:它要求所有 UPDATE 和 DELETE 必须带 WHERE 条件或主键,虽不拦 DROP,但能防止清空整表的误操作。
对真正只读的账号,建议叠加设置:
- 创建账号时指定
WITH MAX_QUERIES_PER_HOUR 0并设MAX_UPDATES_PER_HOUR 0(MySQL 5.7+ 支持) - 或者直接用
SET SESSION sql_log_bin = 0;+SET SESSION read_only = ON;(需 SUPER 权限,适合临时会话) - MySQL 8.0+ 可建角色(ROLE)统一管理只读权限,再 assign 给用户,比逐个授权更稳
别信 phpMyAdmin 的“禁止执行”提示,它不拦截、不审计、不记录
有人改了 $cfg['AllowNoPassword'] 或加了 $cfg['Servers'][$i]['auth_type'] = 'cookie';,就以为安全了——这些只管登录方式,跟 SQL 执行毫无关系。
phpMyAdmin 默认不记录谁在什么时候执行了什么 SQL(除非你手动开启 $cfg['SaveDir'] 并配好日志路径)。也没有内置机制去扫描 TRUNCATE 关键词并拒绝执行。
真要审计或拦截,必须外挂方案:
- MySQL 自身开启 general_log(性能损耗大,仅调试用)
- 用 MySQL 企业版的 Audit Log 插件,或 Percona Server 的 audit log
- 在代理层(如 ProxySQL、MaxScale)做 SQL 规则过滤,拦截含
DROP/TRUNCATE的语句
最常被忽略的一点:phpMyAdmin 的配置文件 config.inc.php 本身如果权限是 644 且 Web 可读,里面可能泄露数据库账号密码。务必确保它不在 Web 根目录可访问范围内,或用 Web 服务器规则禁止访问。
本文共计1032个文字,预计阅读时间需要5分钟。
相关专题:
phpMyAdmin 里普通用户还能执行 DROP/TRUNCATE?那是权限没关严
默认安装的 phpmyadmin 不会主动禁用高危 sql,它只是个前端界面——真正起作用的是 mysql 的用户权限。只要数据库账号本身有 drop 或 create 权限,点“sql”标签页敲 drop table 就能成功。phpmyadmin 本身不校验语句内容,也不拦截关键词。
所以核心动作不是改 phpMyAdmin 配置,而是收缩数据库账号权限:
- 给普通用户只授
SELECT、INSERT、UPDATE、DELETE(按需),绝对不给DROP、CREATE、ALTER、INDEX - 用
REVOKE DROP ON `db_name`.* FROM 'user'@'%';主动回收已有权限 - 确认权限已生效:登录该账号后执行
SHOW GRANTS;,检查输出里不含DROP
想让 phpMyAdmin 界面直接隐藏“删除表”按钮?靠 $cfg['AllowUserDropDatabase'] 不够
phpMyAdmin 提供了 $cfg['AllowUserDropDatabase'] = false;,但它只控制「数据库」层级的删除(即 DROP DATABASE),对单张表的 DROP TABLE 或 TRUNCATE TABLE 完全无效。
真正影响表级操作可见性的配置是 $cfg['ShowSQLQuery'] 和界面逻辑本身——但 phpMyAdmin 没提供开关来隐藏“SQL”输入框或“Drop table”链接。强行删前端 HTML 或 JS 属于 hack 行为,升级后必丢。
更实际的做法:
立即学习“PHP免费学习笔记(深入)”;
- 把
$cfg['AllowUserDropDatabase'] = false;设为false(虽不防表,但至少防库) - 禁用
$cfg['ShowSQLQuery'] = false;—— 这会让所有 SQL 执行入口消失,包括“SQL”标签页和表结构页的“DROP”链接 - 注意:
$cfg['ShowSQLQuery'] = false同时也会屏蔽SELECT查询,普通用户只能用图形化操作(如浏览、搜索)
误删补救难,所以得在 MySQL 层加硬限制:启用 sql_safe_updates + 只读账号
权限控制失守时,sql_safe_updates 是最后一道缓冲:它要求所有 UPDATE 和 DELETE 必须带 WHERE 条件或主键,虽不拦 DROP,但能防止清空整表的误操作。
对真正只读的账号,建议叠加设置:
- 创建账号时指定
WITH MAX_QUERIES_PER_HOUR 0并设MAX_UPDATES_PER_HOUR 0(MySQL 5.7+ 支持) - 或者直接用
SET SESSION sql_log_bin = 0;+SET SESSION read_only = ON;(需 SUPER 权限,适合临时会话) - MySQL 8.0+ 可建角色(ROLE)统一管理只读权限,再 assign 给用户,比逐个授权更稳
别信 phpMyAdmin 的“禁止执行”提示,它不拦截、不审计、不记录
有人改了 $cfg['AllowNoPassword'] 或加了 $cfg['Servers'][$i]['auth_type'] = 'cookie';,就以为安全了——这些只管登录方式,跟 SQL 执行毫无关系。
phpMyAdmin 默认不记录谁在什么时候执行了什么 SQL(除非你手动开启 $cfg['SaveDir'] 并配好日志路径)。也没有内置机制去扫描 TRUNCATE 关键词并拒绝执行。
真要审计或拦截,必须外挂方案:
- MySQL 自身开启 general_log(性能损耗大,仅调试用)
- 用 MySQL 企业版的 Audit Log 插件,或 Percona Server 的 audit log
- 在代理层(如 ProxySQL、MaxScale)做 SQL 规则过滤,拦截含
DROP/TRUNCATE的语句
最常被忽略的一点:phpMyAdmin 的配置文件 config.inc.php 本身如果权限是 644 且 Web 可读,里面可能泄露数据库账号密码。务必确保它不在 Web 根目录可访问范围内,或用 Web 服务器规则禁止访问。

