應用安全測試:雙面的黑盒
軟件安全的最大風險是檢驗工具及過程不透明的本質,以及不同的檢驗技術(例如自動化動態測試)不能覆蓋假陰性錯誤的潛在可能性。
盡管安全軟件開發生命周期(SDLC)有很多相關的最佳實踐,但大多數組織依然有一種傾向,那就是主要依賴測試去構建安全的軟件。當前的測試方法有一個最嚴重的副作用,即組織不太清楚哪些已經被其解決方案測試過,而(甚至更重要的是)還有哪些未被測試過。我們的研究表明,任何單一的自動化保證機制最多可以檢驗44%的安全需求。NIST 靜態分析工具博覽會發現,Tomcat中有26個已知的漏洞,但所有靜態分析工具綜合起來只報告了其中4個警告。因為依賴不透明的檢驗過程是一種普遍存在的習慣,甚至已經成為行業標準,因此許多組織在構建安全的軟件時,滿足于把測試作為最主要的手段。
舉個例子,假設你雇用一家咨詢公司為你的軟件執行滲透測試。許多人將這種測試稱為“黑盒”(基于同名的質保技術),測試人員沒有詳細的系統內部構件知識(比如系統代碼)。執行測試之后,一成不變地生成一份報告,概括你應用中的幾類漏洞。你修復了漏洞,然后提交應用做回歸測試,下一份報告反饋說“已清除”——也就是說沒有任何漏洞了。或者充其量僅僅告知你,你的應用在同一時間范圍內不會被同樣的測試人員以同樣的方式攻破。但另一方面,它不會告訴你:
你的應用中還有哪些潛在的威脅?
你的應用中哪些威脅“其實不易受到攻擊”?
你的應用中有哪些威脅未被測試人員評估?從運行期的角度來看,哪些威脅無法測試?
測試的時間及其他約束如何影響了結果的可靠性?例如,如果測試人員還有5天時間,他們還將執行哪些其他的安全測試?
測試人員的技能水平有多高?你能否從不同的測試人員或者另一家咨詢公司手中取得一組相同的結果?
以我們的經驗來看,組織無法回答以上大多數問題。黑盒是兩面的:一方面,測試人員不清楚應用的內部結構;而另一方面,申請測試的組織對自己軟件的安全狀況也缺乏了解。并不只是我們意識到了這個問題:Haroon Meer在44con上討論了滲透測試的挑戰。這些問題大多數都適用于任何形式的驗證:自動化動態測試、自動化靜態測試、手工滲透測試以及手工代碼審查。實際上, 近期有一篇論文介紹了源代碼審查中類似的挑戰。
關于需求的實例
為了更好地說明這個問題,讓我們看一些常見的高風險軟件的安全需求,以及如何將常見的驗證方法應用到這些需求上。
需求:使用安全的哈希算法(如SHA-2)和唯一的混淆值(salt value)去哈希(Hash)用戶密碼。多次迭代該算法。
在過去的一年里,LinkedIn、Last FM和Twitter發生了眾所周知的密碼泄露事件,對于此類缺陷,本條需求是具體地、合乎時宜的。
如何應用常見的驗證方法:
自動化運行期測試:不可能訪問已存的密碼,因此無法使用此方法驗證本需求
手工運行期測試:只有另一些開發導致已存密碼轉儲時,才能使用此方法驗證本需求。這并不是你所能控制的,因此你不能依靠運行期測試去驗證本需求。
自動化靜態分析:只有滿足以下條件時,才可以用此方法驗證本需求:
工具清楚身份認證是如何工作的(例如,使用了標準的組件,就像Java Realms)
工具清楚應用程序使用了哪個特定的哈希算法
如果應用程序為每次哈希使用了唯一的混淆值,工具要清楚混淆算法和混淆值
實際上,認證有很多實現方法,指望靜態分析方法全面地驗證本需求是不切實際的。更為實際的方案是,使用工具簡單地確認認證程序,并指出必須進行安全的哈希和混淆處理。另一個方案是,你來創建自定義規則,用以鑒定算法和哈希值,確認它們是否符合你專屬的策略,盡管,在我們的經驗中這種實踐極為罕見。
手工代碼審查:對于本需求,這是最可靠的常見驗證方法。手工評估人員能夠理解哪一段代碼中發生了認證,驗證哈希和混淆處理符合最佳實踐。
需求:在SQL語句中綁定變量以預防SQL注入
SQL 注入是最具破壞性的應用漏洞之一。近期發現在Ruby on Rails中有一個缺陷,在其技術棧上搭建的應用系統會受到SQL注入攻擊。
如何應用常見的驗證方法:
自動化運行期測試:雖然,運行期測試通過行為分析也許能夠發現存在的SQL注入,但是,卻不能證明沒有SQL注入。因此,自動化運行期測試不能充分地驗證本需求
手工運行期測試:與自動化運行期測試一樣具有相同的局限性
自動化靜態分析:通常能夠驗證本需求,特別是當你使用標準類庫訪問SQL數據庫時。你是否將用戶輸入動態地拼接為SQL語句,還是使用正確地變量綁定,工具應該都可以分辨得出來。然而,這是有風險的,在以下場景中靜態分析可能會漏掉SQL注入漏洞:
你在數據庫上使用存儲過程,并且無法掃描數據庫代碼。在某些情況下,存儲過程也易受到SQL注入
你使用了一種對象關系映射(ORM)類庫,但你的靜態分析工具不支持這種類庫。對象關系映射也易受到注入。
你使用非標準的驅動或類庫去連接數據庫,并且驅動沒有正確地實現常見地安全控制(比如預編譯語句)
手工代碼審查:與靜態分析一樣,手工代碼審查能夠確認沒有SQL注入漏洞。然而,實際上產品應用中可能有幾百或成千上萬條SQL語句。手工審查每一條語句不僅非常耗時,而且容易出錯。
需求:使用授權檢查以確保用戶無法查看其他用戶的數據。
我們每年都能聽到此類 漏洞新的事例。
如何應用常見的驗證方法:
自動化運行期測試:通過訪問兩個不同用戶數據的方式,使用一個用戶的賬號嘗試訪問另一個用戶的數據,自動化工具能夠在一定程度上完成本需求的測試。然而,這些工具不可能清楚一個用戶賬號的哪些數據是敏感的,也不了解把參數“data=account1”修改為“data=account2”表示違反了授權。
手工運行期測試:通常情況下,手工運行期測試是發現這類漏洞最有效的方法,因為人可以擁有必需的領域知識以探明這類攻擊的位置。然而,在有些情況下,運行期測試人員可能無法全面掌握發現這類缺陷所必需的一切信息。例如,如果附加一個類似于“admin=true”的隱藏參數,使你可以不需授權檢查就能訪問其他用戶的數據。
自動化靜態分析:如果沒有規則的定制,自動化工具通常發現不了這種類型的漏洞,因為它需要對領域的理解能力。例如,靜態分析工具不清楚“data”參數表示條件信息,需要授權檢查。
手工代碼審查:手工代碼審查能夠揭露缺失授權的實體(譯者注,比如代碼),這是使用運行期測試難以發現的,比如添加一個“admin=true”的參數的影響。但是,實際上采用這種方式去驗證是否做了授權檢查費時費力。一處授權檢查可能出現在許多不同部分的代碼中,所以手工審查人員可能需要從頭到尾追蹤數條不同的執行路徑,以檢測是否做了授權。
對你的影響
驗證的不透明的本質,意味著有效的軟件安全需求的管理是必要的。對于已列出的需求,測試人員即可以明確他們已經評估一條具體的需求,也可以明確他們所用到的技術。評論家提出,滲透測試不應該遵循一張“類似于審計的檢查表”,因為沒有檢查表可以覆蓋模糊的范圍和特定領域的漏洞。但是,要靈活地找到獨特的問題,就不可避免地要確定已經充分理解了需求。這種情況與標準的軟件質量保證(QA)非常相似:好的質保測試人員即能夠驗證功能需求,也能夠思考盒子的邊界,想辦法去破壞功能。如果只是簡單、盲目地測試,報告一些與功能需求無關的缺陷,就會顯著降低質量保證的效用。那么為什么要接受較低標準的安全測試呢?
在你執行下一次安全驗證活動之前,確保你有軟件安全需求可用于衡量,并且你要明確屬于驗證范圍內的需求。如果你雇傭手工滲透測試人員或源代碼審查人員,他們就可以相對輕松地確定哪些需求是由他們來測試的。如果你使用某種自動化工具或服務,合作的供應商會表明,哪些需求無法用他們的工具或服務可靠地測試。你的測試人員、產品或服務不可能保證完全沒有假陰性錯誤(例如,保證你的應用中不會受到SQL注入攻擊),但同時也要理解,對它們做測試能夠大大有助于增加你的自信心,有信心你的系統代碼中不包含已知的、可預防的安全漏洞。
posted on 2014-09-19 09:54 順其自然EVO 閱讀(629) 評論(0) 編輯 收藏 所屬分類: 安全性測試