存儲過程與觸發(fā)器是Sql Server進行數(shù)據(jù)庫開發(fā)與管理經(jīng)常使用的兩個對象,但是如果對存儲過程與觸發(fā)器的權限設置不當,則會給數(shù)據(jù)庫帶來巨大的安全隱患,抑或是MS就是這么設計的,是本人杞人憂天。
本文測試環(huán)境:sql server2005。
首先,建立測試環(huán)境
建立測試數(shù)據(jù)庫 create database test
在測試數(shù)據(jù)庫中建立兩張表
create table t1(id int ,name varchar(10))
create table t2(id int ,name varchar(10))
向t2表中插入一行數(shù)據(jù)
insert into t2
select 1,'trieagle'
建立sql身份驗證的登陸賬號 trieagle ,同時test數(shù)據(jù)庫中建立用trieagle
一、存儲過程
情景說明:如果某用戶擁有創(chuàng)建和執(zhí)行存儲過程的權限,則該用戶可以建立一個存儲過程,在該存儲過程操作其他表中的數(shù)據(jù)。那么即使該用戶對其他表沒有操作權限,則調(diào)用該存儲過程,可以對其他表中的數(shù)據(jù)進行操作。
1、為trieagle用戶授予創(chuàng)建存儲過程的權限以及執(zhí)行存儲過程的權限
grant create proc to trieagle
注意:trieagle用戶要創(chuàng)建存儲過程的話,可能還需要修改schema的權限
grant alter on schema :: dbo to trieagle
2、trieagle建立存儲過程
Create proc p1
as
select * from t2
3、向trieagle用戶賦予執(zhí)行p1存儲過程的權限
grant exec on p1 to trieagle
4、trieagle執(zhí)行p1存儲過程
Exec P1
結果
Id name
1 trieagle
成功的查看到t2表中的數(shù)據(jù)。
安全隱患在于:如果用戶能夠執(zhí)行、修改存儲過程的話,那么實際上你的數(shù)據(jù)庫中的數(shù)據(jù)是出于一種既不安全的狀態(tài)。
解決方法:如果該允許某個用戶創(chuàng)建存儲過程的話,讓該用戶在其自己的schema上來創(chuàng)建,這樣可以避免上述問題。即:
管理員:grant create schema to trieagle
用戶:create schema trieagle
Go
Create proc trieagle.p1
as
select * from t2
go
Exec trieagle.P1
結果:
消息229,級別14,狀態(tài)5,過程p1,第3 行
拒絕了對對象't2' (數(shù)據(jù)庫'test',架構'dbo')的SELECT 權限。
同樣的情況在oracle上也存在,oracle的解釋是:執(zhí)行者執(zhí)行存儲過程時,會使用存儲過程設計者所具有的權限,但是可以使用authid current_user指定用戶運行存儲過程時使用的權限。Sql server中有類似的語句是 在execute as ,但使用方法還未學習,例如:
create proc p1
with execute as 'trieagle'
as
select * from t2
二、觸發(fā)器
情景說明:如果某用戶擁有修改表的權限以及向表中有(insert、update、delete)權限之一的話,則該用戶即可創(chuàng)建觸發(fā)器。那么該用戶在觸發(fā)器中可以查看其他表的數(shù)據(jù),甚至插入、修改、刪除其他表的數(shù)據(jù),即使該用戶對其他表沒有任何的操作權限。
一、建立測試環(huán)境
為trieagle用戶授予向t1插入數(shù)據(jù)的權限,以及修改t1的權限
grant alter on t1 to trieagle
grant insert on t1 to trieagle
注意,在此并沒有為trieagle用戶賦予t2表的任何權限
二、trieagle用戶創(chuàng)建觸發(fā)器
create trigger t_query_t2
on t1
for insert
as
select * from t2
三、trieagle向t1表中插入數(shù)據(jù)
insert into t1 select 2,'wang'
觀察結果,你會發(fā)現(xiàn),會成功顯示t2表中的數(shù)據(jù)。結果:
Id name
trieagle
安全隱患在于:如果用戶能夠創(chuàng)建觸發(fā)器,并且在該表上有insert、update、delete權限之一的話,則實際上你的數(shù)據(jù)庫中的數(shù)據(jù)是出于一種不安全的狀態(tài)。
跟樓主的觀點相反。我認為存儲過程恰恰是DBA控制數(shù)據(jù)權限的最最強大的工具。用存儲過程來控制權限,那表達能力可遠超過什么select update delete之類的授權。
例如用戶UserA下建立一個工資表Salar。對于用戶UserB可以給員工漲工資,但他的官可能比較下,每次只能給用戶甲一百元。對于用戶UserC是的大領導,他可以給大家的工資加個0.這情況下在數(shù)據(jù)庫層面上,用授權語句顯然不能結果問題,存儲過程就排上用場了。
首先,授權用戶UserB和UserC對UserA.Salar有select權限,但禁止其update,delete。
在UserA下建立存儲過程ProAdd100 為salar表中的工資加100;
授予UserB執(zhí)行Proadd100的權利;
在UserA下建立存儲過程ProMulti10 為salar表工資乘10;
授予UserC執(zhí)行Promulti10的權限。
這樣不就可以隨心所欲的控制數(shù)據(jù)的權限了。多強大。
DBA殺手........
在mssql中,存儲過程中引用了其它的存儲過程可以不存在,這也是一個小隱患
這有什么隱患呢。如果是程序直接訪問數(shù)據(jù)庫,還可能訪問不存在的表呢。這也是隱患嗎。條條大路通羅馬。關鍵不在走哪條路,關鍵在于質(zhì)量。異常處理是必須的。