MySQL权限控制的设计缺陷?

这个问题是从被问到information_schema.user_privilegeIS_GRANTABLE字段问题开始查起的,就先从user_privilege表的显示规则说起。

 

1、              IS_GRANTABLE字段

root账号执行如下语句(本文中grant后都接flush privileges, 不赘述)

a) grant all privileges on *.* to `myuser`@localhost with grant option;

 

b) select user,select_priv from mysql.user where user='myuser';

+------------------------------+----------------------------+

| user               | select_priv        |

+------------------------------+----------------------------+

| myuser            | Y                      |

+------------------------------+----------------------------+

 

c) select PRIVILEGE_TYPE, IS_GRANTABLE from information_schema.user_privileges where grantee like '\'myuser\'@\'localhost\'' and PRIVILEGE_TYPE = ‘SELECT’;

+------------------------------+----------------------------+

| PRIVILEGE_TYPE     | IS_GRANTABLE     |

+------------------------------+----------------------------+

| SELECT                    | NO                         |

+------------------------------+----------------------------+

   

 

说明: b)myuser已经有了select_priv。而c) IS_GRANTABLENO,这不是显示错误。 实际上,IS_GRANTABLE并非表示用户是否“拥有此权限”,而是表示用户是否拥有“将此权限赋予其他用户”的权限。它对应的是mysql.user表中的grant_priv字段,此时为NO

  

2user_privileges的显示规则

       当我们创建一个新用户create user myuser2;  时,在mysql.user中看到这个用户的所有权限都为NO,此时user_privileges增加一行

+---------------------+-----------------------+--------------------------+---------------------+

| GRANTEE     | TABLE_CATALOG | PRIVILEGE_TYPE  | IS_GRANTABLE  |

| 'myuser2'@'%' | NULL          | USAGE          | NO           |.

+---------------------+-----------------------+--------------------------+---------------------+

 

什么时候显示USAGE 这篇文章中我们知道对应的显示控制代吗在sql/sql_show.cc 对应的函数为fill_schema_schema_privileges

简单分析源码得到规则如下:

 

    PRIVILEGE_TYPE规则:

       a) 当该用户没有权限,或只有grant_priv的时候,PRIVILEGE_TYPE显示为USAGE

       b) 否则按顺序显示被赋予的权限,每行一个,这些权限包括

UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL |  LOCK_TABLES_ACL | EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | ALTER_PROC_ACL | EVENT_ACL | TRIGGER_ACL), GRANT权限不显示。

 

   IS_GRANTABLE规则:若该用户有grant_priv权限,则在列出的所有行的IS_GRANTABLE都显示YES,否则显示NO

 

================================标题党的分割线================================

 

3、权限控制问题

       从上面的分析中我们知道,用户是否拥有给其他用户赋权的权限,取决于这个用户本身是否拥有grant_priv权限。用一个字段控制一批权限,这样就联想到可能有一个“权限混乱“的现象。

       首先,授权必然是要有范围限制的。用户A赋权给用户B,这些赋予的权限不能超过A的权限范围。

       看以下的操作序列。使用root账户登录。

mysql> grant select,insert,delete,update on *.* to `grant_u2`@localhost  ;     

Query OK, 0 rows affected (0.00 sec)

 

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

 

mysql> select * from information_schema.user_privileges where grantee like '%gran_u%';

Empty set (0.01 sec)

 

mysql> select GRANTEE, PRIVILEGE_TYPE, IS_GRANTABLE from information_schema.user_privileges where grantee like '%grant_u%';

+--------------------------------+----------------------------+--------------------+

| GRANTEE            | PRIVILEGE_TYPE   | IS_GRANTABLE |

+--------------------------------+----------------------------+--------------------+

| 'grant_u1'@'localhost' | SELECT            | YES         |

| 'grant_u2'@'localhost' | SELECT            | NO         |

| 'grant_u2'@'localhost' | INSERT            | NO         |

| 'grant_u2'@'localhost' | UPDATE           | NO         |

| 'grant_u2'@'localhost' | DELETE            | NO         |

+-------------------------------+-------------------------------+-------------------+

 

    说明:上面的操作中,我们给grant_u1赋了查询权限且with grant option. grant_u2赋了增删改查权限,但没有grant权限。

information_schema.user_privileges看出目前权限状态正常。

 

    之后用grant_u1登录, select的“赋权”权限赋给grant_u2.

mysql> grant select on *.* to `grant_u2`@localhost with grant option  ;                    

Query OK, 0 rows affected (0.00 sec)

mysql> select GRANTEE, PRIVILEGE_TYPE, IS_GRANTABLE from information_schema.user_privileges where grantee like '%grant_u%';

+--------------------------------+----------------------------+--------------------+

| GRANTEE            | PRIVILEGE_TYPE   | IS_GRANTABLE |

+--------------------------------+----------------------------+--------------------+

| 'grant_u1'@'localhost' | SELECT            | YES         |

| 'grant_u2'@'localhost' | SELECT            | YES         |

| 'grant_u2'@'localhost' | INSERT            | YES         |

| 'grant_u2'@'localhost' | UPDATE           | YES         |

| 'grant_u2'@'localhost' | DELETE            | YES         |

+-------------------------------+-------------------------------+-------------------+

5 rows in set (0.00 sec)

 

    从结果看出,grant_u2用户拥有了对增删改查的赋权权限。这个已经超出了grant_u1的权限范围。

 

进一步的,再用grant_u2登录,执行grant select,insert,delete,update on *.* to `grant_u1`@localhost with grant option ; grant_u1用户也拥有了增删改查的赋权权限。

实际上,root账号设置的权限中,grant_u1grant_u2都没有对增删改的赋权权限,但经过上述操作后,这两个用户的权限都扩大了,且超过了原有权限的并集。

 

4、分析

实际上这个问题的根源,就在于MySQL在设计上用一个grant_priv来控制是否有赋权权限,而每个概念上将每个权限分开。导致在grant_u1将“查询赋权”权限赋给grant_u2的时候,附带的将其他权限也带进去了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值