在 MySQL 的授权操作中,通配符 "_" 和 "%" 用于匹配单个或多个字符的数据库对象名。然而,许多 DBA 在进行授权时可能忽视了这些通配符的特殊作用,导致数据库权限错配。这篇文章将讨论通配符误用所带来的潜在风险,并提供避免此类问题的解决方案。
作者:芬达, 【芬达的数据库学习笔记】公众号作者,开源爱好者,擅长 MySQL、ansible。
爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文约 3300 字,预计阅读需要 12 分钟。
在 MySQL 的授权操作中,通配符 "_" 和 "%" 用于匹配单个或多个字符的数据库对象名。然而,许多 DBA 在进行授权时可能忽视了这些通配符的特殊作用,导致数据库权限错配。这篇文章将讨论通配符误用所带来的潜在风险,并提供避免此类问题的解决方案。
误用通配符导致权限授予错误
在授权数据库权限时,如果数据库名中含有下划线 _,可能会引发意想不到的结果。我们来看一个常见的授权语句:
GRANT ALL ON `db_1`.* test_user;
表面上看,这个语句似乎是授予用户 test_user 对数据库 db_1 的全部权限。然而,通配符 _ 在 MySQL 中具有特殊含义,它用于匹配任意单个字符。因此,这条授权语句实际上可能会匹配多个数据库,而不仅仅是 db_1。例如,以下数据库名都可能被匹配:
- 数据库名匹配数字:
db01,db11,db21,…,db91 - 数据库名匹配英文字符:
dba1,dbb1 - 数据库名匹配特殊字符:
db-1,db+1,db?1,等等
这种误操作可能导致某些用户意外获得了不该有的权限,从而带来严重的安全隐患。实际上,按照常见的数据库命名规范,数据库名中的字符通常是 26 个英文小写字母或 10 个数字,也包括 2 种特殊字符(中划线或下划线)。因此,这个授权错误可能将权限的应用范围扩大到 38 倍之多。这是基于对命名模式的分析得出的估算,具体情况可能因实际使用的命名规则而有所不同。
授权带来的隐患
当库名中有多个 "_" 时,情况更为复杂。假设数据库名称是 db_1_1,那么授权就不仅是扩大到 38 倍,而是 38 * 38 = 1444 倍,权限扩大的规模超出想象。如果这些库中有不应该公开的敏感数据,安全性风险将非常严重。
如何避免这个问题?
正确的做法:转义通配符
为了避免这种授权滥用的风险,我们应该将通配符作为普通字符来处理。MySQL 支持使用反斜杠(\)对通配符进行转义,例如:
GRANT ALL ON `db\_1`.* TO 'test_user';
通过这种方式,_ 将被解释为字面量,而不是通配符,从而确保授权的仅是特定的 db_1 数据库。
接下来,文章会多次提到“通配符(_)”和“转义通配符(\_)”这两个术语,理解它们的区别有助于避免常见授权错误。
阿里云 DMS 等连接工具的优势
值得注意的是,在使用阿里云 DMS 授权时,系统底层会自动将通配符进行转义,这也就是为什么很多 DBA 并没有意识到自己授权时遇到的潜在风险。阿里云的这种机制为用户省去了手动转义的烦恼,保证了授权的准确性。
然而,阿里云允许你绕过 DMS,底层手动授权,所以本篇文章内容依然适用于使用阿里云的 DBA。
整改过程中的风险
在你意识到这个问题后,可能会急于对现有授权进行整改,但需要注意两种场景:
- 遗漏整改: 部分库可能没有彻底整改,仍然使用了通配符授权
- 保留通配符功能: 有些场景下,你希望保留部分通配符授权
在这两种场景下,会碰到我这篇文章要讲的正餐 —— 含有下划线的数据库名在特殊情况下会有权限丢失的坑。

最低0.47元/天 解锁文章
1137

被折叠的 条评论
为什么被折叠?



