MySQL数据库账号权限最小化,业务账号禁止super权限
MySQL 业务账号如果带着 SUPER 权限运行,相当于把数据库管理员的钥匙交给了应用程序。
一旦业务侧被注入或密码泄露,攻击者可以直接执行 SET GLOBAL、修改复制配置、授权其他账号等危险操作。
真正的权限最小化,是让业务账号只拥有读写业务数据的最低权限,同时明确禁用 SUPER。
本文从查看、撤销到验证,给你一套可直接执行的操作流程。
先查清业务账号当前的权限
在调整之前,先要确认账号到底被授予了哪些权限。
使用管理员账号(如 root)登录 MySQL,执行:
SHOW GRANTS FOR 'app_user'@'%';
把 app_user 和 % 替换成实际的业务账号和主机范围。
输出中如果出现 SUPER 或 ALL PRIVILEGES,就说明该账号权限明显过大,需要收紧。
例如:
GRANT ALL PRIVILEGES ON *.* TO 'app_user'@'%'
这种授权方式不仅包含 SUPER,还能对新创建的库表自动获得权限,必须优先处理。
按最小权限原则重新授权
先确定业务真实需要的权限。
绝大多数 Web 应用只需要对某个具体业务库执行增删改查,典型授权如下:
GRANT SELECT, INSERT, UPDATE, DELETE ON bizdb.* TO 'app_user'@'%';
如果应用需要执行存储过程、函数,或使用 LOCK TABLES、REFERENCES,可以按需追加:
GRANT EXECUTE, LOCK TABLES, REFERENCES ON bizdb.* TO 'app_user'@'%';
不建议直接给予 ALL PRIVILEGES ON bizdb.*,
因为 ALTER、CREATE、DROP 这类 DDL 权限会让业务账号具备改表结构能力,
一般应交给专业的发布账号。
执行完授权后,下一步是把多余的 SUPER 权限收回来。
撤销业务账号的 SUPER 权限
SUPER 权限属于全局权限,撤销时必须指定到 *.*,不能只针对某个库。
正确命令:
REVOKE SUPER ON *.* FROM 'app_user'@'%';
如果之前误用了 ALL PRIVILEGES,可以这样撤销全部全局权限,再重新按库授权:
REVOKE ALL PRIVILEGES ON *.* FROM 'app_user'@'%';
FLUSH PRIVILEGES;
注意,REVOKE ALL 不会删除账号,只清掉权限,之后需要重新执行第 2 步里的最小授权语句。
完成后同样执行 FLUSH PRIVILEGES 让权限立即生效,避免新连接读到旧数据。
验证权限是否真的收紧
修改后重新查询授权信息,确认不再出现 SUPER:
SHOW GRANTS FOR 'app_user'@'%';
再用业务账号重新登录,尝试执行需要 SUPER 权限的管理命令。
例如:
SET GLOBAL max_connections = 500;
如果收到 ERROR 1227 (42000): Access denied,说明 SUPER 已被正确禁用。
日常只执行业务读写操作不受影响。
还可以用 SELECT CURRENT_USER(), @@hostname; 确认登录身份不是管理员。
避坑与常见问题
- 不要用 SUPER 代替专用权限:业务需要查看进程列表时,应单独授予
PROCESS;需要查看主从状态时,授予REPLICATION CLIENT;需要配置只读时使用READ_ONLY,而不是给 SUPER。 - 注意账号的 Host 范围:
REVOKE和GRANT中的 Host 必须与账号创建时的 Host 完全匹配,否则会提示账号不存在。建议先用SELECT user, host FROM mysql.user;确认。 - 撤销后应用暂时报错:如果应用代码里执行了
SET GLOBAL或GRANT等管理语句,收权后会失败。此时应修改应用逻辑,把这类操作迁移到专门的管理任务中,而不是恢复 SUPER。 - 为什么业务账号不能有 SUPER:SUPER 可以绕过资源限制、终止任意连接、改变全局变量。对业务账号来说,这些能力既用不到,又是极大风险。如果确实需要临时执行管理操作,应使用独立的管理员账号,并走审批流程。
完成以上操作后,你的 MySQL 业务账号就只保留下沉业务必需的权限,SUPER 权限也被明确排除。
建议把权限清单记录到变更文档中,方便后续安全审计和账号梳理。
如果你正准备做账号权限最小化,可以直接参照本文步骤逐台执行,遇到报错时优先检查主机匹配和授权语句顺序。