Alter Database Set Trustworthy On設定資料庫信任,來達到跨資料庫存取資源

Alter Database Set Trustworthy On設定資料庫信任,來達到跨資料庫存取資源

某些時候我們會遇見需要存取其他資料庫上的物件,例如msdbmsdb.dbo.sp_send_dbmail預存程序

 

。我們會想利用該預存程序達到寄發信件的目的。還有利用msdb.dbo.sp_update_schedule讓前端程式可

 

以修改JOB排程。而一般的做法都是在目的資料庫建立使用者並授予足夠的權限來達到目的。

 

 

但有朋友提出如果有相同的帳號(:User1)已存在兩個DB(:DB1DB2),而此時DB2中的User2是否可以

 

利用Execute As User來模擬User1身分進而存取到DB1的資源呢?

 

做個實驗

 

步驟一 : 如下圖所示,我們先建立兩個資料庫(DB1DB2)及兩個登入帳號(User1User2)。而User1可以

 

連接DB1DB2,而User2只有連接DB2的權限。

clip_image002_thumb

 

 

 

步驟二 : 如下圖所示,我們在DB1上建立一個預存程序叫sp1。並且允許User1來執行它。

clip_image004_thumb

 

 

 

步驟三 : 如下圖所示,我們在DB2上建立兩個預存程序叫sp2sp3並且允許User1User2都可以執行它們。

 

* sp2的預存程序並沒有使用Execute As子句 (以預設值來看就是Execute As Caller)

 

* sp3的預存程序我們使用Execute As User方式來模擬User1的身分。

clip_image006_thumb

 

 

 

步驟四 : 如下圖所示,User1DB2資料庫同時執行sp2sp3兩支預存程序。您可以看見沒有使用Execute As子句的

 

sp2執行成功,而使用Execute As User(模擬User1)sp3卻顯示無權限存取DB1(這裡很有趣,User1利用Execute As

 

User來模擬自己後就無法存取DB1了。根據我的測試在沒有開啟Trustworthy狀態下,User1只有在spExecute As

 

Caller狀況下可以存取到DB1的資源)

clip_image008_thumb

 

 

 

步驟五 : 同樣的方式,我們改用User2DB2資料庫同時執行sp2sp3兩支預存程序。您可以看見不管是執行sp2還是sp3

 

都顯示無權限存取DB1

clip_image010_thumb

 

 

 

步驟六 : 重頭戲,我們將DB2資料庫的Trustworthy屬性設定為ON(msdb外,其他預設都是OFF)

 

 

 

 

步驟七 : 重新使用User1來執行DB2上的sp2sp3。如下圖所示兩支預存程序都順利執行。

clip_image014_thumb

 

 

 

步驟八 : 重新使用User2來執行DB2上的sp2sp3。如下圖所示使用Execute As User(模擬User1)sp3執行成功,

 

但沒使用Execute As 子句sp2執行失敗(這是正常的,由於sp2沒使用Execute As 子句,所以是採預設Execute

 

As Caller方式執行,而CallerUser2,因此SQL會驗證User2是否有權限執行。而我們實驗中並沒有讓User2有權限

 

去執行DB1sp1,因此發生錯誤 )

clip_image016_thumb

 

 

 

完成上述實驗後我們可以知道開啟資料庫的Trustworthy屬性後。DB2上的User2可藉由預存程序模擬User1的身分去存取

 

DB1上的資源。雖然很方便但相對也是很危險,一旦有心人士擁有某個資料庫db_owner db_ddladmin 等相關安全權利,

 

且知道 login 及其他資料庫的 user 關係,就有安全疑慮。因為他可以輕易的利用Execute As的方式存取原本不可以碰觸的

 

資源。(備註:要Alter Database Set TrustWorthy,需要Sysadmin的權限)

 

參考資料來源

 

1 . EXECUTE AS 子句

2 . TRUSTWORTHY 資料庫屬性

 

我是ROCK

rockchang@mails.fju.edu.tw