天天看點

靜态分析可以代替代碼審查嗎?

在上一篇文章中,我解釋了如何正确進行代碼審查 。 我建議利用諸如Findbugs,PMD,Klocwork或Fortify之類的靜态分析工具在将代碼傳遞給審閱者之前檢查常見錯誤和錯誤代碼,以使審閱者的工作更加輕松并提高審閱效率。

一些讀者問是否可以使用靜态分析工具代替手動代碼審查。 手動代碼審查會增加開發的延遲和成本,而靜态分析工具會不斷變得更好,更快和更準确。 那麼,您是否可以像許多團隊自動化功能測試一樣,使代碼審查自動化? 您是否也需要進行人工稽核,還是可以依靠技術為您完成工作?

讓我們從了解靜态分析錯誤檢查工具的優缺點開始。

靜态分析工具可以做什麼–不能做什麼

在本文中 ,GrammaTech的Paul Anderson很好地解釋了靜态分析錯誤查找的工作原理,召回(找到所有實際問題),精度(最小化誤報)和速度之間的權衡,以及使用靜态分析工具查找錯誤。

靜态分析工具非常擅長捕捉某些類型的錯誤,包括記憶體損壞和緩沖區溢出(針對C / C ++),記憶體洩漏,非法和不安全的操作,空指針,無限循環,不完整的代碼,備援的代碼和無效的代碼。

靜态分析工具會知道您是否在錯誤地調用庫(隻要它能夠識别該函數),是否錯誤地使用了語言(編譯器可以找到但找不到的東西)或不一緻(表明程式員可能擁有該語言)誤會了)。

靜态分析工具可以識别具有可維護性問題的代碼,這些代碼不遵循良好實踐或标準,結構複雜或結構不良,并且是重構的理想選擇。

但是這些工具無法告訴您什麼時候您錯了需求,或者什麼時候忘記了某些重要内容或錯過了一些重要的事情–因為該工具不知道代碼應該做什麼。 一個工具可以發現常見的一對一錯誤和一些無窮循環,但它不會捕獲應用程式邏輯錯誤,例如按降序而不是升序排序,或者在您打算乘以除法時除法,在有條件時引用買方是賣方,還是承租人而不是出租人。 這些錯誤也不會在單元測試中發現,因為編寫代碼的人是編寫測試的人,并且也會犯同樣的錯誤。

工具找不到缺少的功能或未實作的功能,或者找不到應有的功能。 他們找不到工作流程中的錯誤或漏洞。 或監督稽核或日志記錄。 或調試意外遺留的代碼。

靜态分析工具可能能夠找到一些後門或陷阱門-至少是簡單的後門或陷阱門。 而且他們可能會發現一些并發問題 -死鎖,競争和錯誤或鎖定不一緻。 但是他們也會想念很多。

諸如Findbugs之類的靜态分析工具可以為您執行安全性檢查:不安全的調用和操作,使用弱加密算法和弱随機數,使用寫死密碼以及至少某些情況下XSS,CSRF和簡單SQL注入。 進行過程間和資料流分析(檢視源,彙和之間的路徑)的更進階的商業工具可以發現其他錯誤,包括難以手動跟蹤且耗時的注入問題。

但是工具無法告訴您您忘記了加密重要的資料,或者您不應該首先存儲一些資料。 它無法找到關鍵安全功能中的邏輯錯誤,是否可能洩露敏感資訊,是否在通路控制中檢查錯誤,或者代碼是否無法打開而不是關閉而失敗。

僅僅使用一個靜态分析工具來檢查代碼可能還不夠。 對靜态分析工具的評估(例如NIST的SAMATE項目(一系列比較研究,其中許多工具針對同一代碼運作))顯示,不同工具發現的問題之間幾乎沒有重疊(除了一些常見的領域,例如緩沖區錯誤) ),即使這些工具本應進行相同類型的檢查。 這意味着要充分利用靜态分析,您将需要針對同一代碼運作兩個或多個工具(例如SonarQube ,它将自己的靜态分析結果與其他工具(包括流行的免費工具)內建在一起,為您做)。 如果您要購買商業工具,那可能很快就會變得非常昂貴。

工具與手動稽核

工具可以發現編碼錯誤或打字錯誤的情況,但思路不正确。 這些都是您必須通過手動檢查發現的問題。

2005年的一項研究, 将Bug查找工具與評論和測試進行了比較,在5個不同的代碼庫上使用了開源Bug查找工具(包括Findbug和PMD),将發現的工具與通過代碼審查和功能測試發現的工具進行了比較。 靜态分析工具隻發現了手動稽核中發現的錯誤的一小部分,盡管這些工具更加一緻–手動稽核人員錯過了一些工具被竊取的案例。

就像人工稽核一樣 ,這些工具發現的可維護性問題比實際缺陷要多(部分原因是所評估的工具之一-PMD-專注于代碼結構和最佳實踐)。 測試(黑盒-包括等效性和邊界測試-以及白盒功能測試和單元測試)發現的錯誤少于評論。 但是不同的錯誤。 測試中發現的錯誤與靜态分析工具發現的錯誤之間完全沒有重疊。

發現可能發生或确實發生的問題

靜态分析工具善于發現“可能發生”的問題,但不一定發現“确實發生”的問題。

科羅拉多州立大學的研究人員針對不同版本的不同開源項目運作了靜态分析工具,并将這些工具所發現的内容與開發人員在過去幾年中所做的更改和修複進行了比較,以檢視這些工具是否可以正确預測修複需要進行的修改以及需要重構的代碼。

