【网络安全】OWASP基准测试测评篇
一、背景
源代碼靜態分析工具(SAST)作為軟件安全的重要保障工具,已經在各個領域被廣泛使用。隨著開源SAST工具的廣泛使用,工具種類的增加,使用者很難判斷工具的優劣及適不適合企業的應用場景,本文從金融、互聯網企業最常用的Java語言代碼分析的角度,對靜態分析進行一次簡要的測評,為大家選擇靜態分析工具提供依據,此外,本文分析了目前靜態代碼分析工具存在的技術問題及工具評估的基本準則。
二、概述
一般來說,誤報和漏報率是SAST最重要的技術評價指標,但由于沒有通用意義上的測試集能夠全面反應靜態分析工具在檢測精度能力方面高低暨分析的敏感度。由此,為了簡化測試難度,本次測評我們選擇了一個Java語言且偏安全的國際通用測試集OWASP benchmark,以反應代碼分析工具在Java安全檢測能力上的強弱。
OWASP基準測試是一個示例應用程序,其中包含來自11個類別的數千個漏洞。基準測試中包括很難通過靜態分析處理的代碼片段,例如:間接調用、不可達分支、映射、依賴于配置文件的值。
用例下載地址:https://github.com/OWASP/Benchmark/releases,可以在一定程度上反應代碼分析工具的檢測能力。
1. 測試依據
下表為某款工具的OWASP檢測結果,如圖所示,左側一列表示所有類別,P/N為正/負樣本數(badcase/goodcase),TP/FP為真/假陽性的數量(badcase報出數/誤報數),TN/FN是真/假陰性的數量(good case報出數/漏報數),TPR和FPR是正確率和誤報率,Y是約登指數,約登指數( Youden’s indx,YI)即正確指數,此指數值的范圍只從0~1,約登指數越大, 其真實性亦越好。其中TPR、FPR、Y的計算公式如下:
TPR=TP/P
FPR=FP/N
Y=[TP/(TP+FN)+TN/(FP+TN)]-1
2. 測試結果
選取市場上主流的SAST工具進行測試,本次選取的測試工具涵蓋較廣,包含國外商業工具、開源工具以及國內自研工具。如SonarQube[1]代碼自動審查工具,該工具是開源工具中使用最多的工具,因為開源免費尤其受很多金融企業喜愛;以色列的Checkmarx CxSAST[2],Micro Focus Fortify[3],目前在電力、金融等行業推廣較多,是中國市場Java應用最多的工具之一;還有在互聯網領域應用的比較廣泛的新思科技的Coverity[4]、IBM Appscan[5]。軍工領域應用比較廣泛的Parasoft的JTest[6]、VeraCode[7]等。下圖是10款靜態分析工具的OWASP基準測試結果。商業SAST工具01-06包括:Checkmarx CxSAST、Micro Focus Fortify、IBM AppScan Source、Coverity Code Advisor、Parasoft Jtest、SourceMeter[9]和Veracode工具。
從上圖可知,覆蓋率指數最大為1(即100%覆蓋,不存在漏報);而誤報率最低的指數為0.12,最高為0.58,尚無。
三、技術分析
靜態代碼分析基本原理:首先將源代碼解析為抽象語法樹;采用控制流分析、多態分析、指向分析、函數調用分析等多種分析算法對基本分析模型;考慮路徑敏感等多種情況,建立符號執行、抽象解釋、圖可達性等程序模型;根據缺陷模式在程序模型的基礎上生成一階邏輯表達式并采用SMT進行可滿足性約束求解,生成最終結果。目前很多工具只做基本分析層面,尤其是開源工具,針對全模式的敏感分析很多工具并不支持,或支持的不好,因此可能產生大量的誤漏報,下面分析了幾種典型的問題:
基于以上要點,分析誤報原因,了解工具的局限性。通過分析,誤報基本由以下幾種情況導致。
1. 集合覆蓋問題
在集合中,部分集合數據存在污染數據,當檢索集合中未污染部分時,導致整個集合覆蓋污染,誤報產生。如:以下代碼中,map中填充帶有一個污點(param)和一個未污點的值(a_value),并且從映射中檢索參數賦值給bar。如果一個集合的一部分被污染了,假設整個collection都被污染,那么在本例中,當我們檢索集合的未污染部分時,導致誤報。
private class Test {public String doSomething(String param) throws ServletException, IOException {String bar = "safe!";java.util.HashMap map831 = new java.util.HashMap();map831.put("keyA-831", "a_Value"); // put some stuff in the collectionmap831.put("keyB-831", param); // put it in a collectionmap831.put("keyC", "another_Value"); // put some stuff in the collectionbar = (String)map831.get("keyB-831"); // get it back outbar = (String)map831.get("keyA-831"); // get safe value back outreturn bar;}} // end innerclass Test2. 集合過度污染問題
在一個集合中,部分集合數據存在污染數據,當對集成做一些操作后,工具無法識別出受污染的數據,導致其他正常數據收到影響,產生誤報。如:在以下代碼中,存在一個未受污染的值(safe),一個受污染的值(param) 和另一個未受污染的值(moresafe) 被添加到列表中。 當第一個值“safe”被刪除后,從列表的開頭,檢索索引為 1 的列表元素,即讀取未受污染的值“moresafe”。同樣導致誤報。
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html");String param = "";boolean flag = true;java.util.Enumeration names = request.getParameterNames();while (names.hasMoreElements() && flag) {String name = (String) names.nextElement(); String[] values = request.getParameterValues(name);if (values != null) {for(int i=0;i<values.length && flag; i++){String value = values[i];if (value.equals("vector")) {param = name;flag = false;}}}} String bar = "alsosafe";if (param != null) {java.util.List valuesList = new java.util.ArrayList( );valuesList.add("safe");valuesList.add( param );valuesList.add( "moresafe" ); valuesList.remove(0); // remove the 1st safe value bar = valuesList.get(1); // get the last 'safe' value} String cmd = org.owasp.benchmark.helpers.Utils.getInsecureOSCommandString(this.getClass().getClassLoader());String[] args = {cmd};String[] argsEnv = { bar }; Runtime r = Runtime.getRuntime();try {Process p = r.exec(args, argsEnv, new java.io.File(System.getProperty("user.dir")));org.owasp.benchmark.helpers.Utils.printOSCommandResults(p, response);} catch (IOException e) {System.out.println("Problem executing cmdi - TestCase");throw new ServletException(e);}}3. 分支問題
在條件分支中,由于條件設置問題,導致某些分支可能永遠無法執行,若工具無法判定某些無法執行的分支,可能導致誤報的產生。如:在以下代碼中,因為num為常量106,(7*18)+num的值永遠大于200,導致bar的值始終都為常量字符串,“This_should_always_happen”。另外一個包含污染數據的分支“param”永遠無法執行。導致工具產生誤報。
private class Test {public String doSomething(String param) throws ServletException, IOException {String bar;// Simple ? condition that assigns constant to bar on true conditionint num = 106;bar = (7*18) + num > 200 ? "This_should_always_happen" : param;return bar;}}四、結論
全面、高效地靜態識別漏洞,減少工具的誤報是靜態分析中至關重要的技術,目前在該領域中,仍然有很大的進步空間。針對本次OWASP的基準測試,在選取的工具中,目前結果最好的工具覆蓋率可以達到100%,且同時誤報率為12%,也說明了工具正不斷趨于成熟,但該結果僅針對OWASP測試用例。在后續的靜態代碼分析技術中,需要不斷對靜態數據流跟蹤器進行持續優化,以此提高檢測精度。
為了更好地對代碼分析工具進行評價,筆者提出了幾個評價維度,并給出評價等級:
| 約登指數 | 查全率-誤報 | 0.9-1.0 | 0.7-0.9 | 0.7- |
| 吞吐量 | 最大檢測代碼規模 | 1000W+ | 100W+ | 10W+ |
| 檢測效率 | 每小時代碼檢測代碼行數 | 100W+ | 50W+ | 10W+ |
| 片段代碼檢測能力 | 能否在編譯不通過情況下檢測 | 支持所有語言 | C/C++,Java | 不支持 |
| 并發檢測能力 | 支持單CPU的多并發測試 | 硬件允許的最大值 | 單進程 | 單進程 |
| 跨語言及框架分析能力 | 支持最新的框架及兼容語言間調用 | 支持70種以上框架 | 支持10種以下 | 不支持 |
| 支持語言 | 支持檢測的語言種類 | 20種+ | 10種+ | 3種+ |
| 與Devops集成能力 | 是否與DevOps主要工具集成 | 支持持續集成工具、版本管理及測試工具,三個方面 | 僅支持版本管理 | 不支持 |
| CWE模式覆蓋數 | 覆蓋的缺陷模式個數 | 200+ | 100+ | 50+ |
最后
【相關資料詳細】
總結
以上是生活随笔為你收集整理的【网络安全】OWASP基准测试测评篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【安全漏洞】ProxyShell漏洞复现
- 下一篇: 【安全】从mimikatz学习Windo