权限未正确校验

【 TiDB 版本】
v5.4.1 , v6.1.0等
【遇到的问题】
同样的两个用户名,不用的 host 范围,不同的权限,登录时可正常校验正确 host,但权限校验时使用了 另一个 host 的权限。
【复现路径】

  1. 创建两个相同的用户名,不同的host,不同的密码
    create user dba_test@’%’ identified by ‘123456’;
    GRANT SELECT,INSERT,UPDATE,DELETE ON test.* TO ‘dba_test’@’%’;

create user dba_test@‘192.168.%’ identified by ‘654321’;
GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER ON test.* TO ‘dba_test’@‘192.168.%’;

  1. 在 192.168.X 服务器上登录并进行删除操作
    mysql -udba_test -p654321 -h192.168.13.15 -P4000
    MySQL [(none)]> use test;
    Database changed
    MySQL [test]> DROP TABLE IF EXISTS a;
    ERROR 1142 (42000): DROP command denied to user ‘dba_test’@‘192.168.%’ for table ‘a’

  2. 删除 dba_test@’%’ 用户后再重新执行删除语句,则可以进行删除操作

你这问题是mysql也有

你要区分权限得用172.0.0.%这样去另外创建用户 root@%默认是匹配所有

mysql 我验证过了,是正常的,而且权限本身也应该校验最小粒度才对

没什么毛病,本身就是最小权限

正常情况下,生产环境不用@’%’ ,显然TiDB这里匹配了“@’%’ ”的权限而未匹配“@‘192.168.%’ ”,不过需要验证下是按允许主机访问范围匹配还是按数据库本身的权限匹配

是的,生产环境是不用 @’%’,测试环境偶然发现有这个问题存在,结果显然和权限分配不符

我测试了下,mysql5.7跟8.0表现跟tidb确实不一样,直接第二个用户登录时可以删除,但是按测试结果,mysql好像不是以最小权限来实现的;

先做访问控制,以 user,host 的优先级做匹配度,匹配到之后才会去校验对应的权限是否存在,mysql 官方给出具体的 IP 和主机名的选择度最优先的,要高于 ‘%’

tidb 这里访问控制匹配到的是正确的 user 和 host,但是在权限校验的时候用了 ‘%’ 这个 host,这里明显不对

tidb对不对,我目前还没找到资料,但是mysql权限验证的时候,如果user表没有全局权限,会去db表验证,db也时排序的,按照host,db,user来排序(在服务器使用的排序规则中,先排序主机名字段值(越精确的值越靠前,字符串主机名和IP地址是最具体的。),然后使用匹配的第一个项;

看mysql官网,这个最小权限说应该是登录时的用户范围,如%的范围比较大,写了具体host的比较小那么会使用具体host的去验证,然后表的操作权限也按这个逻辑去验证,那么结果就回是登录的用户匹配对应的权限,不会使用别的用户权限

我理解的是 dba_test@’%’ 匹配任何地址,那么也包括 ‘dba_test’@‘192.168.%’

在user 表中, username 只有 db_test , 后面的IP 是host字段值,只是用来限制登陆的客户端,并不是用户操作权限, 所以我觉得 在数据库当中 会把这个用户视为同一用户

但是grant 的时候是需要指定root@'XX.XX.X.X’这样的用户才行,校验就应该也是按这个来

但是已经存在了一个 root@%了,
有一个root@% 的用户,那其他root@x.x.x.x 其实意义不大

你可以分别创建 root@%和 root@x.x.x.x 用户,赋予不同权限, 然后从 x.x.x.x 主机上登陆,测试root 的权限是什么

按照mysql的检验规则应该是越精确的越优先, 看有没有user()和current_user() 函数, 看看登陆的用户

提了issue,官方在新版本中已解决此问题
https://github.com/pingcap/tidb/issues/37488

恭喜发现bug,:+1:

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。