這些工具在代碼中報告了數百個問題,但很少發現開發人員最終解決的嚴重問題。 一個簡單的工具(Jlint)找不到開發人員實際修複或清除的任何内容。 在一個項目中修複的112個嚴重錯誤中,靜态分析工具也僅發現3個。 在另一個項目中,這些工具實際發現并修複了136個錯誤中的4個。 開發人員确實修複的許多錯誤都是諸如空指針和不正确的字元串操作之類的問題,這些問題是靜态分析工具應該擅長抓住的,但事實并非如此。

這些工具在預測應重構哪些代碼方面做得更好:開發人員最終重構并清理了該工具報告的70%以上的代碼結構和代碼清晰度問題(PMD,一種免費的代碼檢查工具,特别好為了這)。

愛立信針對大型,經過良好測試的成熟應用評估了各種商業靜态分析工具 。 在一個C應用程式上,一種商用工具發現了40個缺陷-沒有可能導緻崩潰的問題,但是仍然需要解決一些問題。 在另一個大型C代碼基礎上,該工具的發現結果中有1%被證明是足以修複的錯誤。 在第三個項目中,他們針對已知記憶體洩漏的舊版本C系統運作了2個商業工具。 一個工具發現了32個錯誤,另外16個:兩個工具僅發現了3個錯誤。 令人驚訝的是,這兩個工具都沒有發現已知的記憶體洩漏-發現的所有錯誤都是新錯誤。 在具有已知錯誤的Java系統上,他們嘗試了3種不同的工具。 這些工具均未發現任何已知的錯誤,但其中一個工具發現了團隊同意修複的19個新錯誤。

愛立信的經驗是,靜态分析工具會發現很難以其他方式發現的錯誤。 但是, 很少有人使用靜态分析來發現難以置信的錯誤 ,尤其是在生産代碼中。

這在Google和Sun JDK 1.6.0上進行的另一項有關使用靜态分析(Findbugs)的研究中得到了支援。 工程師使用該工具發現了許多真實的錯誤,但不值得付出修複的代價:故意的錯誤,掩蓋的錯誤,不可行的情況,已經注定的代碼,測試代碼或記錄代碼的錯誤,舊代碼的錯誤是“即将離開”或其他相對不重要的案例。 該工具發現的中高優先級正确性錯誤中,隻有大約10%是真正需要修複的錯誤。

安全案例

到目前為止,我們主要關注靜态分析檢查,以檢查運作時正确性和正常代碼品質, 而不是安全性 。

盡管安全性是建立在代碼品質上的,漏洞隻是黑客尋找和利用的錯誤,但檢查代碼的正确性和清晰度對于安全的應用程式而言還不夠。 在過去5到10年中,對靜态分析技術的大量投資一直用于查找代碼中的安全性問題,例如OWASP的前10名或SANS / CWE的25個最危險的軟體錯誤中列出的常見問題。

在發現安全漏洞方面,與手動稽核相比,有幾項研究着眼于靜态分析工具的有效性。 第一項研究是針對一個大型應用程式,該應用程式通過安全專家進行的結構化手動評估發現了15個已知的安全漏洞。 在代碼中運作了兩種不同的商業靜态分析工具。 這些工具共發現了不到一半的已知安全漏洞-僅是最簡單的安全漏洞,這些漏洞不需要對代碼或設計有深入的了解。

當然,這些工具還報告了成千上萬個其他問題,這些問題需要進行檢查和限定,或者作為誤報而丢棄。 這些其他問題包括一些運作時正确性問題,空指針和資源洩漏以及代碼品質發現(死代碼,未使用的變量),但是除手動安全性審查已發現的那些漏洞之外,沒有其他實際的安全漏洞。

但這假設您周圍有安全專家來審查代碼。 要查找安全漏洞,審閱者需要了解代碼(語言和架構),并且他們還需要了解要查找什麼樣的安全問題。

另一項研究表明這是多麼困難。 雇用了30名開發人員對小型Web應用程式(一些安全專家,其他Web開發人員)進行獨立的安全代碼審查。 他們被禁止使用靜态分析工具。 該應用程式有6個已知漏洞。 20%的審閱者沒有發現任何已知的錯誤。 沒有一個審閱者找到所有已知的bug,盡管有幾個發現了研究人員未知的新XSS漏洞。 平均而言,有10位審閱者發現所有安全漏洞的機會隻有80%。

而且,不是

靜态分析工具對于使用諸如C / C ++這樣的不安全語言(有多種工具來查找常見錯誤)或使用動态類型化腳本語言(如Javascript或PHP) (不幸的是,這些工具不夠出色)的開發人員尤其有用,以及開始學習新語言和架構的團隊。 在(例如)醫療裝置和航空電子裝置等高度管制,安全關鍵的環境中,(或應該)使用靜态分析。 并且,直到更多的開發人員接受更多教育訓練并更多地了解如何編寫安全軟體之後,我們所有人都需要依靠靜态分析(和動态分析)安全測試工具來捕獲漏洞。

但是靜态分析不能替代代碼審查。 是的,即使您很聰明地執行代碼檢查,代碼檢查也會花費額外的時間并增加開發成本–并且,聰明的代碼檢查包括在執行檢查之前運作靜态分析檢查。 如果您想快速行動并編寫優質,高品質和安全的代碼,則仍然需要進行審查。您不能僅依靠靜态分析。

翻譯自: https://www.javacodegeeks.com/2014/09/can-static-analysis-replace-code-reviews.html