definer权限等于后门,因其使普通用户通过execute权限即可以高权限账户(如root@%)身份执行任意sql操作;修复须检查现有过程的definer和security_type,重建时选用低权限definer或sql security invoker,并彻底回收definer账户的隐式高危权限。

DEFINER权限为什么等于后门
MySQL存储过程默认以DEFINER身份执行,不是调用者。如果创建时写的是DEFINER='root@%',哪怕普通用户只被授予EXECUTE权限,过程里所有SQL都会以root权限运行——包括UPDATE、DROP TABLE甚至SELECT INTO OUTFILE写文件。这不是“功能”,是提权通道。
检查现有存储过程的DEFINER和安全模式
先摸清线上有哪些高危过程:
SELECT ROUTINE_NAME, DEFINER, SECURITY_TYPE FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'your_db';
重点关注:
- DEFINER字段是否含root、%、或高权限账号
- SECURITY_TYPE是否为DEFINER(危险)而非INVOKER(推荐)
- 若过程跨库访问视图或函数,需递归查INFORMATION_SCHEMA.VIEWS和ROUTINES确认底层依赖权限链
重建过程:强制使用低权限DEFINER或SQL SECURITY INVOKER
两种修复路径,选其一即可,但不能共存:
- 显式指定低权限账户:
CREATE DEFINER='readonly_user@localhost' PROCEDURE ...,该用户仅拥有SELECT等必要权限,且不能有GRANT OPTION - 改用调用者权限执行:
CREATE PROCEDURE ... SQL SECURITY INVOKER(MySQL 5.7+ 支持),这样过程内所有操作都受限于调用者的实际权限,最贴近“只读”语义 - 已有过程不能直接
ALTER PROCEDURE ... DEFINER=...,必须DROP后重建;SQL SECURITY可直接ALTER修改
权限回收比代码修复更关键
光改DEFINER不保险。常见疏漏:
-
DEFINER账户本身仍有SUPER权限 → 必须收回:REVOKE SUPER ON *.* FROM 'readonly_user'@'localhost'; - 过程调用的视图/函数自身也是
DEFINER模式 → 需逐个检查并统一降权 - 用户被赋予
db_datawriter类角色(虽然这是SQL Server术语,但在MySQL中类似给ALL PRIVILEGES ON db.*)→ 实际应只授SELECT、EXECUTE,禁用INSERT/UPDATE/DELETE显式授权
真正难控的从来不是语法,而是DEFINER账户在其他数据库、其他过程、甚至系统表上的隐式权限残留——一次SHOW GRANTS FOR 'definer_user'@'%'可能暴露三条你没意识到的GRANT记录。











