SQL Server 2008的元數(shù)據(jù)安全
細(xì)粒度權(quán)限架構(gòu)的一個(gè)優(yōu)點(diǎn)就是 SQL Server不僅保護(hù)元數(shù)據(jù),也保護(hù)數(shù)據(jù)。在 SQL Server 2005之前,能夠訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的用戶(hù)可以看到數(shù)據(jù)庫(kù)中所有對(duì)象的元數(shù)據(jù),無(wú)論該用戶(hù)是否可以訪(fǎng)問(wèn)其中的數(shù)據(jù)或是否能夠執(zhí)行存儲(chǔ)過(guò)程。
SQL Server 2008 仔細(xì)檢查數(shù)據(jù)庫(kù)中主體所擁有的各種權(quán)限,僅當(dāng)主體具有所有者身份或擁有對(duì)象的某些權(quán)限時(shí),才會(huì)顯示該對(duì)象的元數(shù)據(jù)。還有一種 VIEW DEFINITION 權(quán)限,即使沒(méi)有該對(duì)象的其他權(quán)限,利用它也能查看元數(shù)據(jù)信息。
這種保護(hù)擴(kuò)展到了某些操作返回的出錯(cuò)消息,這些操作試圖訪(fǎng)問(wèn)或更新用戶(hù)無(wú)權(quán)訪(fǎng)問(wèn)的對(duì)象。SQL Server 不會(huì)確認(rèn)確實(shí)存在一份名為 Address 的表,使攻擊者確信自己的方向是正確的,而是返回提示各種可能性的出錯(cuò)消息。例如,如果用戶(hù)無(wú)權(quán)訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)中的對(duì)象,并且試圖訪(fǎng)問(wèn) Address 表,則 SQL Server 將顯示下列出錯(cuò)消息:
Msg 3701, Level 14, State 20, Line 1
Cannot drop the table 'Address', because it does not exist or you do not have permission.
通過(guò)這種方式,攻擊者無(wú)法確認(rèn)是否真的存在 Address 表。但是,通過(guò)排查問(wèn)題,仍然有很小的攻擊可能性。
SQL Server Agent 代理
關(guān)于 SQL Server 2008 中的授權(quán)模型,一個(gè)最佳示例就是 SQL Server Agent??梢远x往往與 Windows 登錄相關(guān)的各種憑證,且它們將鏈接到具有必要權(quán)限以執(zhí)行一個(gè)或多個(gè) SQL Server Agent 步驟的用戶(hù)。然后,SQL Server Agent 代理將憑證與工作步驟鏈接到一起,以提供必要的權(quán)限。
這就以顆粒方式實(shí)現(xiàn)了“最少特權(quán)”原則:只授予工作步驟必要的權(quán)限,僅此而已??梢噪S意創(chuàng)建代理,并使其與一個(gè)或多個(gè) SQL Server Agent 子系統(tǒng)相關(guān)聯(lián)。這與 SQL Server 2000中的全能式代理帳戶(hù)截然不同,后者允許用戶(hù)在 SQL Server Agent 的任何子系統(tǒng)中創(chuàng)建工作步驟。
注釋 在 SQL Server 2000中升級(jí)服務(wù)器時(shí),將創(chuàng)建單代理帳戶(hù),而且所有的子系統(tǒng)都將被分配這個(gè)單代理帳戶(hù),以使現(xiàn)有的工作繼續(xù)運(yùn)行。升級(jí)完成后,將創(chuàng)建憑證和代理帳戶(hù),通過(guò)實(shí)施更安全、粒度更細(xì)的代理集,以保護(hù)服務(wù)器資源。
圖6為 Management Studio 中的 Object Explorer,它顯示了 SQL Server Agent 中可用的子系統(tǒng)列表。每個(gè)子系統(tǒng)都可以擁有一個(gè)或多個(gè)與之相關(guān)的代理,以為工作步驟分配適當(dāng)?shù)臋?quán)限。該架構(gòu)有一個(gè)例外,即 Transact-SQL 子系統(tǒng)需要在模塊所有者的權(quán)限下執(zhí)行,這與 SQL Server 2000 中的方式相同。
圖1:可與代理相關(guān)聯(lián)的 SQL Server Agent 子系統(tǒng)
新安裝了 SQL Server 之后,只有 System Administrator 角色有權(quán)維護(hù) SQL Server Agent工作,而且只有 sysadmins 能夠使用 Management Studio Object Explorer 中的管理窗格。SQL Server 2008 允許用戶(hù)利用其它一些角色授予各種級(jí)別的權(quán)限??梢苑峙溆脩?hù) SQLAgentUser、SQLAgentReaderRole 或 SQLAgentOperator 角色,其中每一個(gè)角色都會(huì)分配級(jí)別逐漸提高的權(quán)限,以創(chuàng)建、管理及運(yùn)行工作,也可分配 MaintenanceUser 角色,它擁有 SQLAgentUser 的所有權(quán)限,還能創(chuàng)建維護(hù)計(jì)劃。
當(dāng)然,sysadmin 角色的成員可以在任何子系統(tǒng)中隨意執(zhí)行任何操作。要授予其他任何用戶(hù)使用子系統(tǒng)到權(quán)限,需要?jiǎng)?chuàng)建至少一個(gè)代理帳戶(hù),這可授予訪(fǎng)問(wèn)一個(gè)或多個(gè)子系統(tǒng)的權(quán)利。圖7顯示了如何將代理帳戶(hù) MyProxy 分配多個(gè)主體,這里包括一位用戶(hù)和一個(gè)角色。代理帳戶(hù)使用憑證,將其鏈接到帳戶(hù),通常是鏈接到域帳戶(hù),并且擁有在操作系統(tǒng)中執(zhí)行各種任務(wù)的權(quán)限,這些權(quán)限也是子系統(tǒng)所必需的。每個(gè)代理都擁有一個(gè)或多個(gè)與之相關(guān)的子系統(tǒng),它們使主體能夠運(yùn)行這些子系統(tǒng)。
圖2:用于各種子系統(tǒng)的 SQL Server Agent 代理帳戶(hù)
下列代碼就是實(shí)施圖7所示架構(gòu)所需的 Transact-SQL 代碼。首先創(chuàng)建憑證和一個(gè)數(shù)據(jù)庫(kù)對(duì)象,后者將提供操作系統(tǒng)帳戶(hù)鏈接,該帳戶(hù)有權(quán)在子系統(tǒng)中執(zhí)行所需動(dòng)作。然后它添加 MyProxy 代理帳戶(hù),該帳戶(hù)其實(shí)只是憑證的友好名稱(chēng)。接著,它將代理分配兩個(gè)主體,就是 SQL Server 登錄和定制角色。最后,它使代理與4個(gè) SQL Server Agent 子系統(tǒng)相關(guān)聯(lián)。
CREATE CREDENTIAL MyCredential WITH IDENTITY = 'MyDOMAIN\user1' sp_grant_proxy_to_subsystem @proxy_name = 'MyProxy', |
SQL Server Management Studio 完全支持憑證和代理的創(chuàng)建,如圖8所示。這將創(chuàng)建與上一段代碼相同的代理。
圖3:SQL Server Management Studio 中的SQL Server Agent 新代理
代理不只是操作系統(tǒng)中杜絕安全問(wèn)題的一種方式。如果與代理一起使用的憑證沒(méi)有 Windows 權(quán)限,如通過(guò)網(wǎng)絡(luò)寫(xiě)入目錄的權(quán)限,則該代理也不會(huì)有此權(quán)限。也可利用代理為xp_cmdshell 授予有限的執(zhí)行權(quán)限,因?yàn)樗呛诳妥钕矚g利用的工具,只要他們能夠成功威脅到 SQL Server 計(jì)算機(jī)的安全,就會(huì)進(jìn)一步利用該工具將其威脅范圍擴(kuò)展到網(wǎng)絡(luò)空間。代理提供了該領(lǐng)域的保護(hù)機(jī)制,因?yàn)榭v使主體在網(wǎng)絡(luò)上不受任何限制,例如域管理員主體,通過(guò)代理執(zhí)行的任何命令也只擁有憑證帳戶(hù)的有限權(quán)限。
#p#
執(zhí)行上下文
一直以來(lái),SQL Server 都支持所有權(quán)鏈的概念,它可確保管理員和應(yīng)用程序開(kāi)發(fā)人員能夠在數(shù)據(jù)庫(kù)的入口點(diǎn)提前檢查權(quán)限,而不是用來(lái)提供所有被訪(fǎng)問(wèn)對(duì)象的權(quán)限。只要調(diào)用模塊(存儲(chǔ)過(guò)程或函數(shù))或視圖的用戶(hù)擁有模塊的執(zhí)行權(quán)限或視圖的選擇權(quán)限,而且模塊或視圖的所有者曾是被訪(fǎng)問(wèn)對(duì)象的所有者(所有權(quán)鏈),則不會(huì)檢查基本對(duì)象的任何權(quán)限,而且調(diào)用者將收到請(qǐng)求的數(shù)據(jù)。
假如因?yàn)榇a的所有者沒(méi)有被引用對(duì)象的所有權(quán),而導(dǎo)致所有權(quán)鏈被打斷,SQL Server 將按照調(diào)用者的安全上下文檢查權(quán)限。如果調(diào)用者擁有訪(fǎng)問(wèn)對(duì)象的權(quán)限,SQL Server 將返回?cái)?shù)據(jù)。如果沒(méi)有此權(quán)限,SQL Server 將提示出錯(cuò)。
所有權(quán)鏈有一些局限性:它只適用于數(shù)據(jù)操作,而不適用于動(dòng)態(tài) SQL。而且,如要跨越所有權(quán)邊界訪(fǎng)問(wèn)對(duì)象,就不可能實(shí)現(xiàn)所有權(quán)鏈。因此,權(quán)限提前檢查行為只適用于某些場(chǎng)合。
SQL Server 2008 能夠利用執(zhí)行上下文標(biāo)記模塊,這樣模塊中的語(yǔ)句即可供與調(diào)用用戶(hù)并列的特殊用戶(hù)執(zhí)行。通過(guò)這種方式,調(diào)用用戶(hù)仍然需要模塊的執(zhí)行權(quán)限,而SQL Server 將按照模塊的執(zhí)行上下文檢查模塊中語(yǔ)句的權(quán)限??梢岳么诵袨榭头袡?quán)鏈的某些缺陷,因?yàn)樗m用于模塊中的所有語(yǔ)句。想要執(zhí)行權(quán)限提前檢查的管理員可以利用執(zhí)行上下文達(dá)到這一目的。
在定義用戶(hù)定義函數(shù)(除了內(nèi)聯(lián)的表值)、存儲(chǔ)過(guò)程和觸發(fā)器時(shí),可以利用 EXECUTE AS 子句指定SQL Server 要使用哪個(gè)用戶(hù)的權(quán)限驗(yàn)證對(duì)對(duì)象以及過(guò)程引用數(shù)據(jù)的訪(fǎng)問(wèn):
CREATE PROCEDURE GetData(@Table varchar(40)) |
SQL Server 2008 提供了4種 EXECUTE AS 選項(xiàng)。
EXECUTE AS CALLER 指定代碼在模塊調(diào)用者的安全上下文中執(zhí)行。不會(huì)出現(xiàn)假冒的現(xiàn)象。調(diào)用者必須擁有所有被引用對(duì)象的訪(fǎng)問(wèn)權(quán)限。但是,SQL Server 只檢查被打斷的所有權(quán)鏈的權(quán)限,假如代碼的所有者也擁有基本對(duì)象的所有權(quán),則只檢查該模塊的執(zhí)行權(quán)限。這就是向后兼容性的默認(rèn)執(zhí)行上下文。
EXECUTE AS 'user_name' 指定代碼在指定用戶(hù)的安全上下文中執(zhí)行。如果不想使用所有權(quán)鏈,這就是一個(gè)不錯(cuò)的選項(xiàng)。否則,可以創(chuàng)建擁有運(yùn)行代碼以及創(chuàng)建定制權(quán)限集所需權(quán)限的用戶(hù)。
EXECUTE AS SELF 是一個(gè)快捷符號(hào),用于為創(chuàng)建或更改模塊的用戶(hù)指定安全上下文。在內(nèi)部,SQL Server 將保存與模塊關(guān)聯(lián)的實(shí)際用戶(hù)名,而不是保存“SELF”。
EXECUTE AS OWNER 指定安全上下文就是模塊執(zhí)行時(shí)模塊當(dāng)前所有者的安全上下文。如果模塊沒(méi)有所有者,則將使用包含架構(gòu)所有者的上下文。如想修改模塊的所有者,而且不想修改模塊本身,這就是一個(gè)絕佳選項(xiàng)。
利用 EXECUTE AS 選項(xiàng)更改用戶(hù)上下文時(shí),模塊的創(chuàng)建者和更改者必須擁有指定用戶(hù)的IMPERSONATE 權(quán)限。不能從數(shù)據(jù)庫(kù)中刪除指定用戶(hù),除非將所有模塊的執(zhí)行上下文更改為其他用戶(hù)。
用戶(hù)/架構(gòu)分離
SQL Server 2000 沒(méi)有架構(gòu)的概念,而 ANSI SQL-99 規(guī)范將架構(gòu)定義為單個(gè)主體所擁有的所有數(shù)據(jù)庫(kù)對(duì)象集合,而且該主體形成了對(duì)象的一個(gè)命名空間。架構(gòu)就是數(shù)據(jù)庫(kù)對(duì)象的容器(如表、視圖、存儲(chǔ)過(guò)程、函數(shù)、類(lèi)型和觸發(fā)器等)。它的功能與.NTE Framework 和 XML 中的命名空間函數(shù)非常類(lèi)似,該函數(shù)可將對(duì)象進(jìn)行分組,以便數(shù)據(jù)庫(kù)能夠重用對(duì)象名稱(chēng),如允許在一個(gè)數(shù)據(jù)庫(kù)中同時(shí)存在 dbo.Customer 和 Fred.Customer,也可對(duì)不同所有者的對(duì)象進(jìn)行分組。
注意:需要用到目錄視圖,如 sys.database_sys.principals、sys.schemas 和sys.objects 等。原因在于 sysobjects 舊系統(tǒng)表不支持架構(gòu),因此不支持U/S分離。此外,不贊成使用舊目錄視圖,在 SQL Server 的未來(lái)版本中它們將被刪除。
圖9的頂端就是 SQL Server 2000中的架構(gòu)工作原理。當(dāng)管理員在數(shù)據(jù)庫(kù)中創(chuàng)建 Alice 用戶(hù)時(shí), SQL Server 將自動(dòng)創(chuàng)建 Alice 架構(gòu),它隱藏于 Alice 用戶(hù)后面。如果 Alice 登錄了正在運(yùn)行 SQL Server 但沒(méi)有數(shù)據(jù)庫(kù)所有權(quán)的服務(wù)器,而且創(chuàng)建了表1,則該表單實(shí)際名稱(chēng)為 Alice.Table1。這也適用于 Alice 創(chuàng)建的其他對(duì)象,如 Alice.StoredProcedure1 和 Alice.View1。如果 Alice 是數(shù)據(jù)庫(kù)所有者或 sysadmin,她創(chuàng)建的對(duì)象將成為 dbo 架構(gòu)的一部分。雖然我們習(xí)慣說(shuō) dbo 擁有對(duì)象,但這是同一碼事。
圖4:SQL Server 2000 and 2008中的用戶(hù)/架構(gòu)/對(duì)象
需要修改對(duì)象的所有權(quán)時(shí),例如 Alice 離開(kāi)公司而 Lucinda 接手了 Alice 的工作,此時(shí)SQL Server 2000 中用戶(hù)和架構(gòu)的融合會(huì)產(chǎn)生一個(gè)問(wèn)題。系統(tǒng)管理員必須將 Alice 擁有的所有對(duì)象的所有者改為L(zhǎng)ucinda。更成問(wèn)題的是,則 Lucinda 擁有了表的所有權(quán)后,還必須將任何引用 Alice.Table1 的Transact-SQL 或客戶(hù)端應(yīng)用程序代碼改為引用 Lucinda.Table1。根據(jù) Alice 擁有的對(duì)象數(shù)量以及內(nèi)部嵌有該名稱(chēng)的應(yīng)用程序數(shù)量,這可能是一項(xiàng)繁重的工作。Microsoft 公司一直建議內(nèi)置的 dbo 用戶(hù)要擁有所有的數(shù)據(jù)庫(kù)對(duì)象,以避免產(chǎn)生這些問(wèn)題。與修改許多對(duì)象和客戶(hù)端應(yīng)用程序相比,修改數(shù)據(jù)庫(kù)的所有權(quán)要容易得多。
注意:不要被 SQL Server 2000 CREATE SCHEMA 語(yǔ)句迷惑。它只是一種簡(jiǎn)單的方法,用以創(chuàng)建特殊用戶(hù)擁有的表和視圖,以及授予權(quán)限。可以利用該語(yǔ)句命名架構(gòu)的所有者,但不能命名架構(gòu)。SQL Server 仍不可避免地將所有者鏈接到架構(gòu),這要面對(duì)修改所有權(quán)帶來(lái)的所有問(wèn)題。
SQL Server 2008 通過(guò)分離用戶(hù)和架構(gòu)克服了這些問(wèn)題,并實(shí)施了 SQL-99 架構(gòu),如圖9底部所示。利用新增的 CREATE USER DDL 創(chuàng)建 Alice 新用戶(hù)時(shí),SQL Server 不再自動(dòng)創(chuàng)建使用相同名稱(chēng)的架構(gòu)。反之,必須顯式創(chuàng)建架構(gòu),并將其所有權(quán)分配用戶(hù)。由于圖示的所有的數(shù)據(jù)庫(kù)對(duì)象都包含于 Schema1 架構(gòu)中,就是 Alice 最初擁有的架構(gòu),因此只須將架構(gòu)的所有者改為 Lucinda,就可以方便地修改所有架構(gòu)對(duì)象的所有權(quán)。每位用戶(hù)也都被分配默認(rèn)架構(gòu),這樣 SQL Server 將假定沒(méi)有架構(gòu)引用且按照名稱(chēng)引用的任何對(duì)象都位于默認(rèn)架構(gòu)中。在圖9的底部,如果 Alice 使用 Schema1 作為默認(rèn)架構(gòu),她就可將該表命名為 Schema1.Table1 或Table1。Carol 用戶(hù)可能沒(méi)有與其名字關(guān)聯(lián)的默認(rèn)架構(gòu),必須將該表命名為 Schema1.Table1。沒(méi)有默認(rèn)預(yù)定義架構(gòu)的任何用戶(hù)都使用 dbo 作為默認(rèn)架構(gòu)。
在 SQL Server 2008 中,完全合格的對(duì)象名稱(chēng)由4部分組成,這與舊版SQL Server 中的對(duì)象名稱(chēng)類(lèi)似:
server.database.schema.object |
與舊版類(lèi)似,如果對(duì)象所在服務(wù)器與運(yùn)行代碼的服務(wù)器同名,則可忽略服務(wù)器名稱(chēng)。如果連接打開(kāi)了同名數(shù)據(jù)庫(kù),則可忽略數(shù)據(jù)庫(kù)名稱(chēng)。如果使用當(dāng)前用戶(hù)的默認(rèn)架構(gòu)或架構(gòu)為 dbo 所擁有,則可忽略架構(gòu)名稱(chēng),因?yàn)檫@是 SQL Server 嘗試消除對(duì)象名稱(chēng)歧義時(shí)最后用過(guò)的架構(gòu)。
可以利用 CREATE USER 語(yǔ)句而非 sp_adduser 語(yǔ)句創(chuàng)建新用戶(hù)。此系統(tǒng)存儲(chǔ)過(guò)程仍然是為了實(shí)現(xiàn)向后兼容性,但已進(jìn)行了少許修改,以遵循用戶(hù)與架構(gòu)分離的新原則。sp_adduser 創(chuàng)建的架構(gòu)與新用戶(hù)名或應(yīng)用程序角色同名,并將該架構(gòu)作為用戶(hù)的默認(rèn)架構(gòu),這與 SQL Server 2000 的行為類(lèi)似,但提供了分離的架構(gòu)。
注意:使用 ALTER AUTHORIZATION 語(yǔ)句時(shí),可能會(huì)產(chǎn)生這種情況:“您”擁有“我的”架構(gòu)中的表(或反之)。這個(gè)問(wèn)題具有重大的隱含意義。例如,誰(shuí)擁有該表的觸發(fā)器,您還是我?底部的代碼行可以設(shè)計(jì)得非常巧妙,以發(fā)現(xiàn)架構(gòu)范圍對(duì)象或類(lèi)型的真正所有者。有兩種方式可以避開(kāi)此問(wèn)題:
利用 OBJECTPROPERTY(id,”O(jiān)wnerId”)發(fā)現(xiàn)對(duì)象的真正所有者。
利用 TYPEPROPERTY(type,”O(jiān)wnerId”)發(fā)現(xiàn)類(lèi)型的真正所有者。
SQL Server 2008 利用同義詞幫助減少擊鍵次數(shù)??梢岳脙刹糠?、三部分或四部分完整對(duì)象名為任何對(duì)象創(chuàng)建同義詞。SQL Server 使用同義詞訪(fǎng)問(wèn)已定義的對(duì)象。在下列代碼中,“History”同義詞表示在AdventureWorks 數(shù)據(jù)庫(kù)中指定的 schema.table。SELECT 語(yǔ)句返回EmployeeDepartmentHistory 表的內(nèi)容。
USE AdventureWorks CREATE SYNONYM History FOR HumanResources.EmployeeDepartmentHistory SELECT * FROM History |
注意:如果其他人準(zhǔn)備使用同義詞,則管理員或所有者必須為其授予權(quán)限。針對(duì)視圖、表或表值函數(shù),可對(duì)同義詞應(yīng)用GRANT SELECT。針對(duì)過(guò)程或標(biāo)量函數(shù),可對(duì)同義詞應(yīng)用 GRANT EXECUTE,諸如此類(lèi)。
也可通過(guò)以下代碼,為完整的四部分名稱(chēng)定義“History”同義詞:
CREATE SYNONYM History |
假設(shè)當(dāng)前的用戶(hù)擁有使用同義詞的權(quán)限以及讀取表的權(quán)限,則使用類(lèi)似的四部分全名即可在其他數(shù)據(jù)庫(kù)上下文中使用同義詞:
USE pubs |
還要注意,如果不提供架構(gòu)名稱(chēng)作為新同義詞名稱(chēng)的一部分,它將成為默認(rèn)架構(gòu)的一部分。
【編輯推薦】