<iframe align="top" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog01.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>
申明。文章僅代表個人觀點,與所在公司無任何聯系。
1.
概述
安全開發周期,即Security Development Lifecycle (SDL),是微軟提出的從安全角度指導軟件開發過程的管理模式。SDL不是一個空想的理論模型。它是微軟為了面對現實世界中安全挑戰,在實踐中的一步步發展起來的軟件開發模式。
那么,SDL到底是什么,它是如何和傳統的軟件開發模式結合?在回答這些問題之前,我們先來闡述一個基本問題,本文的讀者,你,為什么要考慮采用SDL來指導軟件開發?
2.
為什么要從安全的角度來指導整個軟件開發流程?
許多讀者也許會說:對,軟件安全是很重要。但是這些是微軟或其它大型軟件開發廠商進行軟件開發時應該考慮的問題,和我好像沒什么直接關系吧。有這種想法并不奇怪。
回答:現在安全問題已經不局限于操作系統軟件。所有的應用程序,都面臨著安全挑戰。
2.1互聯網環境下的安全挑戰
安全領域是計算機技術中的發展最為活躍的一個分支。每一項新技術的出現,也帶來了相應的風險。不同的時代,不同的技術,就有不同的安全挑戰。
最近幾年來,計算機的攻擊模式的變化,從沒有特定攻擊目的,向有特定的目的變化。不再是簡單的要登上報紙的頭版,或者是惡作劇,而是有特定的目的,即竊取用戶的機密信息,如銀號賬號,密碼等,以獲取經濟上的利益。
目的的變化,導致了手段的變化。若干年前,傳統的攻擊手段主要是針對操作系統的安全漏洞,因為攻擊操作系統可以導致散布病毒的最廣泛的途徑。但是,“最廣泛”,已經不是攻擊的目的。于是,攻擊的軟件系統,已經從操作系統,擴展到圖像處理,辦公處理,備份軟件,反病毒軟件,web應用等等各類應用程序。舉個例子,最流行的一個攻擊方式,sql injection,針對的不是操作系統,而是典型的web應用程序。
特別的,如果開發的應用程序:
·
有面向網絡的功能界面
·
有面向數據庫的應用
·
有不同級別的權限控制
·
有存放重要/敏感信息
就更應該考慮在軟件開發流程加入安全方面的考慮。
2.2傳統的軟件開發流程的局限性
傳統的軟件開發流程中,如瀑布模型,中心圍繞著產品功能,完全沒有安全方面的考慮。因此,無法開發出安全的軟件也就不足為奇了。微軟自身的軟件開發流程,在SDL提出以前,就是一個很好的例子。它可以造就功能上相對完善的軟件,如Windows的早期版本,但是無法滿足在安全上的需要。
需求分析
。傳統的軟件開發流程的需求分析,往往有這個一個傾向,用戶一旦使用軟件,可以直接使用的功能越多越好,所允許的用戶工作環境越靈活越好。但是,實際中,一定是可以直接使用的功能越多越好嗎?往往需要在靈活方便,和安全性能上作一定的平衡。例如,對于不經常需要的功能,缺省配置下是不是應該關閉?
軟件設計
。傳統的軟件設計過程,考慮中心是如何有效,正確的實現功能。往往約定來自相關模塊的數據是值得信賴的,只在最外圍的數據模塊接口處對用戶數據加以校驗。與之帶來的后果就是,如果一個模塊出現安全問題,整個軟件系統就處于不設防狀態。
軟件編碼和評估
。同樣,軟件編碼的實踐主要集中如如何有效,正確的實現功能。沒有針對安全問題的編碼和復查指導,如特定API函數的副作用,堆棧溢出錯誤等等。沒有對應的編譯工具和程序靜態分析工具以檢查通常的代碼安全錯誤。
測試
。按照傳統的黑箱/白箱方式設計數據,是無法模擬一個惡意的攻擊數據的。這是因為傳統的測試數據是根據功能文檔來設計的,數據范圍限于正常數據和邊界情況,以模擬通常的用戶使用環境。
2.3傳統軟件知識結構的不足
以往對于軟件開發的教育,如軟件工程,數據結構,編譯原理,系統結構,程序語言等等,并沒有針對軟件安全方面的知識。
如果開發人員對安全問題沒有的足夠理解,不了解安全設計的基本原理,安全漏洞的常見類型,如何設計針對安全的測試數據,所開發的代碼就自然就更有可能出現安全漏洞。
例如,以下這段代碼[2,p147]就展示了Windows系統RPC調用中的安全漏洞。它就是導致沖擊波病毒(Blaster)爆發的根源。是不是沒想到這么簡單?那么,這段代碼的問題是什么?
HRESULT GetMachineName(WCHAR *pwszPath)
{
WCHAR wszMachineName[ N + 1 ];
...
LPWSTR pwszServeName = wszMachineName;
while (*pwszPath != L'\\')
*pwszServerName++ = *pwszPath++;
...
}
如果你已經看出問題,恭喜你!大多數開發人員在沒有經過安全培訓前,是不知道正確答案的。代碼的問題在于對pwszPath的字符串長度沒有驗證,從而導致wszMachineName堆棧變量的溢出。
這里要特別強調的,這里指的軟件安全的知識,不是指對于安全功能的理解和使用。例如,加密解密的原理,SSL的使用等等。了解這些知識是有用的,但是僅僅掌握SSL的使用,并不能保證設計出的網絡軟件是安全的。
2.4實例:來自微軟自身的數據
Windows Server 2003 是微軟第一次大規模實施SDL 在操作系統的開發上。雖然Windows Server 2003還不是從頭至尾都嚴格按照SDL的規范開發,但我們已經可以從圖1展示的數據中看出,SDL在很大程度上減少了操作系統軟件的安全漏洞。數據來源于[1]。
圖1:Windows 2000和Windows Server 2003 安全漏洞數目對比
3.
如何將SDL應用于傳統軟件開發模式
3.1 SDL綜述
圖2:SDL開發模式
圖2是一個簡化的SDL開發模型。SDL的核心理念,就是將軟件安全的考慮,集成在軟件開發的每一個階段:需求分析,設計,編碼,測試,和維護。
為什么說這是一個簡化的SDL?
·
傳統的軟件開發模型,如瀑布模型,是一個簡化的模型。在實際開發中,需求分析,設計,開發,測試,是一個反復循環的螺旋開發模式(spiral model)。需求分析和設計文檔會經歷若干次的修改。在每一次修改過程中,都應考慮對軟件安全方面的影響。
·
完整的SDL模型,還包括若干更為細化的階段。如在產品正式發布前的Final Security Review (FSR)階段等等。有興趣的讀者可以參考[2]獲取進一步信息。
·
這個模型中沒有包括工程人員的培訓教育。一個再好的流程,如果沒有相應的工程人員來實施,也會是紙上談兵。對工程人員的教育,一是觀念上的改變,加強安全意識。二是基本安全知識的掌握。
3.1.1 SD3+C原則
SD3+C是微軟歸納的實施SDL中的基本原則。
·
安全設計(Secure by Design)。軟件的設計和實現需考慮如何保護其本身(和存儲的信息)抵御外部攻擊。
·
安全配置(Secure by Default)。軟件的缺省配置運行環境應考慮如何降低安全風險。重要的一個假設是軟件自身代碼總存在安全漏洞。那么,如何減少這些安全漏洞的危害?例如,是否可以運行于普通用戶權限,而不需要管理員權限?是否可以缺省關閉某些高風險的代碼模塊?
·
安全部署(Secure in Deployment)。 軟件需提供相應的文檔和工具,指導用戶如何安全的使用。
·
交流(Communications) 。開發人員需要對發布產品中的安全漏洞準備響應方案。
3.2需求分析:設定安全目標
在需求分析階段,加入以下的安全考慮:
·
產品提供的安全功能
·
產品如何安全的與用戶(或其它軟件模塊)交互
·
特別的,安全方面的考慮對產品開發計劃的影響。
·
產品的風險評估和威脅模型(threat modeling)
·
產品的缺省功能配置
3.3安全設計
在安全設計階段,特別加入以下兩方面的考慮。
·
減少攻擊界面。例如,對一個網絡軟件的設計,它需要監聽那些網絡端口,是否可以減少監聽端口的數目?那些用戶可以與這些端口建立連接,是否要加強身份驗證?
·
深層防御。底層模塊的設計中,假設上層模塊有可能出現安全漏洞。對傳遞的數據考慮進一步校驗。
3.4如何避免代碼中的安全問題
每個開發人員都需要遵循安全編碼規范。
·
使用最新的編譯器和編譯選項。對于微軟的最新C/C++編譯器,使用以下兩個編譯選項:
·
/GS 選項。加入檢測函數堆棧緩存溢出錯誤額外代碼。
·
/SAFESEH選項。加入額外的異常處理信息,以確保代碼所調用的是合法的,而不是被非法篡改過的異常處理程序。
·
禁止使用特定的危險API。許多安全漏洞都是由于不當使用危險的API函數導致的。常見的危險函數如strcpy, strcat, sprintf, strlen等等。這些危險函數在最新的C語言運行庫中已經被標為“deprecated”。讀者可以參考[3]獲取進一步的信息。替換這些函數可以考慮使用StrSafe定義的函數。限于篇幅,這里就不給出具體離子了。[4]包括使用StrSafe的詳細信息。
·
使用靜態語言分析工具以掃描安全漏洞
·
定期進行安全代碼復查
3.5安全測試:模擬惡意輸入
安全測試引入了Fuzz測試這個概念。它的主要目的是創建惡意的輸入數據,以模擬軟件被惡意攻擊時的行為。Fuzz測試可包括的對象可以是文件測試,網絡數據測試,用戶界面輸入數據測試,等等。
我們用AVI文件來舉例一個典型的Fuzz測試。下面是AVI HEADER的定義:
typedef struct _avimainheader {
...
DWORDdwStreams;
DWORDdwSuggestedBufferSize;
DWORDdwWidth;
DWORDdwHeight;
...
} AVIMAINHEADER;
假定dwSuggestedBufferSize的通常范圍為1k – 4k,那么,在正常情況下,以下代碼不會出現問題。
dwSuggestedBufferSize = pBuffer->GetDW();
m_pSuggestedBuffer = new char [ dwSuggestedBufferSize ];
但是如果我們在fuzz測試中惡意設定這個輸入變量值為0xFFFF,那么,就可能發現它導致了系統的內存分配錯誤,從而可以避免一個客戶端/服務器端的DOS(deny of service)安全漏洞。
同樣基于fuzz原理,我們根據AVI HEADER的結構信息,設計其它的測試數據,如:
-
惡意的dwStreams
-
惡意的圖像尺寸:dwWidth,dwHeight
-
無或多個AVI HEADER,等等
3.6安全響應和維護:緊急反應
當前任何一個軟件開發模式(包括SDL在內),都無法確保發布的軟件沒有安全漏洞。因此,需要事先制訂對應的相應模式,包括:
-
(內部或外部發現的)安全漏洞以何種途徑匯報
-
如何評估安全漏洞的嚴重級別
-
開發安全補丁的流程
-
測試安全補丁的流程
-
發布安全補丁的流程
-
如何在以后開發中避免類似的安全漏洞,等等
4.
總結
實踐證明,SDL可以有效的減少軟件的安全漏洞,提高軟件的安全。但是它不是萬能的。實施SDL開發的軟件也不能完全避免安全漏洞。例如,Windows Vista就是嚴格按照SDL開發的,但是它依然存在安全漏洞。只不過我們期望,它的安全漏洞的數目和嚴重程度,要比以往的操作系統減少許多。
安全領域中,沒有免費的午餐。SDL的實施,需要時間,精力,教育,管理等多方面的支持。但是,如果不購買這頓午餐的話,晚餐賬單可能會比想象的要高的多。
限于篇幅,這里只能對SDL作一個泛泛介紹。如果需要進一步了解,可以參閱附錄中的參考文獻。
5.
參考文獻
1.
The Trustworthy Computing Security Development Lifecycle, Steve Lipner, Michael Howard
2.
The Security Development Lifecycle, Michael Howard, Steve Lipner
3.
Deprecated CRT Functions,
http://msdn2.microsoft.com/en-us/library/ms235384(VS.80).aspx
, Microsoft Corporation
4.
Using the Strsafe.h Functions, http://msdn2.microsoft.com/en-us/library/ms647466.aspx, Microsoft Corporation
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1600590