with grant option是高危权限,因为它赋予用户二次分发权限的能力——即使只授予select,也能将自身所有权限转授他人,极易导致权限扩散和管控失效。

为什么WITH GRANT OPTION是个高危权限
它不是“能执行GRANT命令”那么简单,而是让账号获得**二次分发权限的能力**——哪怕只给了SELECT,只要带WITH GRANT OPTION,该用户就能把SELECT甚至其他已有权限转授给任意新账号。一旦这个账号被泄露或误操作,攻击者可快速扩散权限,绕过原有管控边界。
新建账号时默认不带GRANT OPTION
MySQL不会自动赋予WITH GRANT OPTION,必须显式声明。但很多人在写GRANT语句时习惯性加上它,或复制旧脚本未删干净。关键点在于:不写,就没有。
-
GRANT SELECT ON app_db.* TO 'reporter'@'%';✅ 安全,无转授权 -
GRANT SELECT ON app_db.* TO 'reporter'@'%' WITH GRANT OPTION;❌ 默认不该加 - 即使你后续用
REVOKE GRANT OPTION ON app_db.* FROM 'reporter'@'%';回收,也得先确认它真被授过——SHOW GRANTS FOR 'reporter'@'%';里没出现GRANT OPTION才真正安全
检查现有账号是否意外持有GRANT OPTION
别信部署记录或脚本注释,直接查实际生效权限。很多账号是早期调试时临时加的,后来忘了清理。
- 运行
SHOW GRANTS FOR 'user'@'host';,逐行看输出里有没有GRANT OPTION字样 - 特别注意:
USAGE权限本身不含GRANT OPTION,但若该账号曾被GRANT ALL ON *.*过又没彻底REVOKE,可能残留 - 如果发现有,立刻执行
REVOKE GRANT OPTION ON *.* FROM 'user'@'host';(作用域要和原GRANT一致,否则无效)
权限最小化时,连库级GRANT OPTION都该慎用
有人觉得“只给SELECT + WITH GRANT OPTION很安全”,其实不然。只要该账号后续被授予了INSERT或DROP等权限,它就能把那些权限一起转授出去——GRANT OPTION绑定的是**当前拥有的全部权限集合**,不是当初那条GRANT语句里写的那几个。
- 真正需要转授权的场景极少,通常是DBA或专职运维账号
- 如果只是想让开发人员建测试表,授
CREATE, DROP ON test_db.*即可,不必配WITH GRANT OPTION - MySQL 8.0+ 的角色机制更适合权限复用,比靠
GRANT OPTION层层下放更可控
最易被忽略的一点:GRANT OPTION不是开关,是权限附着体——它随你授予的权限范围动态生效,且无法局部禁用。一旦存在,就得全程盯紧那个账号的所有权限变更。











