近來幾年,很多大型網站頻發安全事件,比如2011年眾所周知的CSDN密碼洩露事件,2014年eBay也因受到攻擊造成使用者密碼和個人資料洩露,Web安全逐漸進入人們的視野,安全測試也逐漸成為了軟體測試中非常重要的一部分。
提到安全測試,很多人應該都會想到ZAP,ZAP(Zed Attack Proxy)是OWASP提供的一款免費Web安全漏洞掃描工具,使用者可以通過設定瀏覽器和ZAP的Proxy,在開發過程或測試過程中自動檢測Web應用程式是否存在安全漏洞,ZAP還會提供掃描結果的風險等級,修復建議以及一些參考文件,下圖就是ZAP掃描後的一個使用者介面。
除了自動掃描功能,ZAP也支援手動安全測試,通過在資料傳送到伺服器之前手動修改請求資訊來測試Web應用程式是否存在安全漏洞。
很多人會有這樣的疑惑,ZAP能否掃描出所有的安全漏洞?ZAP掃描出的安全漏洞和安全等級是否可靠?用了ZAP,軟體是不是就安全了?
ZAP侷限性
首先雖然ZAP的自動掃描功能非常強大,但對於OWASP Top 10中的某些項或者Top 10以外的一些安全漏洞,想要通過ZAP掃描檢測出來是非常困難的,比如Top 10中的A5 “Security Misconfiguration” 就很難通過掃描檢測出來,所以ZAP所能掃描到的安全漏洞只是OWASP Top 10的一個子集。
其次,ZAP掃描後的安全報告,還是需要結合實際專案進行分析才能確定其有效性和安全等級,比如我們在專案中曾經用ZAP掃描出了 “Cookie set without HttpOnly flag” 的安全隱患,推薦的解決方案是將所有的Cookie都設定成HttpOnly,但現實的情況是專案中前端AJAX需要攜帶這個Cookie來給後端傳送請求,如果設定了這個flag,那麼我們正常的請求也會失敗,所以這個漏洞對我們來說就是無效的,或者說我們是不應該修復的。
另外因為Web應用程式往往比較複雜,會有很多組成部分,比如前端、伺服器端、資料庫等,各層分別使用了不同的框架、語言,而且經常會引入一些第三方的庫、框架或者模組,每一個環節都有可能存在安全隱患,所以僅僅依賴ZAP是不夠的,比如針對第三方元件的安全測試,就可以藉助OWASP提供的另外一款工具Dependency Check。
通過分析實際專案中發現的安全問題,我們發現缺陷大體上如下分佈:
安全問題可以歸為兩大類:
- 一類是比較有共性的,即可以拋開業務上下文,軟體之間共通的一些問題,常見的比較嚴重的安全隱患,如XSS攻擊,CSRF攻擊等,ZAP可以幫我們掃描出大多數的問題。
- 另一類是針對業務需求的,比如非授權的賬戶是否不能訪問/修改他們沒有許可權的資訊等等,對於這一類問題,離開具體的業務上下文,是很難測試的,因為什麼樣的使用者具有什麼樣的許可權往往是業務領域的知識,換句話說,這一類問題的測試重點是看正常的使用者能否按照業務需求所期望地正常使用系統,怎麼區分evil user並阻止其對系統的使用和破壞,需要很強的業務背景。
舉一個簡單的例子,比如一個Web系統有兩種角色,管理員和普通賬戶,業務需求是管理員可以修改所有人的所有資訊,普通賬戶只能看到和修改自己的資訊,如果普通賬戶張三可以通過一些非正常手段修改李四的資訊,或者非系統的使用者(evil user)通過某些方式可以看到系統內賬戶的個人資訊,這些都是嚴重的安全缺陷,而且這一類的缺陷所佔比率比較大,但是都沒有辦法通過ZAP掃描出來,也沒有辦法脫離對業務知識的瞭解來進行測試。
安全內建
ZAP掃描,針對業務上下文的使用者許可權測試(不能侷限於介面,還要通過其他一些方式比如修改請求)以及evil user的使用者場景測試,可以覆蓋絕大多數的Web安全缺陷,但是正如我們沒有辦法將質量注入一個已經成型的產品一樣,安全也是同樣的道理。
如果我們在軟體已經編碼完成之後再引入安全檢查和測試,那麼軟體的安全質量已經確定,後期的修復只能解決已經發現的安全漏洞,不能讓軟體更加安全,而且對於這些安全缺陷,發現得越晚,修復的成本就會越高。
所以為了開發安全質量較高的產品,除了選擇好的工具以及增加業務背景下的安全測試,還非常有必要將安全檢查和測試提前,在軟體開發各個過程中引入安全實踐。
微軟提出的SDL(Security Development Lifecycle)就是這樣的理念,SDL提出了很多軟體開發過程中非常好的的安全活動,比如需求分析階段的“最小許可權原則”,開發階段“棄用不安全的函式”,以及測試階段可以使用“模糊測試”等等,其核心理念就是將軟體安全的考慮整合在軟體開發的每一個階段,從需求,設計,編碼,測試,到最後的釋出整個過程中,下圖是一個簡化版的SDL流程圖,完整的SDL還包括前期的培訓,釋出後的響應等:
ThoughtWorks提出的BSI(Build Security In),即安全內建,強調的也是安全提前的理念,結合敏捷軟體開發實踐,將安全融入到使用者故事的生命週期中,引入安全驗收條件, 不同角色(業務人員、開發人員,測試人員以及客戶)在使用者故事的每個階段對安全驗收條件進行溝通,檢查,驗證,確保在使用者故事交付之前滿足了定義的安全驗收條件,下圖就是使用者故事的生命週期圖以及在各個階段哪些角色會參與哪些安全活動的一個簡單介紹:
在保證使用者故事滿足了安全需求的基礎上,基於迭代/釋出還會有一些整體的功能級別的驗證,做到真正的安全內建。
以上兩種理念強調的都是把安全作為跟功能一樣重要的考慮因素,在軟體開發的各個階段進行溝通和反覆驗證,很多實踐經驗也表明,將安全活動作為軟體開發過程的一部分來執行,其安全效益要大於臨時的或者零散的安全活動。
結論
所以從安全測試的選擇來看,我們不能單一依賴某種工具,比如ZAP掃描,而應該多加入一些基於業務需求的安全測試,多從攻擊者的角度思考問題,更重要的是,可靠的安全測試只能避免安全漏洞造成更大的危害和影響,並不能打造安全的產品,真正的安全產品必定需要整個軟體開發過程中每個環節的保障,需要從業務分析階段就將安全作為重要的考慮因素,將安全實踐融入到整個軟體開發過程中,所有角色共同參與,這樣才能做到真正的安全內建。