目前我可以肯定的一點(diǎn)是,任何看過(guò)這篇文章的人都會(huì )立即發(fā)現自己不具備的習慣。這非常好。我知道除此以外還有其他好的想法。這里只是列出我所觀(guān)察到的!因此,下面介紹的是我在這幾年中注意到的幾種典型習慣。
這是長(cháng)期以來(lái)“沒(méi)有銀彈”觀(guān)點(diǎn)的一種轉變,該觀(guān)點(diǎn)是 25 年前 Fred Brookes 在其“人月神話(huà)”一書(shū)中提出的。能否使您的產(chǎn)品具有足夠的安全性完全取決于您自己。其他任何人或任何出色的工具或編程語(yǔ)言都無(wú)法解決所有安全隱患。不要誤解我的意思,我喜歡源代碼分析工具,但他們無(wú)法神奇般地修復您的所有安全漏洞。只有您自己可以做到這一點(diǎn)。
只有創(chuàng )建安全設計和編寫(xiě)安全代碼的開(kāi)發(fā)人員才能構建出安全產(chǎn)品。最后,編寫(xiě)代碼由個(gè)人完成。工具不能取代個(gè)人完成這項工作。因此,您產(chǎn)品的安全性就是您的責任!Blaster 和 CodeRed 蠕蟲(chóng)利用的就是個(gè)人編寫(xiě)的代碼(參見(jiàn)圖 1)。

