天天看點

記一次mysql神奇現象--root可以看到函數内容,普通使用者看不到?概述問題1、檢視權限2、重新授權3、考慮definer

概述

分享一個比較神奇的現象,是我們的開發人員在開發環境因為不規範操作發現的,後來研究了一下是mysql權限控制方面的問題,下面分享一下這個問題的解決過程。

問題

問題:用root使用者在資料庫lcpdb建立函數getUnitChildList可以看到函數内容,但是普通使用者賬号隻能看到函數存在,看不到函數内容,無法修改,且無法調用。而且,普通賬号可以删除這些存儲過程并重建。

記一次mysql神奇現象--root可以看到函數内容,普通使用者看不到?概述問題1、檢視權限2、重新授權3、考慮definer
記一次mysql神奇現象--root可以看到函數内容,普通使用者看不到?概述問題1、檢視權限2、重新授權3、考慮definer

下面介紹下排查時的思路:

1、檢視權限

記一次mysql神奇現象--root可以看到函數内容,普通使用者看不到?概述問題1、檢視權限2、重新授權3、考慮definer

有大佬說這個問題是由于是賦權是采用 all privileges的方式進行賦權的,這種賦權方式,是沒有函數等存儲過程使用的權限。需要重新給普通使用者賦權。因為我們授權剛好是使用這種方式,還是挺符合的。

定義該存儲過程還需要有CREATE ROUTINE的權限、更改存儲過程需要有ALTER ROUTINE的權限(這裡是用超級使用者在lcpdb建立的存儲過程,上述權限都是具備的),調用存儲過程的使用者需要有EXECUTE權限,最終執行存儲過程的使用者也即存儲過程定義者要具備存儲過程定義語句中相關的各種權限。

2、重新授權

alter routine---修改與删除存儲過程/函數

create routine--建立存儲過程/函數

execute--調用存儲過程/函數

grant execute on lcpdb.* to 'fsl'@'%'
grant execute on lcpdb.* to 'fsl'@'localhost'
grant create routine on lcpdb.* to 'fsl'@'%'
grant create routine on lcpdb.* to 'fsl'@'localhost'
grant alter routine on lcpdb.* to 'fsl'@'localhost'
grant alter routine on lcpdb.* to 'fsl'@'%'
flush privileges;
      

授權後檢視函數還是不行,之是以在指令行操作是考慮有可能在navicat看不到,但是指令行可以看到的情況。

記一次mysql神奇現象--root可以看到函數内容,普通使用者看不到?概述問題1、檢視權限2、重新授權3、考慮definer
記一次mysql神奇現象--root可以看到函數内容,普通使用者看不到?概述問題1、檢視權限2、重新授權3、考慮definer

3、考慮definer

在mysql建立view、trigger、function、procedure、event時都會定義一個Definer=‘xxx’

SQL SECURITY { DEFINER | INVOKER } :指明誰有權限來執行。DEFINER 表示按定義者擁有的權限來執行

INVOKER 表示用調用者的權限來執行。預設情況下,系統指定為DEFINER

以存儲過程為例:

(1)MySQL存儲過程是通過指定SQL SECURITY子句指定執行存儲過程的實際使用者;
(2)如果SQL SECURITY子句指定為DEFINER,存儲過程将使用存儲過程的DEFINER執行存儲過程,驗證調用存儲過程的使用者是否具有存儲過程的execute權限和DEFINER使用者是否具有存儲過程引用的相關對象的權限;
(3)如果SQL SECURITY子句指定為INVOKER,那麼MySQL将使用目前調用存儲過程的使用者執行此過程,并驗證使用者是否具有存儲過程的execute權限和存儲過程引用的相關對象的權限;
(4)如果不顯示的指定SQL SECURITY子句,MySQL預設将以DEFINER執行存儲過程。
因為fsl對函數getUnitChildList有執行的權限,但是它依舊沒有權限直接操作mysql庫,由于我們定義的SQL SECURITY為DEFINER,是以在執行時是以root的身份執行的,是以可以正常查詢出來,普通使用者沒有mysql權限
      

這裡執行指令:

grant all privileges on mysql.* to 'fsl'@'%'
      

可以查詢select * from mysql.proc來檢視權限。

記一次mysql神奇現象--root可以看到函數内容,普通使用者看不到?概述問題1、檢視權限2、重新授權3、考慮definer

到這裡問題就解決了。

這裡按資料庫管理規範還是建議root隻做權限方面的控制,不同資料庫用不同使用者來管理,不要用root來直接建立函數,這樣也就不會有這種情況發生啦!