公司最近啟用了Fortify掃描項目代碼,報出較多的漏洞,安排了本人進行修復,近段時間將對修復的過程和一些修復的漏洞總結整理於此!
本篇先對Fortify做個簡單的認識,同時總結一下sql注入的漏洞!
一、Fortify軟件介紹
Fortify是一款能掃描分析代碼漏洞的強大工具,是由一家加州軟件安全廠商開發而成,該公司成立於2003年,它於2010年被惠普收購。現在,它在惠普軟件業務方面作為惠普企業安全產品的一部分,它提供軟件應用程序的安全漏洞保護識別,修復產品和服務。
Fortify Manager(Fortify安全管理平台)是一個為安全管理團隊和軟件開發團隊提供集中管理安全策略和Fortify SCA掃描報告的安全信息綜合管理平台,它可以收集來自Fortify SCA(源代碼掃描器)對多個項目掃描的結果。 當開發人員和安全管理員使用Fortify SCA對多個應用軟件掃描后,其結果會被存放在Fortify Manager數據庫中,然后在控制台中顯示出來,以便他們監視開發過程, 分析關鍵的安全度量元,並作統計和生成詳盡的報告。
二、 Fortify掃描常見漏洞 - Sql Injection(sql注入)
1.1、產生原因:
SQL injection 錯誤在以下情況下發生:
1、數據從一個不可信賴的數據源進入程序。
2、數據用於動態地構造一個 SQL 查詢。
例 1:以下代碼動態地構造並執行了一個 SQL 查詢,該查詢可以搜索與指定名稱相匹配的項。該查詢僅會顯示條目所有者與被授予權限的當前用戶一致的條目。
...
String userName = ctx.getAuthenticatedUserName();
String itemName = request.getParameter("itemName");
String query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"+ itemName + "'";
ResultSet rs = stmt.execute(query);
...
這一代碼所執行的查詢遵循如下方式:
SELECT * FROM items WHERE owner = <userName> AND itemname = <itemName>;
但是,由於這個查詢是動態構造的,由一個不變的基查詢字符串和一個用戶輸入字符串連接而成,因此只有在 itemName 不包含單引號字符時,才會正確執行這一查詢。如果一個用戶名為 wiley 的攻擊者為 itemName 輸入字符串“name' OR 'a'='a”,那么查詢就會變成:
SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name' OR 'a'='a';
附加條件 OR 'a'='a' 會使 where 從句永遠評估為 true,因此該查詢在邏輯上將等同於一個更為簡化的查詢:
SELECT * FROM items;
這種查詢的簡化會使攻擊者繞過查詢只返回經過驗證的用戶所擁有的條目的要求;而現在的查詢則會直接返回所有儲存在 items 表中的條目,不論它們的所有者是誰。
例 2:這個例子指出了將不同的惡意數值傳遞給在例 1 中構造和執行的查詢時所帶來的各種影響。如果一個用戶名為 wiley 在itemName 中輸入字符串“name'; DELETE FROM items; --”,則該查詢將會變為以下:
SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name';DELETE FROM items;--'
眾多數據庫服務器,其中包括 Microsoft(R) SQL Server 2000,都可以一次性執行(同一行)多條用分號分隔的 SQL 指令。對於那些不允許運行用分號分隔的批量指令的數據庫服務器,比如 Oracle 和其他數據庫服務器,攻擊者輸入的這個字符串只會導致錯誤;但是在那些支持這種操作的數據庫服務器上,攻擊者可能會通過執行多條指令而在數據庫上執行任意命令。
圖1.1.1:Oracle服務器執行批量Sql演示
注意成對的連字符 (--);這在大多數數據庫服務器上都表示下面的語句將作為注釋使用,而不能加以執行。在這種情況下,注釋字符的作用就是刪除修改的查詢指令中遺留的最后一個單引號。而在那些不允許這樣加注注釋的數據庫中,通常攻擊者可以如例 1 那樣來攻擊。如果攻擊者輸入字符串“name'); DELETE FROM items; SELECT * FROM items WHERE 'a'='a”就會創建如下三個有效指令:
SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name'; DELETE FROM items; SELECT * FROM items WHERE 'a'='a';
簡而言之,就是攻擊者可能把sql語句或者一些不安全條件以參數的形式傳入到程序中,然后這些sql語句或不安全條件拼接到系統原有的sql語句中,而系統沒有采用預編譯的方式處理原有sql語句,而是動態構造sql語句,此時就有可能導致攻擊者傳人進來的sql語句或是不安全條件被編譯為正常的sql語句而執行了。
1.2、修復方案:
參數化查詢:
a、確保sql語句不通過拼接的方式構造;
b、然后采用一些對sql語句進行預編譯的執行方法;
c、最后再以參數綁定的方式設置sql語句需要的條件的值。