程序員十大安全技巧
來源:轉(zhuǎn)自:http://xch6636.51.net
作者:
時(shí)間:2010-04-06
如果在 .NET Framework 環(huán)境中將代碼分離成程序集,請(qǐng)考慮每段代碼所需的權(quán)限級(jí)別。您會(huì)發(fā)現(xiàn)這是一個(gè)很容易的過程:把需要較高權(quán)限的代碼分離到可賦予其更多權(quán)限的單獨(dú)的程序集中,同時(shí)使其余大部分程序集以較低的權(quán)限運(yùn)行,從而在您的代碼周圍添加更多的防護(hù)。 在進(jìn)行此操作時(shí),不要忘了,由于代碼訪問安全 (CAS) 堆棧的作用,您限制的不僅是自己程序集的權(quán)限,也包括您調(diào)用的任何程序集的權(quán)限。
許多人建立了自己的應(yīng)用程序,使得其產(chǎn)品在測(cè)試并提供給客戶后可以插入新的組件。保護(hù)這種類型的應(yīng)用程序非常困難,因?yàn)槟鸁o法測(cè)試所有可能的代碼路徑來發(fā)現(xiàn)錯(cuò)誤和安全漏洞。然而,如果您的應(yīng)用程序是托管的,則 CLR 提供了一個(gè)極好的功能,可以使用它關(guān)閉這些可擴(kuò)展點(diǎn)。通過聲明一個(gè)權(quán)限對(duì)象或一個(gè)權(quán)限集并調(diào)用 PermitOnly 或 Deny,您可以為自己的堆棧添加一個(gè)標(biāo)記,它將阻塞授予您調(diào)用的任何代碼的權(quán)限。通過在調(diào)用某個(gè)插件之前進(jìn)行此操作,您就可以限制該插件所能執(zhí)行的任務(wù)。例如,一個(gè)用于計(jì)算分期付款的插件不需要任何訪問文件系統(tǒng)的權(quán)限。這只是最小權(quán)限的另一個(gè)例子,由此您可以事先保護(hù)自己。請(qǐng)確保記錄下這些限制,并注意,具有較高權(quán)限的插件能夠使用 Assert 語句逃避這些限制。
8. 注意失敗模式
接受它吧。其他人和您一樣憎恨編寫錯(cuò)誤處理代碼。導(dǎo)致代碼失敗的原因如此眾多,一想到這些就讓人沮喪。大多數(shù)程序員,包括我們,更愿意關(guān)注正常的執(zhí)行路徑。那里才是真正完成工作的地方。讓我們盡可能快而無痛地完成這些錯(cuò)誤處理,然后繼續(xù)下一行真正的代碼吧。
只可惜,這種情緒并不安全。相反,我們需要更密切地關(guān)注代碼中的失敗模式。人們對(duì)這些代碼的編寫通常很少深入注意,并且常常沒有經(jīng)過完全測(cè)試。還記得最后一次您完全肯定調(diào)試過函數(shù)的每一行代碼,包括其中每一個(gè)很小的錯(cuò)誤處理程序是什么時(shí)候?
未經(jīng)測(cè)試的代碼常會(huì)導(dǎo)致安全漏洞。有三件事情可以幫助您減輕這個(gè)問題。首先,對(duì)那些很小的錯(cuò)誤處理程序給予和正常代碼同樣的關(guān)注。考慮當(dāng)您的錯(cuò)誤處理代碼執(zhí)行時(shí)系統(tǒng)的狀態(tài)。系統(tǒng)是否處于有效并且安全的狀態(tài)中?其次,一旦您編寫了一個(gè)函數(shù),請(qǐng)逐步將它徹底調(diào)試幾遍,確保測(cè)試每一個(gè)錯(cuò)誤處理程序。注意,即使使用這樣的技術(shù),也可能無法發(fā)現(xiàn)非常隱秘的計(jì)時(shí)錯(cuò)誤。您可能需要給您的函數(shù)傳遞錯(cuò)誤參數(shù),或者以某種方式調(diào)整系統(tǒng)的狀態(tài),以使您的錯(cuò)誤處理程序得以執(zhí)行。通過花時(shí)間單步調(diào)試代碼,您可以慢下來并有足夠的時(shí)間來查看代碼以及系統(tǒng)運(yùn)行時(shí)的狀態(tài)。通過在調(diào)試器中仔細(xì)單步執(zhí)行代碼,我們?cè)谧约旱木幊踢壿嬛邪l(fā)現(xiàn)了許多缺陷。這是一個(gè)已得到證明的技術(shù)。請(qǐng)使用這一技術(shù)。最后,確保您的測(cè)試組合能使您的函數(shù)進(jìn)行失敗測(cè)試。盡量使測(cè)試組合能夠檢驗(yàn)函數(shù)中的每一行代碼。這能幫助您發(fā)現(xiàn)規(guī)律,特別是當(dāng)使測(cè)試自動(dòng)化并在每次建立代碼后運(yùn)行測(cè)試時(shí)。 關(guān)于失敗模式還有一件非常重要的事情需要說明。當(dāng)您的代碼失敗時(shí)要確保系統(tǒng)處于可能的最安全狀態(tài)。下面顯示了一些有問題的代碼:
bool accessGranted = true; // 過于樂觀!
try {
// 看看我們能否訪問 c:test.txt
new FileStream(@"c:test.txt",
FileMode.Open,
FileAccess.Read).Close();
}
catch (SecurityException x) {
// 訪問被拒絕
accessGranted = false;
}
catch (...) {
// 發(fā)生了其他事情
}
盡管我們使用了 CLR,我們?nèi)员辉试S訪問該文件。在這種情況下,并沒有引發(fā)一個(gè) SecurityException。但是,例如,如果文件的自由訪問控制列表 (DACL) 不允許我們?cè)L問呢?這時(shí),會(huì)引發(fā)另一種類型的異常。但由于代碼第一行的樂觀假設(shè),我們永遠(yuǎn)也不會(huì)知道這一點(diǎn)。
編寫這段代碼的一種更好的方法就是持謹(jǐn)慎態(tài)度:
bool accessGranted = false; // 保持謹(jǐn)慎!
try {
// 看看我們能否訪問 c:test.txt
new FileStream(@"c:test.txt",
FileMode.Open,
FileAccess.Read).Close();
// 如果我們還在這里,那么很好!
accessGranted = true;
}
catch (...) {}
這樣會(huì)更加穩(wěn)定,因?yàn)闊o論我們?nèi)绾问。倳?huì)回到最安全的模式。
9. 模擬方式非常容易受到攻擊
編寫服務(wù)器應(yīng)用程序時(shí),您常常會(huì)發(fā)現(xiàn)自己直接或間接使用了 Windows 的一個(gè)稱為模擬的很方便的功能。模擬允許進(jìn)程中的每個(gè)線程運(yùn)行在不同的安全環(huán)境中,通常是客戶端的安全環(huán)境。例如,當(dāng)文件系統(tǒng)重定向器通過網(wǎng)絡(luò)收到一個(gè)文件請(qǐng)求時(shí),它對(duì)遠(yuǎn)程客戶端進(jìn)行身份驗(yàn)證,檢查以確認(rèn)客戶端的請(qǐng)求沒有違反共享上的 DACL,然后把客戶端的標(biāo)記附加到處理請(qǐng)求的線程上,從而模擬客戶端。然后此線程便可以使用客戶端的安全環(huán)境訪問服務(wù)器上的本地文件系統(tǒng)。由于本地文件系統(tǒng)已經(jīng)是安全的,因此這樣做很方便。它會(huì)考慮所請(qǐng)求的訪問類型、文件上的 DACL 和線程上的模擬標(biāo)記來進(jìn)行一個(gè)訪問檢查。如果訪問檢查失敗,本地文件系統(tǒng)會(huì)將其報(bào)告給文件系統(tǒng)重定向器,然后重定向器向遠(yuǎn)程客戶端發(fā)送一個(gè)錯(cuò)誤。毫無疑問,對(duì)文件系統(tǒng)重定向器來說這很方便,因?yàn)樗皇呛?jiǎn)單地把請(qǐng)求傳給本地文件系統(tǒng),讓它去做自己的訪問檢查,就好象客戶端在本地一樣。 這對(duì)于文件重定向器這樣簡(jiǎn)單的網(wǎng)關(guān)而言,一切良好。但模擬常常用在其他更復(fù)雜的應(yīng)用程序中。以一個(gè) Web 應(yīng)用程序?yàn)槔H绻帉懸粋(gè)經(jīng)典的非托管 ASP 程序、ISAPI 擴(kuò)展或 ASP.NET 應(yīng)用程序,在它的 Web.config 文件中有如下指定
<identity impersonate='true'>
那么您的運(yùn)行環(huán)境將有兩種不同的安全環(huán)境:您將具有一個(gè)進(jìn)程標(biāo)記和一個(gè)線程標(biāo)記,一般來說,線程標(biāo)記會(huì)被用來做訪問檢查(見圖 )。假設(shè)您正在編寫一個(gè)在 Web 服務(wù)器進(jìn)程中運(yùn)行的 ISAPI 應(yīng)用程序,并假定大多數(shù)請(qǐng)求未經(jīng)身份驗(yàn)證,則您的線程標(biāo)記可能是 IUSR_MACHINE,而進(jìn)程標(biāo)記卻是 SYSTEM!假設(shè)您的代碼能被一個(gè)壞家伙通過緩沖區(qū)溢出利用。您認(rèn)為他會(huì)只滿足作為 IUSR_MACHINE 運(yùn)行嗎?當(dāng)然不會(huì)。他的攻擊代碼很可能會(huì)調(diào)用 RevertToSelf 以刪除模擬標(biāo)記,從而希望提高他的權(quán)限級(jí)別。在這種情況下,他會(huì)很容易獲得成功。他還可以調(diào)用 CreateProcess。它不會(huì)從模擬標(biāo)記復(fù)制新進(jìn)程的標(biāo)記,而是從進(jìn)程標(biāo)記復(fù)制,這樣新進(jìn)程便可以作為 SYSTEM 運(yùn)行。
最新評(píng)論共有 0 位網(wǎng)友發(fā)表了評(píng)論
查看所有評(píng)論
發(fā)表評(píng)論










