不安全,除非显式配置权限隔离;MySQL默认不自动按用户隔离数据,所有操作权限取决于GRANT配置,需按需授权、及时回收,并验证CURRENT_USER()与授权匹配。

不同用户访问同一数据库是否安全?
不安全,除非你已显式配置权限隔离。MySQL 默认不按用户自动隔离数据——SELECT、UPDATE、DELETE 等操作能否执行,完全取决于该用户被授予的 GRANT 权限,而非数据库或表名本身。同一个库下,用户 A 可能对 users 表有读写权,而用户 B 只能查 logs 表,这必须靠人工配,不是 MySQL 自动保障的。
如何用 GRANT 实现最小权限隔离?
核心是「按需授权」:只给每个用户访问其业务必需的库、表、甚至字段的权限。常见错误是直接 GRANT ALL ON mydb.* TO 'user'@'%' ,这等于交出整把钥匙。
- 按表授权:
GRANT SELECT, INSERT ON mydb.orders TO 'app_writer'@'10.0.1.%'; - 按列授权(仅 SELECT):
GRANT SELECT(id, status) ON mydb.orders TO 'report_reader'@'10.0.2.%'; - 禁止跨库访问:不显式
GRANT其他库,用户就无法USE other_db或SELECT FROM other_db.table - 及时回收:
REVOKE DELETE ON mydb.users FROM 'app_writer'@'10.0.1.%';比删用户更稳妥
容易被忽略的权限陷阱
权限生效不是即时的,且某些操作绕过常规限制:
-
SHOW DATABASES权限默认关闭:未授权用户看不到其他库名,但若已知库名仍可USE xxx尝试访问(只要权限允许) - 超级用户(
SUPER、PROCESS、REPLICATION CLIENT)权限会破坏隔离,比如PROCESS可看到所有连接的 SQL,含敏感查询 - 视图和存储过程的执行权限独立于底层表:即使用户没查
users表权限,若被授了视图GRANT SELECT ON mydb.v_user_summary,且视图定义里包含脱敏逻辑,就可能绕过限制——但这也意味着你要审计视图定义本身 - MySQL 8.0+ 的角色(
CREATE ROLE)可简化管理,但角色本身不自动继承;必须GRANT role_name TO user才生效,且SET DEFAULT ROLE才让会话默认启用
验证权限是否真正生效
别只信 SHOW GRANTS FOR 'u'@'h',要实际测行为。登录目标用户后执行:
SELECT USER(), CURRENT_USER(); USE mydb; SELECT COUNT(*) FROM sensitive_table; -- 应报 ERROR 1142 (42000): SELECT command denied SELECT COUNT(*) FROM allowed_table; -- 应返回数字
注意 CURRENT_USER() 返回的是认证用户(即权限匹配来源),USER() 是客户端声明的用户——两者不一致常导致权限误判。如果测试时发现“明明没授权却能查”,先看 CURRENT_USER() 是否匹配你 GRANT 的那个 'user'@'host'。
权限粒度越细,维护成本越高;但生产环境里,漏掉一个 GRANT DELETE 或多开一个 WITH GRANT OPTION,都可能让隔离形同虚设。










