加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

MySQL存储流程的权限问题小结

发布时间:2022-03-13 16:05:02 所属栏目:MySql教程 来源:互联网
导读:MySQL的存储过程,没错,看起来好生僻的使用场景。问题源于一个开发同学提交了权限申请的工单,需要开通一些权限。 本来是一个很正常的操作,但在我来看是比较着急且紧迫的,说来惭愧,忙着方向规划和开发的事情,这个基础的操作功能竟然给忽略了,所以看
  MySQL的存储过程,没错,看起来好生僻的使用场景。问题源于一个开发同学提交了权限申请的工单,需要开通一些权限。
 
  本来是一个很正常的操作,但在我来看是比较着急且紧迫的,说来惭愧,忙着方向规划和开发的事情,这个基础的操作功能竟然给忽略了,所以看到目前的一些实现方式,还是希望能够做一些细小的事情把这些重复性的工作给解放了。
 
  当然我决定把一些基础性的工作接过来,一方面是给同事减压,另一方面是在做一个完整的体验,因为很多需求和痛点通过实践是能够很容易捕捉到重点的,如果我觉得不合理,那么这个过程中势必会有一些改进的地方。比如部署安装,比如权限开通。数据库的权限开通就是一个相对典型的案例,而存储过程的权限开通甚至都有点让人怀疑人生了。
 
  简单声明了下立场,开发同学的想法是能够方便管理,于是乎我就直接招过去了,简单沟通下,其实发现他们的需求场景还是很常规的,他们需要动态创建一些日表,那么需要create权限在评估之后是可以给与的,而对于一般的用户而言,create的权限是不建议开放的,主要的出发点就是能够对SQL进行一些基本的审核,哪怕是人工审核还是平台审核都是一个需要的过程。所以沟通了一圈发现,开通的权限就可以迅速裁剪,对他们而言,修改存储过程的逻辑也是需要的,因为在一些特定的场景下,他们对逻辑的控制希望能够更加灵活。
 
  好了,基础的背景介绍完了。赋予基本的表的权限,赋予存储过程的权限,存储过程的这个地方需要注意一个重要的点是SQL SECURITY,默认创建是definer,如果需要开放给其他的用户调用,则建议是设置为invoker.
 
  所以很简单的一句:
 
  grant execute,alter procedure on xxx.xxx to xxx@'xxxx';
  但是很不幸的,开发同学反馈,他们通过SQLyog或者是Navicator打开的时候,竟然看不到存储过程的内容。
 
  因为我们没有select procedure或者view procedure的权限,所以我们几乎再无从干预了。
 
  使用命令行的方式能够复现出这个问题:
 
  MySQL存储过程的权限问题小结
 
  没有存储过程的实质性内容。在那儿折腾了好一会,发现是个老问题了,10多年前的老问题了。
 
  https://bugs.mysql.com/bug.php?id=20235
 
  问题的解决其实很简单,就是需要这样一句:
 
  grant select on mysql.proc to xxxx@'xxxx'即可
  所以细粒度的权限控制就是这么纠结,但是确实有效。
 
  比如我们举一反三一下,我们知道MySQL里的all privileges算是一个很大的权限,但是里面包含多少种权限,可能我们没有清晰的概念。
 
  我们就完全可以通过细粒度的权限控制来反推。
 
  比如创建一个用户,赋予all privileges的权限。
 
  2 rows in set (0.00 sec)
  我们做一下收缩。
 
  mysql> revoke insert on test.* from jeanron@'%';
  Query OK, 0 rows affected (0.00 sec)
  喏,all privileges的权限就现出原形了。
  mysql> show grants for jeanron;
  | Grants for jeanron@%
  +------------------------------------------------------------------------------------------------------
  | GRANT USAGE ON *.* TO 'jeanron'@'%'
  | GRANT SELECT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `test`.* TO 'jeanron'@'%' |
  所以在上面的问题中,其实如果select on *.*其实已经包含了我们需要的细粒度权限mysql.proc,如果要抽丝剥茧,基本就是这样的套路。

  在使用GRANT创建用户的时候分配这三种权限。 存储过程在运行的时候默认是使用建立者的权限运行的。
 
  需要注意的是在一个用户拥有建立存储过程的权限时,如果其没有对于select、update或delete等权限的话,虽然操作数据的存储过程可以建立,但调用存储过程的话仍是无法成功的,会返回权限错误,就算拥有运行存储过程的权限也一样。所以,如果有人给你建立了一个没有select、update、delete权限只有CREATE ROUTINE权限的用户,骂他吧,他是故意的。
 
  当然这样的用户建立的存储过程倒并不是完全不能使用,创建存储过程中有一个特征子句可以让存储过程使用运行者的权限,在建立存储过程后只要加上SQL SECURITY INVOKER特征子句就可以了。
 
  如下。
 
   CREATE PROCEDURE p() SQL SECURITY INVOKER 这样的话就可以分配两批人,一批给与创建存储过程的权限,作为开发者,一批给与运行存储过程和select、update、delete权限,作为测试者。(脑筋秀逗了) 有了这种权限分配,mysql的安全性完全不需要在功能层去保护了,我通过root用户建立的存储过程,但是在功能层用一个只拥有运行存储过程权限的用户来调用。那么,你就算从功能层上得到数据库的用户名和密码,并且模拟了ip,也不能得到你想要的任何东西。 有了权限,我们可以放心大胆的使用存储过程,不用担心安全问题了。

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读