軟件安全測試是保證軟件能夠安全使用的最主要的手段,如何進行高效的安全測試成為業界關注的話題。多年的安全測試經驗告訴我們,做好軟件安全測試的必要條件是:一是充分了解軟件安全漏洞,二是擁有高效的軟件安全測試技術和測試工具。
一:安全主要漏洞與測試方法分析
軟件安全保證的主要目的就是為了防止黑客或者惡意的內部人員對軟件進行攻擊,并保證軟件在受到惡意攻擊的情況能夠正常運行。而攻擊者主要是通過對軟件系統輸入惡意的數據來進行攻擊。因此,軟件主要的安全問題來源于外部的輸入數據。開放性WEB應用項目安全組織OWASP Top Ten總結每年的全球WEB應用系統十大安全漏洞,其中最多的安全漏洞就是來自外部輸入數據的驗證方面。全球最大的軟件安全廠商Fortify Software公司的軟件安全漏洞分類中安全風險最高的安全漏洞也是輸入驗證與表現這個方面。由外部輸入惡意數據可以直接構成嚴重的軟件安全漏洞主要有:
命令注入(Command Injection)
跨站腳本(Cross-Site Scripting)
拒絕服務(Denial of Service)
HTTP響應截斷(HTTP Response Splitting)
路徑操縱(Path Manipulation)
資源注入(Resource Injection)
配置操縱(Setting Manipulation)
訪問控制:數據庫(Access Control: Database)
日志偽造 (Log Forging)
所以做好外部輸入數據安全測試是軟件安全測試中最重要的工作,那么目前主要安全測試方法有:
1.靜態的代碼安全測試:主要是通過對軟件系統的源代碼進行安全掃描,根據程序中數據流,控制流,語義等信息與其特有軟件安全規則庫進行匹對,從中找出代碼中潛在的安全漏洞。靜態的源代碼安全測試是非常有用的方法,它可以在編碼階段找出所有可能存在安全風險的代碼,這樣開發人員可以在早期解決潛在的安全問題。而正因為如此,靜態代碼測試比較適用于早期的代碼開發階段,而不是測試階段。同時,由于關系到開發部門,測試部門,管理部門等多個部門的工作,在實際的貫徹實施工作上有一定的難度。
2.動態的滲透測試:滲透測試也是我們常用的安全測試方法。使用自動化工具或者人工的方法模擬黑客的輸入,對應用系統進行攻擊性測試,從中找出運行時刻所存在的安全漏洞。這種是測試的特點就是真實有效,一般找出來的問題都是正確的,也是較為嚴重的。但滲透測試一個致命的缺點就是,但由于模擬的測試數據只能到達有限的測試點,覆蓋率很低。根據美國權威機構統計,滲透測試的覆蓋率只能達到20%-30%。漏報率比較高。
二:Dynamic Taint Propagation方法
分析兩種常用的安全測試的方法,對于外部輸入數據的測試都有一定的不足之處,那么如何才能對外部輸入數據進行較好的安全測試呢?業界提出了動態污染傳播的方法(Dynamic Taint Propagation)。
動態污染傳播方法,主要通過跟蹤外部輸入的數據在程序中的傳播過程,和最終執行的情況來分析是否存在安全漏洞和存在什么類別的漏洞。如下圖1,它不需要任何特殊的攻擊性的測試數據,它假定由外部輸入的數據都是不可信的、污染的數據,為數據打上污染的標記,在程序中傳播的過程中,如果經過了嚴格的,我們可以依賴的安全驗證,我們就認真它不再是污染的,掉去污染標記,否則污染標記在整個傳播過程都會被繼承下來。一旦有污染標的數據被送到執行代碼中執行的時候就判斷這里可能存在一個安全漏洞。
圖1:污染數據的傳播過程圖
實現動態污染傳播方法來進行測試,首先要對軟件程序所有二進制碼進行靜態地分析,主要是指定以下信息:
Source:污染數據的來源。找出所有外部數據進行程序的入口的代碼。對于WEB應用系統,主要是指讀取客戶端輸入的數據的地方:如HTML的Form表單,用戶的Request的參數,客戶端的Cookie信息等這些接收外部數據方法。當數據由這些入口點進行程序內部時,數據假定是污染的,被標記上污染標記。
Propagation:污染數據傳播。數據在程序中傳播的過程中,當數據從Source點傳入,標記上污染標記,污染數據在程序中傳播的過程中,無論是被賦給另一個數據,被拼接到另一個數據之中,污染標記都要被繼承下來。
Sink:漏洞的引爆點。找出所有可能引發安全漏洞的代碼。這些代碼常常是根據外部傳入數據而執行特定任務的代碼。如SQL的查詢,HTML中輸出,命令的執行等等。當數據被傳到Sink代碼時,Sink首先去檢查此數據是否帶有污染標記,如果沒有,則沒有安全問題。反之,則此處可能存在安全問題。然后再根據代碼執行的結果來判定是什么類別的安全問題。舉例來說明這一分析過程:
userID = request.getParameter("user");
……
2
try {
sql = "SELECT * FROM users " +"WHERE id='" + userID + "'";
……
stmt.executeQuery(sql);
}
這段代碼在靜態分析過程中,request.getParameter()方法會被標記為一個“污染源”: Source。stmt.executeQuery()方法會被標記為一個“引爆點”:Sink。當用戶輸入數據“user”通過request.getParameter()進入程序并賦值予變量“userID”時, “userID”會被標記上“污染”標記。當用 “userID” 來構造變量“sql”時,“sql”會獲取“userID”的“污染”標記而成為被“污染”的數據。當“sql”被送到Sink函數stmt.executeQuery()中執行的時候,Sink函數的檢測機制檢測到了“sql”有污染標記,從而判定此處可能引發一個安全問題,隨后再根據Sink函數執行“污染”數據“sql”的結果,這里是執行一個SQL查詢命令,依此可以判定此處可能會引發一個SQL—Injection的安全問題。
原文轉自:http://www.uml.org.cn/Test/201001284.asp