在共享實例上啟用 CLR 的安全隱患
我的數據庫目前在它自己的實例和虛擬機中被隔離。我的客戶正在淘汰該伺服器,我需要將數據庫遷移到新環境。我的數據庫使用 CLR,所以新環境需要啟用它。
客戶建議使用現有伺服器和現有 SQLServer 2014 Standard 實例,在其上託管來自其他軟體供應商的數據庫。我擔心會招致一種“你破壞它,你買了它”的責任,因為我不能保證那些其他數據庫或其前端的安全策略。我不想做會帶來重大風險的事情。
我不時與其他客戶遇到類似的情況。我是一名數據庫開發人員。我偶爾會為我的中小型企業客戶提供與我自己的產品相關的 DBA 服務,但我絕不是一個熟練的 DBA。每個客戶都有不同的預算、優先級、IT 人員和安全策略,但通常沒有一個客戶的 IT/DBA 可以理解和/或在此詳細級別上進行有能力的風險評估。
在共享實例上啟用 CLR 將如何影響其他數據庫的安全性?(我不是在詢問數據庫級別的權限集級別,只是啟用 CLR 本身)。我需要充分了解風險(如果有的話),以便能夠建議“最佳實踐”和特定於客戶的“足夠安全”的替代方案。
鑑於我們正在處理一個共享實例,可以安全地假設“客戶”數據庫的所有登錄都沒有
sysadmin
權限或被授予CONTROL SERVER
權限。在這種情況下,啟用 SQLCLR 不應該有任何安全風險,不管許多人似乎聲稱什麼。啟用實例級“啟用 CLR”選項僅允許具有適當權限的登錄名來載入程序集,並允許任何有權訪問這些程序集中的對象的人使用已載入的程序集。
如果使用者無法載入程序集,那麼程序集中就不會有未知程式碼的風險,因為不會有任何程序集。然後,如果一個使用者(例如您自己)被授予
CREATE ASSEMBLY
權限(應該與使用證書來處理程序集安全性相結合),那麼只有您可以載入程序集。當然,對於 SQL Server 2005 - 2016 和 SQL Server 2017 及更高版本禁用了“CLR 嚴格安全”實例級配置選項*,數據庫所有者(即
dbo
使用者)和任何具有db_owner
固定數據庫角色的使用者都可以創建SAFE
程序集,但這些不是安全風險。當然,它們可能會帶來性能風險,但對於草率的數據建模、T-SQL、觸發器等也是如此。如果各個供應商不dbo
支持他們的數據庫,那麼這不是問題。如果供應商dbo
針對他們各自的數據庫並且*希望阻止他們創建SAFE
程序集,那麼為CREATE ASSEMBLY``ROLLBACK
如果使用者不是您和/或它未在您的數據庫中執行,則聲明並發出 a 。如果某人是
sysadmin
實例級角色的成員,或者被授予CONTROL SERVER
實例級權限,那麼他們也可以載入程序集。但是,這是大多數與“安全”相關的建議所遺漏的:禁用“啟用 CLR”並不能保護已啟用sysadmin
或具有CONTROL SERVER
權限的人,因為他們有權啟用“啟用 CLR”選項(並啟用xp_cmdshell
等)無論他們想要什麼)!啟用此選項沒有內在風險,因為啟用它不會授予任何人載入存在安全風險的程序集的權限(在 SQL Server 2005 - 2016
dbo
中,角色使用者db_owner
可以載入SAFE
程序集)。並且,一旦載入,程序集標記為EXTERNAL_ACCESS
或UNSAFE
需要額外的安全性(即證書/強命名,而不是TRUSTWORTHY
)才能執行其程式碼。而且,從 SQL Server 2017 開始,預設情況下,所有程序集都需要額外的安全性才能首先載入。並且,額外的安全性(對於程序集的操作)需要sysadmin
級別權限:
- 在有人將數據庫設置為 的不幸情況下
TRUSTWORTHY ON
,擁有數據庫的登錄名需要具有EXTERNAL ACCESS ASSEMBLY
orUNSAFE ASSEMBLY
權限(對於啟用“CLR 嚴格安全”的 SQL Server 2017+ - 預設值 - 必須是UNSAFE ASSEMBLY
),這只能是由系統管理員授予(如果擁有登錄名是 a ,這些權限顯然是隱含的sysadmin
)。希望供應商數據庫永遠不會TRUSTWORTHY
啟用。- 簽署程序集時,需要在數據庫中創建證書或非對稱密鑰
[master]
,然後需要從中創建登錄名,然後需要授予該登錄名EXTERNAL ACCESS ASSEMBLY
或UNSAFE ASSEMBLY
權限(對於具有“CLR 嚴格安全性的 SQL Server 2017+ " 啟用 — 預設 — 必須是UNSAFE ASSEMBLY
)。有關處理 SQLCLR 安全性的一些範例,請參閱:
話雖如此,正如大衛布朗在對此答案的評論中指出的那樣:
另一個重要的一點是關於各種數據庫的利益相關者之間可能存在的信任。在企業環境中,每個人都應該是值得信賴和合作的。在第 3 方託管環境中,您必須假設相鄰工作負載的所有者是完全不受信任甚至是惡意行為者。許多不完全安全的事情在防火牆後面和朋友之間是足夠安全的。