普通用户能看见别人连接是因为MySQL默认隐式授予USAGE权限且PROCESS权限未被显式回收;必须用REVOKE PROCESS ON .并FLUSH PRIVILEGES,同时禁用performance_schema和sys表访问以防间接泄露。

为什么普通用户能看见别人在连什么
MySQL 默认给新用户隐式授予 USAGE 权限,但只要没显式 REVOKE,某些全局权限(如 PROCESS)就可能残留。而 PROCESS 权限一开,用户执行 SHOW PROCESSLIST 或查 information_schema.PROCESSLIST 就能看到所有连接,包括其他用户的 IP、SQL、运行时长——这属于典型的权限泄露。
直接回收 PROCESS 权限的正确写法
不能只靠建用户时不给,因为权限是叠加的;必须显式撤销:
REVOKE PROCESS ON *.* FROM 'appuser'@'192.168.1.%';-
FLUSH PRIVILEGES;—— 这步不可省,否则缓存仍生效 - 验证是否生效:
SELECT CURRENT_USER();切换到该用户后执行SHOW PROCESSLIST;,应只返回自己的连接(或报错ERROR 1227 (42501): Access denied)
注意 MySQL 8.0+ 的权限继承陷阱
在 MySQL 8.0+ 中,CREATE USER 不再自动赋予任何权限,但如果你用老脚本先 GRANT ALL ON *.* 再慢慢收权,REVOKE PROCESS ON *.* 必须和当初 GRANT 的范围完全一致,否则无效。常见错误包括:
- 当初
GRANT ... ON *.*,却只REVOKE PROCESS ON mydb.*→ 不生效 - 用户有多个 host 条目(如
'appuser'@'%'和'appuser'@'192.168.1.%'),只 revoke 其中一个 → 另一个仍可查 - 没检查
mysql.user表里Process_priv字段是否真为N:执行SELECT User, Host, Process_priv FROM mysql.user WHERE User = 'appuser';
替代方案:用视图 + 权限隔离代替硬回收
如果业务确实需要“有限查看连接”,又不想彻底禁用,可以创建受限视图:
CREATE VIEW safe_processlist AS SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE FROM information_schema.PROCESSLIST WHERE USER = SUBSTRING_INDEX(CURRENT_USER(), '@', 1); GRANT SELECT ON yourdb.safe_processlist TO 'appuser'@'%';
这样用户只能看到自己用户名发起的连接,且无法绕过——前提是已 REVOKE SELECT ON information_schema.*,否则视图本身无意义。
真正容易被忽略的是:即使 PROCESS 被收回,用户仍可能通过 performance_schema.threads 或 sys.session 等间接路径窥探,所以必须同步 REVOKE SELECT ON performance_schema.* 和 REVOKE SELECT ON sys.*(MySQL 8.0+)。这些表默认对所有认证用户可读,不是“系统表限制”的自然结果,得手动关。


















