TDSQL案例:账户加固会影响到视图无法访问?
背景
用户反馈实例视图无法访问,与用户沟通后,了解到近期安全变更将部分用户绑定的ip从%变为客户端ip地址,发生故障后,用户紧急进行了回滚,视图访问恢复正常,业务恢复。
分析
首先mysql族的关系数据库,账户组成由user@ip共同决定,对其中任意结构的变更都将破坏原来账户的定义。 针对于用户的描述,包括关键行为:1、删除账户(变更相当于删除之前的账户);2、视图无法使用;3、修复账户后又恢复。我们估计是视图的definer被删除导致,查看用户故障视图,果然发现其定义者就是被删除的用户。换一种说话,由于视图definer(由user@ip组成)在mysql.user表中被移除,导致该视图无法正常提供访问。
### https://mariadb.com/kb/en/create-view/
If you specify the DEFINER clause, these rules determine the legal DEFINER user values:
If you do not have the SUPER privilege, the only legal user value is your own account, either specified literally or by using CURRENT_USER. You cannot set the definer to some other account.
If you have the SUPER privilege, you can specify any syntactically legal account name. If the account does not actually exist, a warning is generated.
If the SQL SECURITY value is DEFINER but the definer account does not exist when the view is referenced, an error occurs.
其流程图可以展示为:
扩展
我们以一个测试的mariadb视图创建语句来做分析
MariaDB [alan]> show create view aaaG
*************************** 1. row ***************************
View: aaa
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`vky`@`%` SQL SECURITY DEFINER VIEW `aaa` AS select `alan`.`ha`.`id` AS `id`,`alan`.`ha`.`name` AS `name` from `ha`
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set, 1 warning (0.00 sec)
其中view列的意义是视图的名称,character_set_client列和collation_connection列为视图使用到的字符集和排序规则; create view当中包含了视图的主体结构,分类列举: 1、ALGORITHM=UNDEFINED ALGORITHM表示实例对视图的处理算法,这个参数有三个值,包括MERGE、TEMPTABLE以及缺省值UNDEFINED,其中merge可以简单的理解为将外部的sql语句和视图定义的语句合并起来,到原表进行查询;TEMPTABLE与merge相对应,他将视图中的结果先储存到临时表,外部sql直接调用临时表中的结果;至于UNDEFINED,可以理解为实例按照场景自己决定使用哪一个处理算法。 2、DEFINER=`vky`@`%` DEFINER表示视图的定义者(包括用户名以及绑定的ip),通常可以显式的指定,缺省值为当前用户,也就是select current_user();返回的用户。 3、SQL SECURITY DEFINER SQL SECURITY约束视图的安全性策略,他的值有DEFINER和INVOKER。其中DEFINER的策略为如果引用者存有引用该视图的权限(该视图的select权限),通常可以成功返回结果;如果为INVOKER,他需要引用视图的账户也需要同时对视图中的原表具有select的权限,否则也会返回报错。
回到我们故障场景,用户修改了视图定义者的host之后,导致视图无法访问,这里我们前面也进行了充分的解释,更进一步,既然不能破坏user@host这个结构,那我们破坏掉这个用户的权限从而来实现软删除的目的可以不呢?我们对SQL SECURITY 解释中,默认definer策略下,当前账户只需要有试图的select权限即可以正常的引用,其中对原表数据访问实际上使用到了定义者的权限,如果我们对定义者的权限进行完全破坏,实际上也是会失去对视图的使用。以下截屏是我们测试的结果:
MariaDB [alan]> show grants for vky@'%';
+--------------------------------------------------------------------------------------------------------+
| Grants for vky@% |
+--------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'vky'@'%' IDENTIFIED BY PASSWORD '*96A12F0614169E80CC46E92BDE3DBF0FD4751D7C' |
+--------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
MariaDB [alan]> select * from aaa;
ERROR 1356 (HY000): View 'alan.aaa' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
MariaDB [alan]> show grants for vky@'%'G
*************************** 1. row ***************************
Grants for vky@%: GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON *.* TO 'vky'@'%' IDENTIFIED BY PASSWORD '*96A12F0614169E80CC46E92BDE3DBF0FD4751D7C'
1 row in set (0.00 sec)
MariaDB [alan]> select * from aaa;
+----+------+
| id | name |
+----+------+
| 1 | alan |
| 2 | joke |
| 3 | tom |
+----+------+
3 rows in set (0.00 sec)
同样的逻辑,在invoker策略下,虽然删除定义者不会影响其它拥有权限的用户引用视图,但是这里也跑偏了创建视图的初衷。
那要如何完成变更definer操作呢?
由于云上实例通常不存在super权限,所以无法直接使用super账户直接将视图从a归属到b名下,但是却可以使用b账户登录实例,对视图进行definer的变更操作。如截屏:
MariaDB [alan]> show create table aaaG
*************************** 1. row ***************************
View: aaa
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`vky`@`%` SQL SECURITY DEFINER VIEW `aaa` AS select `ha`.`id` AS `id`,`ha`.`name` AS `name` from `ha`
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)
MariaDB [alan]> alter ALGORITHM=UNDEFINED DEFINER=`vky`@`10.%` SQL SECURITY DEFINER VIEW `aaa` AS select `ha`.`id` AS `id`,`ha`.`name` AS `name` from `ha`;
Query OK, 0 rows affected (0.00 sec)
MariaDB [alan]> show create table aaaG
*************************** 1. row ***************************
View: aaa
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`vky`@`10.%` SQL SECURITY DEFINER VIEW `aaa` AS select `ha`.`id` AS `id`,`ha`.`name` AS `name` from `ha`
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)
MariaDB [alan]> select current_user();
+----------------+
| current_user() |
+----------------+
| vky@10.% |
+----------------+
1 row in set (0.00 sec)
MariaDB [alan]>
该操作完成之后,,用户方可进行对高风险用户(绑定%的用户)进行回收操作。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 网罗收集10046的各种Case,方便trace信息的收集 | Oracle官方博客转载
- 目标检测算法YOLO-V3结构详解
- 使用OPCache提升PHP的性能
- 克隆图
- LeetCode 03无重复字符的最长子串(滑动窗口)
- elasticSearch学习(五)
- MySQL进阶:索引与优化
- CentOS7搭建Zabbix4.2系统
- vue项目更换favicon.ico
- 一种O(n)的排序——计数排序引发的围观风波
- LeetCode 04寻找两个正序数组的中位数(困难)二分法
- Java程序员面试必备:Volatile全方位解析
- HTTP协议基础及发展历史
- Vi 和 Vim 的使用
- k8s删除Terminating状态的命名空间