黃 松,龔士豪
(陸軍工程大學(xué) 指揮控制工程學(xué)院,江蘇 南京 210007)
隨著信息化程度的不斷提高,軟件的復(fù)雜性也在不斷增加,這對提高軟件質(zhì)量、保證其行為的可信性帶來了一定的困難。許多軟件產(chǎn)品在發(fā)布甚至廣泛應(yīng)用后,往往仍包含各種各樣的缺陷和漏洞,這不僅降低了用戶體驗,同時也使得軟件面臨安全風(fēng)險。靜態(tài)分析在尋找代碼缺陷和漏洞方面具有舉足輕重的作用,已成為軟件質(zhì)量保證實踐中不可或缺的一部分[1]。靜態(tài)分析工具的應(yīng)用可以在一定程度上提高軟件質(zhì)量, 但分析報告中的大量誤報以及人工檢查報告所需的花費會降低靜態(tài)分析工具的可用性,于是各種報告處理方法不斷涌現(xiàn)。該文將靜態(tài)程序分析報告處理方法定義為“對靜態(tài)程序分析工具輸出的報告進(jìn)行處理,以達(dá)到降低工具誤報率和漏報率目的的一系列方法”。通過對報告進(jìn)行后續(xù)處理,上述問題能夠得到緩解,分析工具的可用性得以提高。迄今為止,機(jī)器學(xué)習(xí)、統(tǒng)計分析、數(shù)據(jù)融合等技術(shù)已被應(yīng)用于報告處理領(lǐng)域之中。
通過調(diào)研國內(nèi)外近些年在程序靜態(tài)分析報告處理方法方面的研究進(jìn)展,簡要綜述程序靜態(tài)分析報告處理方法的研究動向,同時根據(jù)調(diào)研內(nèi)容,討論程序靜態(tài)分析報告處理方法未來可能的研究方向。
程序分析技術(shù)以分析過程“是否需要運行軟件”為準(zhǔn)則,可以劃分為靜態(tài)分析技術(shù)和動態(tài)分析技術(shù)兩大類。動態(tài)分析通過運行程序獲取程序的輸出或者內(nèi)部狀態(tài)等信息來驗證程序是否存在缺陷和漏洞,針對特定的輸入,通??梢匀〉镁容^高的分析結(jié)果,但對于其他輸入則無法保證[2]。靜態(tài)分析無需運行程序,通過語法分析、定理證明、符號執(zhí)行等技術(shù)來發(fā)現(xiàn)程序中存在的缺陷。與動態(tài)分析相比,靜態(tài)分析在編碼階段就可以實施,能更早地發(fā)現(xiàn)問題,并且對程序執(zhí)行路徑分析的更全面,可以發(fā)現(xiàn)更多缺陷。
目前流行的靜態(tài)分析工具,例如Coverity、Klocwork、Fortify、Parasoft等,大多采取多種分析技術(shù)相結(jié)合的分析策略,旨在發(fā)現(xiàn)更多的缺陷和漏洞。但根據(jù)Rice定理:不存在可以判定任何程序是否具有某種非平凡屬性的通用算法[3]。例如程序路徑的可行性就是不可判定的,因此無法要求靜態(tài)分析工具對程序進(jìn)行精確的分析,只能采用流不敏感或上下文不敏感等分析策略給出保守的結(jié)果,這將不可避免地導(dǎo)致誤報和漏報的產(chǎn)生[4]。誤報即分析工具報告程序某處存在缺陷,但實際上此缺陷并不存在。漏報即程序某處實際存在缺陷,而分析工具沒有報告。靜態(tài)分析工具的分析性能大多使用漏報率和誤報率來衡量。
研究人員發(fā)現(xiàn),靜態(tài)分析工具的誤報率通常高達(dá)30%~100%,每千行代碼就會產(chǎn)生40個警報[5]。據(jù)估計,確認(rèn)一個警報的正確性大約需要5.28分鐘,假設(shè)一個工具報告了500個警報,那么需要測試人員每天工作8小時,連續(xù)5.5天才能將這份報告全部檢查完[6]。這種體驗往往會讓測試人員拒絕再使用這些工具。
對此,多年來,人們在靜態(tài)程序分析報告處理方面做了大量的研究工作,取得了很大的進(jìn)步。通過提高靜態(tài)分析工具的分析精度或?qū)蟾孢M(jìn)行有效地后續(xù)處理可以在一定程度上解決上述問題[7]。對于提高分析精度這一方法,許多學(xué)者進(jìn)行了研究[8-10],但由于驗證問題通常是不可判定的,并且分析工具在設(shè)計時也必須在精度與速度之間做出取舍,因此報告中存在誤報是無法避免的。針對第二種方法——對報告進(jìn)行有效地后續(xù)處理,國內(nèi)外的學(xué)者也提出了許多方案,根據(jù)處理方法的基本思想可分為:基于多工具報告融合的處理技術(shù)、基于警報分類的處理技術(shù),以及基于警報排序的處理技術(shù)。這些方法通常是互補(bǔ)的,可以獨立工作,也可以通過不同的方式組合在一起。
雖然市面上存在大量靜態(tài)分析工具,但由于不同靜態(tài)分析工具的工作原理與運行機(jī)制大不相同,單一工具通常只在小部分問題上表現(xiàn)的很好。例如,對于詞法工具來說,當(dāng)漏洞規(guī)則庫不同、漏洞定義的等級不同時,分析結(jié)果會出現(xiàn)很大差異[4]。因此,在檢查源代碼時,為了盡可能發(fā)現(xiàn)其中的缺陷,不能僅使用單一的工具,但每個工具在生成分析報告時遵循的風(fēng)格不同,工具之間的缺陷檢測能力的優(yōu)勢很難結(jié)合起來。若能將不同分析工具的分析結(jié)果通過某種方式融合在一起,則可以充分利用分析工具各自的優(yōu)勢,讓報告間相互補(bǔ)充,相互驗證,降低報告的漏報率與誤報率,有效提高工具的效率和性能。使用戶輕松地從多個靜態(tài)分析工具中受益,從而提升軟件質(zhì)量。
Kong等人[11]提出了一種基于數(shù)據(jù)融合的源代碼靜態(tài)分析漏洞檢測技術(shù)。他們首先將來自不同分析工具的分析報告中的漏洞信息提取出來,以一個六元組序列的形式存儲。六元組包括漏洞的文件名、漏洞所在行數(shù)、危險等級、漏洞類型、導(dǎo)致漏洞的函數(shù)和漏洞威脅評分。通過這種統(tǒng)一的格式,多份報告可以融合為一份報告。此外,融合過程中每條漏洞被賦予一個估分隨機(jī)變量X代表該漏洞為真實漏洞的概率。其值的定義準(zhǔn)則為:
(1)多個工具同時識別的漏洞分值高;
(2)漏洞本身危險等級高則分值高;
(3)來自不同分析工具的結(jié)果以工具自身的可信賴度權(quán)值體現(xiàn)對分值的貢獻(xiàn)。
工具的可信賴度權(quán)值可以由用戶指定,也可以由誤報率和漏報率自動評估。融合以后,漏洞按照估分由高到低排列。該方法經(jīng)過融合多個工具的報告并對最終報告中的警報進(jìn)行排序,增加了檢測出的漏洞數(shù),繼而降低了漏報率,并且最可能是真正漏洞的漏洞被放在前列,用戶可以以較少的時間找出更多的漏洞。但此方法并未考慮不同工具的報告之間存在重復(fù)警報的問題,融合報告中的冗余警報仍需處理。
Dang[12]提出了一個混合模型,將數(shù)據(jù)融合與統(tǒng)計分析相結(jié)合,對不同工具生成的報告中的警報進(jìn)行融合并排序。與Kong等人[11]的方法類似,在數(shù)據(jù)融合時,提取不同工具所產(chǎn)生的警報間共有的屬性,將警報融合為統(tǒng)一格式。例如Cppcheck和SciTool,它們的警報共有屬性是文件名、警報類別和行號,而PMD和FindBugs則是文件名、優(yōu)先級、行號和規(guī)則集。與Kong等人[11]不同的是,Dang并不為單個警報排序,他認(rèn)為工具生成的警報都與文件或類相關(guān),因此可以對文件或類排序。從融合后的警報中挖掘出統(tǒng)計特征之后,對這些特征使用主成分分析法(PCA),從而為文件或類計算得分并排序。該方法可以很好地將具有大量真實缺陷的文件放在警報列表頂部,將具有誤報的文件放在列表底部,但并不會去除誤報也不會檢測正報。
Meng等人[13]通過為缺陷定義缺陷模式,并提供一個通用規(guī)范使它們保持一致的描述風(fēng)格,從而融合來自不同工具的分析報告。每個通用規(guī)范包含三個部分:摘要信息、所屬缺陷模式類別和缺陷嚴(yán)重等級。當(dāng)不同工具產(chǎn)生的結(jié)果被轉(zhuǎn)換為一致的描述風(fēng)格后,再應(yīng)用優(yōu)先級策略對其進(jìn)行排序。優(yōu)先級策略包括:
(1)根據(jù)警報嚴(yán)重等級。例如,屬于“錯誤”的警報要排在“不良風(fēng)格”前面;
(2)同一類中被多次報告的缺陷擁有更高的優(yōu)先級。
經(jīng)過上述操作,來源于不同工具但屬于同一缺陷模式的警報被放到一起,并且危害等級高的警報位于報告前列。用戶可以選擇感興趣的缺陷模式重點關(guān)注,將注意力放在更重要的缺陷上。但此方法僅適用于文中使用的三個Java靜態(tài)分析工具,如果出現(xiàn)不屬于任何缺陷模式的警報則無法對其進(jìn)行處理。此外,雖然來源于不同工具但屬于同一缺陷模式的警報被放到一起,但警報冗余問題依舊存在,并且也沒有分析警報的正確性。
張麗等人[14]為了解決在分析報告簡單融合時,融合報告中引入了每一種工具的誤報的問題,重點研究了如何優(yōu)化融合后分析報告的質(zhì)量。她們利用缺陷數(shù)據(jù)的一些自然屬性,例如報告該缺陷的工具、缺陷所在代碼位置、缺陷所在代碼的復(fù)雜程度等,通過機(jī)器學(xué)習(xí)算法對警報進(jìn)行二元分類(正報和誤報),從而剔除部分警報,實現(xiàn)集成優(yōu)化。能夠?qū)崿F(xiàn)分類的機(jī)器學(xué)習(xí)算法很多,她們選用了樸素貝葉斯、邏輯回歸、決策樹和支持向量機(jī)。優(yōu)化過程包括報告生成與解析、數(shù)據(jù)預(yù)處理、分類優(yōu)化三個部分。其中的數(shù)據(jù)預(yù)處理部分又包括了數(shù)據(jù)清洗、標(biāo)準(zhǔn)化、函數(shù)粒度級別的聚合、向量化以及數(shù)據(jù)分割的過程,以將數(shù)據(jù)處理成機(jī)器學(xué)習(xí)算法所需的形式。經(jīng)過在Juliet數(shù)據(jù)集上的大量實驗可證實,優(yōu)化后的分析報告在各項指標(biāo)上均優(yōu)于優(yōu)化前,其中支持向量機(jī)和決策樹獲得了較好的分類效果。
基于警報分類的處理技術(shù)是根據(jù)警報之間的某些關(guān)系或代碼特征對警報進(jìn)行分類的技術(shù)。在這類方法中,機(jī)器學(xué)習(xí)技術(shù)被大量使用以構(gòu)建分類器,例如k-最近鄰(K-Nearest Neighbor)[15]、隨機(jī)森林(Random Forest)[16]、支持向量機(jī)(Support Vector Machines)[17]、邏輯回歸模型[18]等。在基于警報之間關(guān)系的分類技術(shù)中,通常一組警報中的某一個警報處于主導(dǎo)地位,其正確性被驗證后,同組中的其他警報就無需再檢查?;诖a特征的分類方式則直接將警報分為正報和誤報,測試人員只需檢查正報。兩種方法都大大降低了警報審查的工作量,但錯誤的分類會導(dǎo)致部分正報被忽視,也就造成真實缺陷仍然遺留在程序中,因此對于安全關(guān)鍵型軟件來說,該方法并不安全。
Ruthruff等人[18]使用邏輯回歸模型,基于警報和其所涉及代碼中的信息來預(yù)測警報是否為誤報或可操作警報。值得關(guān)注的是,他們在構(gòu)建模型過程中使用了一種篩選方法,該方法會丟棄預(yù)測能力較低的指標(biāo),節(jié)省了預(yù)測成本。在谷歌進(jìn)行的一項案例研究表明,該模型在預(yù)測誤報方面的準(zhǔn)確率超過85%,在識別可操作警報方面的準(zhǔn)確性超過70%。
張大林等人[19]提出基于缺陷關(guān)聯(lián)的報告處理技術(shù)。他們根據(jù)不同缺陷間的依賴關(guān)系將缺陷分組,當(dāng)缺陷a可靠地依賴于缺陷b,那么如果缺陷b被確定為誤報,則缺陷a也是誤報,缺陷b就被稱為主導(dǎo)缺陷。缺陷間的依賴關(guān)系通過切除一個缺陷的錯誤狀態(tài)來確定,如果一個缺陷的錯誤狀態(tài)被切除后會影響另一個缺陷的警報生成,則依賴關(guān)系存在。而警報是否為誤報是根據(jù)缺陷的錯誤狀態(tài)是否可達(dá)來判斷的,錯誤狀態(tài)不可達(dá)則代表警報為誤報。該方法可以有效減少警報的確認(rèn)工作,為大規(guī)模軟件使用靜態(tài)分析工具提供了有力支持。但如何在靜態(tài)分析工具所提供的抽象域下精確地切除缺陷錯誤狀態(tài)仍需改進(jìn)。Lee等人[20]提出的警報聚類方法與張大林[19]的方法類似,通過尋找主導(dǎo)警報減少檢查警報的負(fù)擔(dān)。在14個開源基準(zhǔn)測試中,他們的聚類方法可以識別出45%的警報是非主導(dǎo)的,相當(dāng)于減少了45%的警報檢查的工作量。
Reynolds等人[21]通過研究不同類型的誤報信息,總結(jié)出14個核心的誤報模式,實現(xiàn)了自動判斷一條警報是否為誤報。在研究過程中,由于判斷一條警報是否為誤報并不容易,因此他們選擇了Juliet測試套件作為數(shù)據(jù)集,因為在這個測試套件中漏洞所在位置已經(jīng)添加了注釋來指示。當(dāng)發(fā)現(xiàn)一條誤報時,他們會對產(chǎn)生這條誤報的源代碼進(jìn)行刪減,直到刪除下一個元素會導(dǎo)致誤報消失。通過這種方式,可以去掉源代碼中與誤報無關(guān)的所有元素,剩下的代碼即為誤報模式。然后為這些模式分類就可以確定代碼庫中反復(fù)出現(xiàn)的源代碼結(jié)構(gòu),正是這些結(jié)構(gòu)會導(dǎo)致靜態(tài)分析工具產(chǎn)生誤報。這項工作減少了開發(fā)人員和測試人員需要驗證的警報數(shù)量,但同時也具有一些局限性。首先,Juliet測試套件是人造數(shù)據(jù)集,不能代表實際代碼。其次,缺乏對誤報模式的規(guī)范描述,這種描述應(yīng)該是獨立于語言的。最后,數(shù)據(jù)不完整,研究中缺乏誤報模式的出現(xiàn)頻率。
在進(jìn)一步研究中,Koc等人[22]在預(yù)處理階段引入了兩種技術(shù)來縮減代碼,分別是方法體和程序切片。方法體是一種較為簡單的方法,僅僅是將包含錯誤行的方法的主體部分保留下來。但需要注意的是,與警報相關(guān)的許多代碼位置并不在警報方法的主體中,很多情況下警報的原因跨越了多個方法和類,因此這種縮減并不完美。程序切片是在程序中給定一個位置,將程序縮減到最小形式,但在該位置仍保持相同行為的技術(shù)。在訓(xùn)練模型階段,同樣使用了兩種技術(shù),分別是基于貝葉斯推理的學(xué)習(xí)模型和基于神經(jīng)網(wǎng)絡(luò)的長短期記憶網(wǎng)絡(luò)(LSTM)。在國際通用數(shù)據(jù)集OWASP benchmark上的實驗表明,樸素貝葉斯模型在方法體和程序切片方法下的分類準(zhǔn)確率分別為63%和72%,LSTM則分別為89.6%和85%,均取得了不錯的分類結(jié)果。但該實驗僅針對OWASP benchmark下的SQL注入缺陷,數(shù)據(jù)集和缺陷類型都比較片面。
Flynn等人[16]分別使用了Lasso回歸模型、分類回歸樹(CART)、 隨機(jī)森林(Random Forest)和極端梯度提升(Extreme Gradient Boosting)四種分類技術(shù),基于28個特征訓(xùn)練分類器。并且使用多個靜態(tài)分析工具,1個開源數(shù)據(jù)集和3個來自合作者的匿名數(shù)據(jù)集生成報告。測試結(jié)果表明,使用多個靜態(tài)分析工具可以有效提高分類的準(zhǔn)確性,但許多類型的缺陷標(biāo)記的不夠充分,導(dǎo)致對這些缺陷的預(yù)測準(zhǔn)確性較差。
Heckman[23]使用51個候選特征,15種機(jī)器學(xué)習(xí)算法建立模型對警報分類,獲得了88%~97%的平均正確率。構(gòu)建模型分為四個步驟:
(1)收集靜態(tài)分析產(chǎn)生的警報的特征。
(2)使用屬性評估算法來選擇重要的警報特征集合。
(3)使用選定的特征集合和機(jī)器學(xué)習(xí)建立模型。
(4)通過指標(biāo)評估選擇出最佳模型。
他們發(fā)現(xiàn),不同項目之間選用的警報特征和最佳模型是不同的。也就是說,當(dāng)面對不同的項目時,需要重新選擇警報特征并訓(xùn)練模型才能取得較好的分類效果,這在工程實踐中顯然是不可取的,如何使分類模型更加通用是值得考慮的問題。
基于警報排序的處理技術(shù)一般通過計算每一條警報是正報的概率來為警報排序,將最有可能揭示真實錯誤的警報放到報告頂端,而具有較低正報可能性的警報被放到報告底部。排序有助于測試人員在給定時間內(nèi)發(fā)現(xiàn)更多的缺陷,提高工作效率。
當(dāng)前有許多不同類型的排序算法,它們僅針對特定的程序語言,并非通用。排序算法的實現(xiàn)方法主要分兩類:第一類是通過分析報告中的每一條警報,尋找錯誤警報之間的關(guān)系和它們之間的相同點,找出錯誤警報的分布規(guī)律,從而計算得出更高效的報告排序;第二類是通過統(tǒng)計的方法,首先經(jīng)過統(tǒng)計學(xué)的分析,使用貝葉斯網(wǎng)絡(luò)構(gòu)造模型,再利用模型建立測試集與訓(xùn)練集,從而預(yù)測每條警報為正報還是誤報。但是一般來說,所有的警報都需要被檢查,由于警報只是被排序而沒有過濾,因此這種方法也被認(rèn)為是一種安全的方法。
Kremenek和Engler[5]提出一種基于統(tǒng)計分析對警報進(jìn)行排序的技術(shù)——Z-Ranking。他們認(rèn)為,在通常情況下,源代碼中的缺陷密度很低,因此在針對某個問題檢查源代碼時,未觸發(fā)該檢查的位置應(yīng)該較多,而觸發(fā)該檢查的位置相對較少。相反,如果檢查導(dǎo)致很多位置觸發(fā)檢查,則這些觸發(fā)很可能是誤報。實驗表明,在報告的前10%條警報中,Z-Ranking能夠比隨機(jī)排序算法發(fā)現(xiàn)平均多3~7倍的錯誤。Jung等人[24]使用另外一種統(tǒng)計方法——貝葉斯統(tǒng)計,來計算警報為正報的概率,然后根據(jù)這些概率對警報進(jìn)行排序,支持用戶設(shè)置概率閾值,只有超過閾值的警報才會報告給用戶。Xypolytos等人[25]提出了一個基于工具性能統(tǒng)計數(shù)據(jù)的排序框架。該框架的前提是要完成一個基準(zhǔn)測試,在基準(zhǔn)測試中,使用精確度和召回率衡量靜態(tài)分析工具針對不同類型的軟件缺陷的分析性能,然后用置信度得分來表示并據(jù)此對警報進(jìn)行組合和排序。初步實驗結(jié)果表明,該方法在提高工具效率和有用性方面具有一定潛力,但基準(zhǔn)測試對排序結(jié)果的影響較大,基準(zhǔn)測試數(shù)據(jù)集的選擇直接影響工具的置信度得分,從而導(dǎo)致最終報告中警報排序結(jié)果并不準(zhǔn)確。
Kremenek等人[26]在進(jìn)一步的研究中,將警報之間的相關(guān)性用于警報排序。經(jīng)過分析來自兩個大型系統(tǒng)(Linux和某商業(yè)系統(tǒng))的歷史漏洞數(shù)據(jù)中的聚類行為,他們發(fā)現(xiàn)漏洞和誤報通常按代碼位置聚集,這種聚集可以發(fā)生在函數(shù)、類等級別,因此利用聚類可以大幅提高警報排序技術(shù)。并且他們將反饋機(jī)制與聚類相結(jié)合,提出了反饋排序算法。當(dāng)測試人員在驗證了部分警報的正確性后,剩余的警報可以根據(jù)測試人員的反饋結(jié)果動態(tài)更新排名。此方案克服了Z-Ranking[5]不會隨檢查結(jié)果更新排名的缺點,充分利用了警報間的相關(guān)性。
Heckman[27]也將開發(fā)人員的反饋用于警報自適應(yīng)排序。首先使用類型精度、代碼位置和是否產(chǎn)生測試失敗這三個因素來計算警報為正報的概率,并根據(jù)此概率為警報排序。其中類型精度是指基于警報類型,該警報是正報的概率,代碼位置是指基于警報在代碼中的位置,該警報是正報的概率,是否產(chǎn)生測試失敗是指針對某個警報測試用例是否會失敗。在當(dāng)前排序的基礎(chǔ)上,開發(fā)人員以過濾警報的方式提供反饋,剩余的警報將根據(jù)反饋自動修改排名。Shen等人[28]在設(shè)計基于靜態(tài)分析工具FindBugs的警報排序策略時也將反饋機(jī)制納入排序過程。首先,通過統(tǒng)計數(shù)據(jù),為每個缺陷模式分配預(yù)定義的缺陷可能性,并根據(jù)缺陷可能性來為缺陷報告初始化排序。然后,通過測試人員的反饋來自適應(yīng)地處理初始排名,這個過程是自動執(zhí)行的,基于相同的缺陷模式的錯誤報告的相關(guān)性。通過在三個廣泛使用的Java項目(AspectJ、Tomcat、Axis)上進(jìn)行實驗,結(jié)果表明,該策略在精度、召回率和f1得分方面明顯優(yōu)于FindBugs對警報的原始排序。
Boogerd和Moonen[29]提出使用代碼執(zhí)行可能性來確定警報的優(yōu)先級。對于每個警報涉及的代碼位置,計算其執(zhí)行可能性。如果該位置很可能被執(zhí)行,那么警報就會獲得高優(yōu)先級。如果該位置不太可能被執(zhí)行,則警報的優(yōu)先級較低。這項技術(shù)可以使測試人員將注意力放在具有高執(zhí)行可能性位置的警報上。然而,具有低執(zhí)行可能性位置的警報也可能很重要,并且正是由于該位置執(zhí)行概率較低,其中的嚴(yán)重錯誤更難以被檢測到。
Kim和Ernst[30-31]提出基于歷史的警報排序方法。他們通過分析軟件更改歷史,為每個警告類別計算生命周期,即警報出現(xiàn)與消失之間的時間。如果某類警報的生命周期較短,也就是說該類警報會很快被開發(fā)人員修復(fù),則說明該類別中的警報很重要,在報告中應(yīng)放在前列。如果一個警報長時間沒有被移除,或許說明它不值得修復(fù),那么該類別的警報可以被忽略。在三個開源項目(Columba、Lucene、Scarab)上的實驗表明,基于歷史的警報排序算法可以將頂部警報的正報精確度分別提高17%、25%和67%,并且該排序算法是通用的,可以用于任何警報。但是如果能將分析工具對警報設(shè)置的優(yōu)先級與該算法為警報設(shè)置的優(yōu)先級結(jié)合起來,應(yīng)該可獲得更高精度。Williams和Hollingsworth[32]也提出了一個類似的排序方案,該方案基于缺陷的修復(fù)記錄和在源代碼存儲庫中挖掘的信息。
Ribeiro等人[33]為了實現(xiàn)排序技術(shù)盡可能通用,將排序所需數(shù)據(jù)限制在了報告本身,而不使用其他任何信息。為了獲得良好且充足的數(shù)據(jù),首先,將不同工具生成的警報轉(zhuǎn)換為統(tǒng)一格式,并且為每個警報貼上標(biāo)簽,以區(qū)分它們是正報還是誤報。然后,將每個警報關(guān)聯(lián)到特定的特征,這些特征組成一個數(shù)據(jù)集用來訓(xùn)練預(yù)測模型。特征中的觸發(fā)警報的工具名稱、警告的嚴(yán)重等級等可以通過一次檢查一個警報來獲取,但其他特征需要處理整個匯總的報告才能獲得,其中包括:
(1)報告中指出同一位置有缺陷的次數(shù);
(2)給定警報位置周圍出發(fā)的警報數(shù)量;
(3)警報所指的軟件漏洞類別;
(4)其他分析工具在同一位置生成警報;
(5)為當(dāng)前警報所指向的同一文件生成的警報數(shù)。
使用AdaBoost算法訓(xùn)練幾個弱分類器,經(jīng)過組合得到一個強(qiáng)分類器。在對測試數(shù)據(jù)集進(jìn)行分類時,達(dá)到了0.805的準(zhǔn)確率和0.958的召回率。
上文中三類處理方法的總結(jié)與對比如表1所示。
表1 程序靜態(tài)分析報告處理方法對比
隨著報告處理技術(shù)的不斷探索,靜態(tài)分析在軟件測試中發(fā)揮著越來越重要的作用。雖然目前靜態(tài)分析仍面臨諸多挑戰(zhàn),但相信經(jīng)過研究人員更多的嘗試與努力,靜態(tài)分析會有更廣闊的應(yīng)用前景。下面對靜態(tài)分析告處理領(lǐng)域未來的發(fā)展和研究方向提出一些展望:
(1)方法組合。雖然目前有許多報告處理方法,但不同類型的方法并非獨立,如何將它們完美的組合在一起,使靜態(tài)分析工具的優(yōu)勢發(fā)揮的更充分,是未來需要考慮的問題。
(2)思路拓展。當(dāng)前的處理方法大都利用警報本身或代碼中所包含的信息,沒有考慮到靜態(tài)分析工具的分析規(guī)則是否可以為警報處理做出貢獻(xiàn)。由于靜態(tài)分析工具基于規(guī)則庫實現(xiàn)缺陷的識別,并且分析報告中的警報描述與規(guī)則也有所關(guān)聯(lián),或許未來可以利用分析規(guī)則探索一條警報處理的新道路。
(3)技術(shù)更新。當(dāng)前一些熱門技術(shù),例如機(jī)器學(xué)習(xí),不僅被廣泛應(yīng)用于程序靜態(tài)分析領(lǐng)域,在分析報告優(yōu)化方面機(jī)器學(xué)習(xí)技術(shù)也取得了較好的效果,但仍存在警報大量重復(fù)、警報正確性難以確定和警報排序不合理等問題。或許未來可以考慮從其他技術(shù)出發(fā),研究一種全新的報告處理方法。
首先,對靜態(tài)分析技術(shù)進(jìn)行了簡要介紹,指出了當(dāng)前靜態(tài)分析工具輸出報告存在的主要問題。接著,總結(jié)了近年來國內(nèi)外研究人員提出的對靜態(tài)分析工具所產(chǎn)生的警報的各種處理方法,根據(jù)基本思想將其主要分為三類:基于融合、基于分類、基于排序,并分析了這三類方法的優(yōu)點和缺點。最后,對靜態(tài)分析報告處理技術(shù)未來的發(fā)展方向進(jìn)行了展望并對全文進(jìn)行了總結(jié),希望能為讀者在研究主題或開發(fā)方法時提供指引。