請記住,要仔細檢查所有代碼,所有代碼都有可能受到攻擊。沒(méi)關(guān)系。受到攻擊也沒(méi)關(guān)系。關(guān)鍵是,您的代碼是否會(huì )遭到破壞?只有您可以決定最終結果。因此您的代碼必須要使您自己滿(mǎn)意。您必須對代碼的質(zhì)量充滿(mǎn)信心,因而在晚上可以安心地休息,因為您知道如果受到攻擊,您已經(jīng)做好了萬(wàn)全的準備,可以防止代碼受到破壞。
如果有可能,最好請一位安全專(zhuān)家對您的代碼進(jìn)行專(zhuān)業(yè)評審。不要讓那些對安全一無(wú)所知的人來(lái)檢查您的代碼,不要期望他們能夠找出安全錯誤和漏洞。要留出充分的時(shí)間讓真正了解安全性的人檢查您的代碼。
不要過(guò)于自負,在需要幫助時(shí)應主動(dòng)尋求幫助。我剛剛提到了,您不應完全依賴(lài)于工具,但您應該利用一切可利用的資源。請對您的代碼運行所有可用的源代碼分析工具,并經(jīng)常這樣做。利用所有可用的防御性語(yǔ)言構造和庫技巧。例如在 C# 語(yǔ)言中,將執行數組訪(fǎng)問(wèn)的面向網(wǎng)絡(luò )的代碼打包,其中數組索引來(lái)自網(wǎng)絡(luò )請求,采用 checked 操作符的形式,以檢測可能出現的整數算法錯誤。
對于這一點(diǎn),我已經(jīng)說(shuō)過(guò)無(wú)數次,但我還要重申一遍:所有輸入在得到證明之前都是不可信的??纯茨切┳钭屓松?lèi)和唇^的安全漏洞,您就會(huì )發(fā)現它們所擁有的最顯著(zhù)的共性就是開(kāi)發(fā)人員相信了輸入的數據。問(wèn)題在于您的代碼假定這些數據是可靠的,那么如果您的假設不正確將會(huì )怎樣?在某一天您的應用程序很可能會(huì )崩潰。如果嚴重的話(huà),攻擊者可能會(huì )在您的流程中插入惡意代碼并破壞您的流程。
安全系統的定義是只執行所要求的任務(wù)而不執行其他任務(wù)的系統。這一定義有些古怪。當輸入的數據存在信任問(wèn)題時(shí),您往往會(huì )讓系統執行其他任務(wù)。常見(jiàn)漏洞和披露 (CVE) 數據 (cve.mitre.org) 的粗略分析顯示,從 2001 年至 2004 年,CVE 跟蹤的所有安全漏洞中有 47% 的漏洞屬于輸入信任問(wèn)題。最顯著(zhù)的問(wèn)題就是緩沖區溢出、整數算法錯誤、跨站點(diǎn)腳本和 SQL 插入錯誤。我們開(kāi)始不斷看到這種漏洞的新變體,如 XPath 插入漏洞和輕型目錄訪(fǎng)問(wèn)協(xié)議 (LDAP) 插入漏洞。
您可以根據幾個(gè)簡(jiǎn)單規則糾正輸入信任問(wèn)題。首先,不要只看您知道的錯誤,這就假定了您知道所有錯誤,并可預測將來(lái)發(fā)生的所有錯誤。查找錯誤是可以的,但條件是這不是您唯一的防御手段。更好的策略是將輸入控制在您知道的正確的范圍內。對于諸如 C# 和 Perl 此類(lèi)的高級語(yǔ)言,我喜歡使用正則表達式來(lái)確保這一點(diǎn)。
其次,拋棄您已知的錯誤。例如,如果某人通過(guò)您的代碼遠程請求一個(gè)文件,并且文件名中包含不確定的字符(如:or \),請拒絕該請求。并且不要告訴攻擊者原因;只要說(shuō)“找不到文件”即可。
最后,凈化數據,這一點(diǎn)并非對所有情形都適用。例如,在 Web 服務(wù)器中,您應對可能不受信任的輸入的輸出進(jìn)行 HTML 編碼。
您應該有威脅模型對吧?利用威脅模型,您可以了解您的軟件可能面臨的風(fēng)險,并確保您有適當的降低風(fēng)險的舉措。但威脅建模帶來(lái)的益處不僅僅限于安全設計。威脅模型還可以幫助您確保代碼質(zhì)量。威脅模型可以告訴您數據的來(lái)源。數據是遠程的還是本地的?數據來(lái)自匿名的用戶(hù),還是來(lái)自可信賴(lài)的(已驗證的)用戶(hù)、管理員?
通過(guò)掌握這些信息,您可以確定您的防御措施是否到位。例如,匿名用戶(hù)和遠程用戶(hù)都可以訪(fǎng)問(wèn)的代碼最好是非常安全的代碼。這并不是說(shuō)只有本地管理員可以訪(fǎng)問(wèn)的代碼就應該是不安全的代碼,我的意思是遠程可訪(fǎng)問(wèn)的代碼(尤其是默認情況下運行的代碼)必須非常安全,這就意味著(zhù)要提供更多的防御措施、對代碼進(jìn)行更詳細的審查、更注意代碼的細節。此外,威脅模型還可以告訴您受保護的數據的特點(diǎn)。例如高價(jià)值業(yè)務(wù)數據和個(gè)人可識別的信息應受到嚴格保護。您的防御措施是否到位?
確保您的威脅模型準確并保持最新,然后確定您的代碼的所有入口點(diǎn),并按可訪(fǎng)問(wèn)性(遠程還是本地,高權限還是低權限(或無(wú)權限)用戶(hù))對其進(jìn)行排序。首先要對最多人可訪(fǎng)問(wèn)的代碼進(jìn)行最深入的審查。最后沿著(zhù)匿名數據路徑審查所有代碼,換句話(huà)說(shuō),從每個(gè)匿名可訪(fǎng)問(wèn)的入口點(diǎn)開(kāi)始,沿著(zhù)該路徑跟蹤數據,檢查代碼的準確性。
安全環(huán)境總是在不斷變化中。似乎每個(gè)星期都會(huì )出現安全問(wèn)題的新變體。這就意味著(zhù)您必須不斷演變并了解新威脅和防御措施,否則您就要承受由此帶來(lái)的后果。
可保持領(lǐng)先的幾個(gè)簡(jiǎn)單策略是經(jīng)常閱讀關(guān)于軟件安全性的優(yōu)秀書(shū)籍。同時(shí)從您過(guò)去的錯誤中吸取教訓,當然能夠從他人的錯誤中吸取教訓則更好。要做到這一點(diǎn),您可以閱讀 bugtraq — 轉至 securityfocus.com 并同意通過(guò)您的收件箱接收 bugtraq 發(fā)布的內容。但請務(wù)必采納以下建議:創(chuàng )建一項收件箱規則,將發(fā)布的內容轉移到一個(gè)特定的文件夾中,以便您進(jìn)行處理。這一點(diǎn)非常重要。
模糊化處理是一項測試技術(shù),旨在找出可靠性錯誤。經(jīng)證實(shí),有 1% 的可靠性錯誤為安全漏洞,很有可能被利用!當然,緩沖區溢出可能會(huì )使應用程序崩潰,但假定出現設計完善的惡意負載,可能不會(huì )出現應用程序崩潰,攻擊者可能會(huì )按照他的意愿運行代碼。在這一點(diǎn)上我們的格言是“今天拒絕服務(wù)就是明天代碼的執行”。
偶然的運氣或模糊化處理幾乎可以找出所有文件解析錯誤/漏洞。Microsoft 對 XLS、PPT、DOC 和 BMP 等多種文件格式進(jìn)行了解析,并發(fā)現了多個(gè)安全漏洞。大多數供應商都存在類(lèi)似的漏洞,因為對復雜的數據結構進(jìn)行解析是一項非常復雜的任務(wù),復雜的代碼會(huì )存在錯誤,其中一些錯誤會(huì )暴露出安全漏洞。
您必須對解析文件和網(wǎng)絡(luò )流量的所有代碼進(jìn)行模糊處理。Microsoft 的安全開(kāi)發(fā)生命周期 (SDL) 中就此對文件格式有何意義有非常具體的介紹。您必須利用一個(gè)文件模糊處理程序,通過(guò)對不正確文件的 100,000 次迭代對所有解析器進(jìn)行模糊處理。目前有一些比較好的模糊處理程序,在我和 Steve Lipner 合著(zhù)的“安全開(kāi)發(fā)生命周期”一書(shū) (microsoft.com/MSPress/books/8753.asp) 中,我們提供了一個(gè)文件模糊處理程序及 C++ 源代碼。
關(guān)于模糊化處理還需要注意一點(diǎn)。如果出現了崩潰,不要認為這只是崩潰。這些所謂的崩潰中有很大一部分都是在請求某人編寫(xiě)漏洞。因此不要簡(jiǎn)單地將一次崩潰認定為“只是一次崩潰”。
在 Microsoft,我們使用質(zhì)量把關(guān)的概念來(lái)幫助降低開(kāi)發(fā)人員使存在漏洞的代碼流入產(chǎn)品的可能性。質(zhì)量把關(guān)是在代碼上運行一組源代碼分析工具,然后進(jìn)行登記,對所有問(wèn)題進(jìn)行標記。所有發(fā)現的問(wèn)題必須在登記完成前修復。您還可以執行嚴格的代碼規則,如阻止對禁用功能的使用,如不能調用 strcpy 或 strncat,不允許無(wú)用的加密。(Microsoft 已經(jīng)禁用了超過(guò) 100 個(gè)針對新代碼的 C runtime 函數?。├?,就加密算法而言,我們不允許在新代碼中使用 DES(密鑰長(cháng)度太短)、MD4 或 MD5(它們目前都已被破解),除非行業(yè)標準中規定使用這些算法。
不要重新發(fā)明功能。如果您具備對特定文件格式進(jìn)行解析的代碼,那么您無(wú)需兩套或三套解析代碼;只需一套解析代碼即可,使其功能足夠強大并將其捆綁在一個(gè)可在多個(gè)項目之間使用的窗體中。
最后,請記住,工具不能取代人來(lái)了解如何編寫(xiě)安全代碼。這就是安全和隱私教育為何如此重要的原因。您需要全面深入的了解這些概念,對您的工具無(wú)法進(jìn)行的調用和洞察做出判斷。
這是我最喜歡的一種習慣。記住,作為一名軟件開(kāi)發(fā)人員,安全方面的隱患會(huì )對您不利。我喜歡稱(chēng)之為“攻擊者的優(yōu)勢和防御者的尷尬”您需要確保代碼和設計在 100% 的時(shí)間內 100% 準確,這是不可能的。更糟糕的是,您還必須在固定的預算內達到這一無(wú)法實(shí)現的目標,同時(shí)還必須考慮到可支持性、兼容性、可訪(fǎng)問(wèn)性和其他“能力”的要求。攻擊者會(huì )用足夠長(cháng)的時(shí)間來(lái)找出錯誤,然后向全世界宣布您的應用程序是不安全的。
在習慣 6 中,我曾經(jīng)提到,您應該停止編寫(xiě)新的不安全代碼。對于習慣 7,您應該關(guān)注所有代碼,因為攻擊者會(huì )攻擊所有代碼,無(wú)論是哪個(gè)時(shí)期的代碼?;ㄐr(shí)間查看舊代碼,找出安全漏洞,并認真考慮受到貶低的舊的不安全功能。如果您使用的是靈活的開(kāi)發(fā)方法,那么您應該考慮派一名或多名專(zhuān)業(yè)人員修復舊代碼,使其質(zhì)量與新代碼持平。
最后,盡可能使用最佳工具。我喜歡源代碼分析工具,并且喜歡所有能夠幫助我編寫(xiě)出更安全代碼的技術(shù)。正如我提到的,工具并非萬(wàn)能的,但它們會(huì )有所幫助。會(huì )有很大幫助!工具還可以幫助衡量源代碼分析得出的問(wèn)題。工具可以快速掃描大量代碼,比人工速度要快得多。而且,這還可以使您感覺(jué)到某些代碼有多么“差”。
我喜歡的一種技巧就是使用可能的最高警告級別編譯代碼,例如在使用 Visual C++® 時(shí)使用 /W4 警告級別,或者在使用 gcc 時(shí)使用 –Wall 警告級別。如果您在代碼中發(fā)現了大量警告,那么可能該代碼還存在編譯程序或其他工具沒(méi)有發(fā)現的其他錯誤。對于這種代碼,在提供代碼前應該對其進(jìn)行更詳細的安全檢查(參見(jiàn)習慣 3)。
我發(fā)現我所尊敬的 Microsoft 內部和外部的開(kāi)發(fā)人員具備了這八種良好的習慣。這些習慣本身不會(huì )使您成為一流的安全開(kāi)發(fā)人員,但它們肯定會(huì )對您有所幫助!
聯(lián)系客服