1. 程式人生 > >SQL Server 安全篇——資料層面安全性(2)——所有權連結( Ownership Chaining)

SQL Server 安全篇——資料層面安全性(2)——所有權連結( Ownership Chaining)


Ownership Chaining


SQL Server 2016提供了一種叫行級安全性(row-level security,RLS)的功能,但是這種功能是比較有限制的,標準的方式是使用檢視或儲存過程來限制資料返回。並且通過對檢視或儲存過程的授權,可以使得使用者不需要直接訪問底層實體表。 
這種方式的實現基礎來自於一個叫“所有權連結(Ownership Chaining)”。當多個物件被一個查詢順序呼叫時,SQL Server會把這個視為一個鏈。當你把物件“鏈”在一起時,許可權檢查則會變得很複雜,特別是要依據物件的“架構”。
比如有一個檢視V1,訪問兩個表:t1和t2。如果三個物件都屬於同一個擁有者,那麼在SELECT檢視時,檢視會對呼叫者進行許可權校驗,但是在表上的許可權則不會進行校驗。意味著如果想授權另一個使用者UserB對錶T1的特定行有訪問許可權,可以建立一個檢視並查詢使用者被允許的那些行。此時,使用者可以藉助檢視來返回資料而不用直接訪問表。
但是所有者連結也會在某些時候發生中斷,按前面的說法,就是在不同的擁有者情況下。SQL Server需要對這些不同的擁有者進行許可權校驗,如果使用者沒有許可權訪問某些底層表時會報錯。在大部分情況下ownership chaining是一個好東西,因為它可以讓你建立一個保護訪問資源的機制。但是某些時候也會破壞安全性,因為Ownership chains會導致DENY設定被繞過,原因是許可權校驗不會對GRANT或DENY進行。

Cross DB Ownership Chaining

到Ownership Chaining,那就要順帶提一下Cross db Ownership Chaining,前面提到的是庫內的Ownership Chaining,Cross DB Ownership Chaining則是在例項層面跨庫的所有權連結。如果cross db Ownership Chaining=0則禁用跨庫所有權連結,1則為啟用。可以通過SELECT is_db_chaining_on, name FROM sys.databases;來查詢是否啟用。 由於安全原因,微軟並不建議啟用這個只有sysadmin角色成員才能控制的功能,除非所有庫都必須參加。

假設一個伺服器上有不同專案的庫,彼此之間不應該互訪,此時有一個庫A的儲存過程P1想訪問庫B的資料。如果開放了Cross db Ownership Chaining,那麼B會放行P1訪問,這就會導致不必要的安全風險。

小結

Ownership Chaining 通過對某個物件(如檢視)的許可權配置來允許管理多個物件(如表)的訪問,在某些情況下對效能也有少許提升(因為許可權檢查必然需要消耗時間和資源)。它對管理對資料庫的許可權時非常有用,但是如果SQL Server認為某個使用者授予了對訪問鏈中第一個物件(檢視)的許可權,就會認為這個使用者也有共享該檢視所引用的所有檢視和表的許可權。在正式環境下是這種“認為”是不成立和不合理的。因此,首先不要在某些物件中引用過多物件和巢狀引用,這會加大安全風險跟問題偵測工作量。其次,可以考慮借用2016引入的RLS功能。
另外,特權使用者可以使用跨資料庫所有權連結來訪問自身資料庫之外的資料庫物件,只需要在需要訪問的庫B中建立一個本庫A已存在的db_onwer成員的使用者,然後在A中建立一個呼叫B中使用者可訪問的物件,即可繞過許可權來訪問不應該訪問的資源。這就會帶來不安全性。