MYSQL儲存過程許可權問題分析(Security_type詳解)
最近遇到一些諮詢儲存過程訪問許可權拒絕的問題,有可能是應用賬戶沒有被賦予儲存過程執行許可權,也有可能是沒有訪問儲存過程物件的許可權,甚至有可能是儲存過程定義安全型別預設的情況下建立儲存過程的使用者被刪除等等都有可能導致儲存過程無法被指定使用者訪問,這裡做下大概的分析和驗證,僅供遇到同樣問題的人參考。
MYSQL資料庫許可權彙總:
SELECT ,INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE
與儲存過程本身有關的許可權有三類,分別是CREATE ROUTINE, ALTER ROUTINE, EXECUTE。一般來說如果使用者需要有建立、刪除儲存過程許可權,需要賦予CREATE ROUTINE即可;如果有修改儲存過程許可權,需要賦予ALTER ROUTINE即可;如果需要有呼叫儲存過程許可權,需要賦予EXECUTE許可權即可。
但MYSQL本身對儲存過程定義的語法結構有些限制,也會對使用者呼叫許可權做嚴格的篩選,主要與儲存過程定義引數:Definer 和 Security_type有關,前者是建立儲存過程的使用者,一般是表現形式為root@localhost等;而Security_type主要分為DEFINER | INVOKER,主要用以稽核呼叫儲存過程的安全稽核,如果設定為DEFINER,則建立儲存過程的使用者需要存在、並且有呼叫儲存過程許可權、有訪問儲存過程裡面物件的許可權,每次呼叫都會對definer=root@localhost稽核,看其是否存在並由相應的許可權,如果設定為INVOKER,則每次呼叫不會去稽核definer對應的賬戶是否存在,只需要呼叫儲存過程的使用者有執行儲存過程許可權,訪問儲存過程裡面包含物件的許可權即可。
測試用例驗證如下:
本示例採用dbtest資料庫,以及其下面的表t1,分別利用root,dbuser01,dbuser02三個使用者
1.建立測試賬戶dbuser01
建立賬戶dbuser01,僅賦予usage,create routine許可權
[root@node1 ~]# mysql
(root:localhost:Wed Dec 14 14:19:05 2016)[(none)]>grant USAGE on *.* to dbuser01@'10.127.%' identified by 'dbuser01';
Query OK, 0 rows affected (0.00 sec)
(root:localhost:Wed Dec 14 14:19:25 2016)[(none)]>grant create routine on dbtest.* to dbuser01@'10.127.%';
Query OK, 0 rows affected (0.00 sec)
(root:localhost:Wed Dec 14 14:19:52 2016)[(none)]>flush privileges;
Query OK, 0 rows affected (0.01 sec)
(root:localhost:Wed Dec 14 14:20:33 2016)[(none)]>show grants for dbuser01@'10.127.%';
+----------------------------------------------------------------------------------------------------------------+
| Grants for dbuser01@10.127.% |
+----------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'dbuser01'@'10.127.%' IDENTIFIED BY PASSWORD '*0B9488E6078162E584CCE461DE11578474EBBC84' |
| GRANT CREATE ROUTINE ON `dbtest`.* TO 'dbuser01'@'10.127.%' |
+----------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
2.建立儲存過程pro_test
利用dbuser01登陸dbtest資料庫,並建立儲存過程pro_test
[root@node4 ~]# mysql -udbuser01 -pdbuser01 -h10.127.32.121 -D dbtest
mysql> delimiter //
mysql> create procedure pro_test() begin select * from t1; end;//
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> delimiter ;
儲存過程pro_test呼叫場景一
場景1:建立儲存過程者:dbuser01
dbuser01許可權:usage on *.*,create routine ON `dbtest`.*
Definer: dbuser01@10.127.%
Security_type: DEFINER
dbuser01呼叫儲存過程pro_test:
mysql> call pro_test;
ERROR 1370 (42000): execute command denied to user 'dbuser01'@'10.127.%' for routine 'dbtest.pro_test'
dbuser01呼叫儲存過程pro_test:
(root:localhost:Wed Dec 14 14:34:28 2016)[dbtest]>call pro_test();
ERROR 1370 (42000): execute command denied to user 'dbuser01'@'10.127.%' for routine 'dbtest.pro_test'
root呼叫儲存過程:
(root:localhost:Wed Dec 14 14:34:28 2016)[dbtest]>call pro_test();
ERROR 1370 (42000): execute command denied to user 'dbuser01'@'10.127.%' for routine 'dbtest.pro_test'
場景01結論:dbuser01使用者存在,且Security_type: DEFINER,dbuser01建立儲存過程後,需要賦予賬戶execute 儲存過程pro_test的許可權,否則會報無許可權執行。即呼叫儲存過程的時候會檢查
Definer: ##看此使用者是否有執行儲存過程許可權
Security_type: DEFINER
儲存過程pro_test呼叫場景二
場景02:建立儲存過程者:dbuser01
dbuser01許可權:usage on *.*,create routine ON `dbtest`.*, execute on procedure dbtest.pro_test
Definer: dbuser01@10.127.%
Security_type: DEFINER
(root:localhost:Wed Dec 14 14:34:32 2016)[dbtest]>grant execute on procedure dbtest.pro_test to 'dbuser01'@'10.127.%' ;
Query OK, 0 rows affected (0.00 sec)
dbuser01呼叫儲存過程pro_test:
mysql> call pro_test();
ERROR 1142 (42000): SELECT command denied to user 'dbuser01'@'10.127.32.122' for table 't1'
root呼叫儲存過程:
(root:localhost:Wed Dec 14 14:47:03 2016)[dbtest]>call pro_test();
ERROR 1142 (42000): SELECT command denied to user 'dbuser01'@'10.127.%' for table 't1'
場景02結論:dbuser01使用者存在,且Security_type: DEFINER ,dbuser01建立儲存過程後,需要賦予賬戶execute 儲存過程pro_test的許可權,還要被賦予儲存過程裡相應物件的訪問許可權,比如select on dbtest.t1許可權,否則會報無許可權執行。即呼叫儲存過程的時候會檢查Definer: ##看此使用者是否有執行儲存過程許可權、訪問物件許可權
Security_type: DEFINER
儲存過程pro_test呼叫場景三
場景03:建立儲存過程者:dbuser01
dbuser01許可權:usage on *.*,create routine ON `dbtest`.*, execute on procedure dbtest.pro_test,select on dbtest.t1
Definer: dbuser01@10.127.%
Security_type: DEFINER
(root:localhost:Wed Dec 14 15:43:32 2016)[dbtest]>grant select on dbtest.t1 to 'dbuser01'@'10.127.%' ;
Query OK, 0 rows affected (0.01 sec)
dbuser01呼叫儲存過程pro_test:
mysql> call pro_test();
+------+
| id |
+------+
| 3 |
| 4 |
| 1 |
+------+
3 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
root呼叫儲存過程:
(root:localhost:Wed Dec 14 15:43:45 2016)[dbtest]>call pro_test();
+------+
| id |
+------+
| 3 |
| 4 |
| 1 |
+------+
3 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
場景03結論:dbuser01使用者存在,且Security_type: DEFINER ,dbuser01建立儲存過程後,需要賦予賬戶execute 儲存過程pro_test的許可權,還要被賦予儲存過程裡相應物件的訪問許可權,比如select on dbtest.t1許可權,否則會報無許可權執行。即呼叫儲存過程的時候會檢查Definer: ##看此使用者是否有執行儲存過程許可權、訪問物件許可權
Security_type: DEFINER
儲存過程pro_test呼叫場景四
場景04:建立儲存過程者:dbuser02
dbuser01許可權:usage on *.*,create routine ON `dbtest`.*, execute on procedure dbtest.pro_test,select on dbtest.t1
dbuser02許可權:execute on procedure dbtest.pro_test
Definer: dbuser01@10.127.%
Security_type: DEFINER
(root:localhost:Wed Dec 14 15:44:44 2016)[dbtest]>grant execute on procedure dbtest.pro_test to 'dbuser02'@'10.127.%' identified by 'dbuser02' ;
Query OK, 0 rows affected (0.00 sec)
dbuser02呼叫儲存過程pro_test:
[root@node4 ~]# mysql -udbuser02 -pdbuser02 -h10.127.32.121 -D dbtest
mysql> call pro_test();
+------+
| id |
+------+
| 3 |
| 4 |
| 1 |
+------+
3 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t1;
ERROR 1142 (42000): SELECT command denied to user 'dbuser02'@'10.127.32.122' for table 't1'
場景04結論:dbuser01使用者存在,且Security_type: DEFINER ,dbuser01建立儲存過程後,需要賦予賬戶execute 儲存過程pro_test的許可權,還要被賦予儲存過程裡相應物件的訪問許可權,比如select on dbtest.t1許可權,否則會報無許可權執行。即呼叫儲存過程的時候會檢查Definer: ##看此使用者是否有執行儲存過程許可權、訪問物件許可權
Security_type: DEFINER
其他使用者如dbuser02若要呼叫pro_test儲存過程,只需要被賦予execute許可權即可,裡面的物件許可權無需擁有,只要建立過程的使用者有執行許可權、訪問物件許可權即可。
儲存過程pro_test呼叫場景五
場景05:刪除使用者dbuser01
dbuser02許可權:execute on procedure dbtest.pro_test,select on dbtest.t1
Definer: dbuser01@10.127.%
Security_type: DEFINER
(root:localhost:Wed Dec 14 16:11:13 2016)[dbtest]>delete from mysql.user where user='dbuser01';
Query OK, 1 row affected (0.00 sec)
(root:localhost:Wed Dec 14 16:11:24 2016)[dbtest]>flush privileges;
Query OK, 0 rows affected (0.00 sec)
(root:localhost:Wed Dec 14 16:31:29 2016)[dbtest]>grant SELECT ON `dbtest`.`t1` to 'dbuser02'@'10.127.%' ;
Query OK, 0 rows affected (0.00 sec)
dbuser02呼叫儲存過程pro_test:
mysql> call pro_test;
ERROR 1449 (HY000): The user specified as a definer ('dbuser01'@'10.127.%') does not exist
root呼叫儲存過程:
(root:localhost:Wed Dec 14 16:11:27 2016)[dbtest]>call pro_test;
ERROR 1449 (HY000): The user specified as a definer ('dbuser01'@'10.127.%') does not exist
(root:localhost:Wed Dec 14 16:12:08 2016)[dbtest]>show procedure status \G
*************************** 1. row ***************************
Db: dbtest
Name: pro_test
Type: PROCEDURE
Definer: dbuser01@10.127.%
Modified: 2016-12-14 14:24:46
Created: 2016-12-14 14:24:46
Security_type: DEFINER
Comment:
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: utf8_general_ci
1 row in set (0.00 sec)
場景05結論:dbuser01使用者被刪除,且Security_type: DEFINER ,dbuser01建立儲存過程pro_test無法被其他賬戶訪問。即呼叫儲存過程的時候會檢查
Definer: ##看此使用者是否有執行儲存過程許可權、訪問物件許可權
Security_type: DEFINER
儲存過程pro_test呼叫場景六
場景06:刪除使用者dbuser01
dbuser02許可權:execute on procedure dbtest.pro_test
Definer: dbuser01@10.127.%
Security_type: INVOKER
(root:localhost:Wed Dec 14 16:31:50 2016)[dbtest]>alter procedure pro_test SQL SECURITY INVOKER ;
Query OK, 0 rows affected (0.00 sec)
dbuser02呼叫儲存過程pro_test:
mysql> call pro_test;
+------+
| id |
+------+
| 3 |
| 4 |
| 1 |
+------+
3 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
若果dbuser02只有execute的許可權,沒有select on dbtest.t1的許可權,則呼叫也會報錯
mysql> call pro_test;
ERROR 1142 (42000): SELECT command denied to user 'dbuser02'@'10.127.32.122' for table 't1'
root呼叫儲存過程:
(root:localhost:Wed Dec 14 16:42:56 2016)[dbtest]>call pro_test;
+------+
| id |
+------+
| 3 |
| 4 |
| 1 |
+------+
3 rows in set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
場景06結論:dbuser01使用者被刪除,且Security_type: INVOKER ,dbuser01建立儲存過程pro_test可以被授予execute許可權、訪問儲存過程裡相應物件許可權,的賬戶執行。即呼叫儲存過程的時候會不會檢查
Definer: ##不會看此使用者是否有執行儲存過程許可權、訪問物件許可權
Security_type: INVOKER ##只檢查呼叫儲存過程賬戶是否有執行許可權、訪問物件許可權
儲存過程pro_test呼叫場景七
場景06:dbuser01存在,且賬戶許可權被回收的情況下
dbuser02許可權:execute on procedure dbtest.pro_test
Definer: dbuser01@10.127.%
Security_type: INVOKER
dbuse01僅execute on procedure dbtest.pro_test from dbuser01
(root:localhost:Wed Dec 14 16:43:35 2016)[dbtest]>grant USAGE on *.* to dbuser01@'10.127.%' identified by 'dbuser01';
Query OK, 0 rows affected (0.00 sec)
(root:localhost:Wed Dec 14 16:58:10 2016)[dbtest]>revoke EXECUTE ON PROCEDURE `dbtest`.`pro_test` from 'dbuser01'@'10.127.%' ;
Query OK, 0 rows affected (0.00 sec)
dbuser01呼叫儲存過程pro_test:
mysql> call pro_test;
ERROR 1370 (42000): execute command denied to user 'dbuser01'@'10.127.%' for routine 'dbtest.pro_test'
dbuser02呼叫儲存過程pro_test:
mysql> call pro_test;
+------+
| id |
+------+
| 3 |
| 4 |
| 1 |
+------+
3 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
root呼叫儲存過程:
(root:localhost:Wed Dec 14 16:58:37 2016)[dbtest]>call pro_test;
+------+
| id |
+------+
| 3 |
| 4 |
| 1 |
+------+
3 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
dbuser01回收execute on procedure dbtest.pro_test from dbuser01以及select on dbtest.t1
(root:localhost:Wed Dec 14 16:59:45 2016)[dbtest]>revoke select on `dbtest`.`t1` from 'dbuser01'@'10.127.%' ;
Query OK, 0 rows affected (0.00 sec)
dbuser01呼叫儲存過程pro_test:
mysql> call pro_test;
ERROR 1370 (42000): execute command denied to user 'dbuser01'@'10.127.%' for routine 'dbtest.pro_test'
dbuser02呼叫儲存過程pro_test:
mysql> call pro_test;
+------+
| id |
+------+
| 3 |
| 4 |
| 1 |
+------+
3 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
root呼叫儲存過程:
(root:localhost:Wed Dec 14 17:01:17 2016)[dbtest]>call pro_test;
+------+
| id |
+------+
| 3 |
| 4 |
| 1 |
+------+
3 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
場景07結論:dbuser01使用者存在,且Security_type: INVOKER ,dbuser01建立儲存過程pro_test可以被授予execute許可權、訪問儲存過程裡相應物件許可權的賬戶執行。即呼叫儲存過程的時候會不會檢查,即時是dbuser01是儲存過程的建立者,但其沒有被賦予execute和select on dbtest.t1的許可權,其也無法執行pro_test.
Definer: ##不會看此使用者是否有執行儲存過程許可權、訪問物件許可權
Security_type: INVOKER ##只檢查呼叫儲存過程賬戶是否有執行許可權、訪問物件許可權
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/27067062/viewspace-2130598/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL儲存過程的許可權問題MySql儲存過程
- ORACLE中儲存過程的許可權問題Oracle儲存過程
- mysql儲存過程的許可權 definerMySql儲存過程
- 呼叫者儲存過程訪問許可權問題儲存過程訪問許可權
- 儲存過程與許可權儲存過程
- 儲存過程與許可權(二)儲存過程
- MySQL儲存過程詳解 mysql 儲存過程MySql儲存過程
- 在儲存過程中使用EXECUTE IMMEDIATE報許可權問題儲存過程
- 資料庫許可權-儲存過程資料庫儲存過程
- 關於檢視和儲存過程的許可權問題探究儲存過程
- 儲存過程中使用Dbms_Scheduler包的許可權問題儲存過程
- 儲存過程,角色相關的呼叫者許可權和定義者許可權問題儲存過程
- MySQL儲存過程詳解 mysql 儲存過程linkMySql儲存過程
- mysql儲存過程詳解MySql儲存過程
- oracle儲存過程許可權繼承小結Oracle儲存過程繼承
- 儲存過程許可權__Authid Current_User儲存過程
- MySQL 許可權詳解MySql
- 解決執行儲存過程出現許可權不足問題(ORA-01031)儲存過程
- 檢視、儲存過程以及許可權控制練習儲存過程
- MySQL許可權問題MySql
- 【許可權】儲存過程執行時,報ORA-01031許可權不足儲存過程
- 如何在儲存過程中擁有role的許可權儲存過程
- mysql多次呼叫儲存過程的問題MySql儲存過程
- 儲存過程問題。。儲存過程
- all許可權使用者無法執行儲存過程儲存過程
- 詳解Oracle建立使用者許可權全過程Oracle
- mysql儲存過程經典例項詳解MySql儲存過程
- win10 儲存excel報錯 許可權問題怎麼解決Win10Excel
- mongo 儲存過程詳解Go儲存過程
- 儲存過程的詳解儲存過程
- java儲存過程呼叫servlet的授權問題Java儲存過程Servlet
- 讓使用者擁有儲存過程的除錯許可權儲存過程除錯
- Mysql資料庫許可權問題MySql資料庫
- MySQL儲存過程中的sql_mode問題MySql儲存過程
- Vim儲存時許可權不足
- oracle儲存過程!解決網友問題Oracle儲存過程
- 定義者許可權儲存過程role無效,必須要有顯式授權儲存過程
- mysql 儲存過程MySql儲存過程