在SDLC中使用靜態代碼分析的最佳實踐

http://vultrace.cn更多精彩,盡在個人博客。
文章翻譯自ncc group的論文,論文超長預警,請耐心觀看。
Best Practices for the use of Static Code Analysis within a Real-World Secure Development Lifecycle Authored by Jeremy Boone NCC Group


摘要

靜態代碼分析(SAST:Static application security testing)是在不實際運行代碼的情況下進行軟件分析。該術語通常適用於由自動化工具執行的分析,而人工分析通常被稱爲針對安全性(security-focused)代碼審查。SAST的主要目標是瞭解軟件的行爲,通常旨在發現安全、隱私及代碼質量上的問題。近年來,商業化SAST解決方案已經相當成熟,並且它們現在提供了支持各種開發流程與系統的集成方法:持續集成、漏洞追蹤、版本控制、代碼review等。然而,NCC Group發現經常存在無效或不理想的靜態分析部署,這些部署要麼無法滿足安全開發生命週期(SDLC)的要求,要麼給開發人員帶來了巨大的負擔,從而導致靜態代碼分析工具無法達到理想的效果。這些缺點會導致SAST解決方案無法達到其主要目的:提高軟件安全性。在本文中,我們將評估和選擇最適合你組織的靜態代碼分析解決方案,以及將成熟的安全開發生命週期中的解決方案與開發過程有效集成的最佳實踐指南。但是,我們必須有意的避免推薦特定的SAST解決方案,因爲根據我們的經驗,沒有“一刀切”的解決方案。

目的與動機

促使軟件開發組織使用靜態代碼分析的主要動力是能夠以較低的價格提供更高質量和更安全的產品。研究表明,自動靜態代碼分析最多可以檢測到60%的安全問題。當考慮到單個故障可能導致廣泛且昂貴的產品召回時,此指標就變得非常重要。例如:
美國國家標準技術研究院(NIST)在2002年表示,美國經濟每年因軟件缺陷造成的損失約爲595億美元;
2015年,Charlie Miller 和 Chris Valasek 發現了安全缺陷,導致召回了140萬輛菲亞特.克萊斯勒汽車;
2011年,FDA指出 24% 的醫療設備召回可歸因於軟件缺陷。
因此,不難想象,對SAST進行少量的投資就能避免昂貴的召回和對產品打補丁。除了恐懼,還應該認識到靜態代碼分析並不是靈丹妙藥,正如Forrester在2015年第二季度的應用程序安全報告中的總結:
SAST爲客戶提供了巨大的價值 – 它擁有可靠的可追蹤的記錄,並提供了廣泛的收益。爲了從SAST中獲得最大效果,團隊必須相對成熟,並且能夠系統地進行補救。隨着應用程序環境變得更加複雜並且其攻擊面和風險狀況發生變化,SAST將在未來5~10年繼續取得重大成功。
換句話說,儘管商業靜態代碼分析解決方案已經開始成熟,但要獲得SAST技術的全面成功,還是需要勤奮和精心的準備。需要一種早期且經常使用的方法,從一開始就強調工具的正確和安全的應用,在組織內部部署SAST時必須格外小心。

爲什麼SAST經常失敗

SAST的成功與否取決於採用率和參與度。換句話說,如果開發人員不信任靜態分析解決方案(例如誤報率很高),則他們將不會使用它們。建立信任的最佳方法是證明解決方案可以提供價值。證明價值的最佳方法是證明工具的準確性、快速並且不會給開發人員帶來負擔。
首先,您應該尋找並消除開發人員與工具之間的摩擦,不斷致力於改善SAST服務。如果可能的話,應該將SAST服務無縫集成到目前支持的開發系統中,例如漏洞跟蹤系統、代碼review工具、代碼存儲庫及構建環境。這有助於減少每次用戶需要與SAST服務之間交互時的開銷。 其次,應該努力減少開發人員分類的負擔。這可以通過減少誤報及不相關的警告來實現。這不是一蹴而就的,需要不停的優化和改進。最後,當未將SAST作爲強制使用工具或未將SAST度量標準納入到產品發佈標準時,SAST的有效性就會開始減弱。爲了獲得成功,您需要達成自上而下的協議,並進行必要的過程更改,從而使靜態分析成爲所有軟件產品發佈標準的必要組成部分,並作爲KPI和預期的最低質量標準。否則,開發團隊很容易忽略SAST報告的缺陷,並將它們添加到無限長的“for future fix”缺陷積壓中。

方法論

NCC Group認爲,成功進行靜態代碼分析部署有五個核心原則。我們相信,如果在評估SAST購買解決方案並將其部署到整個組織中時遵循這些原則,您將獲得最大的成功,這些目標與安全開發生命週期的目標一致。
{% raw %}

原則 目標
自動化 自動化可以確保SAST可以掃描組織內編寫的所有軟件;SAST工具應該無處不在,並與現有的開發支持系統透明集成,例如漏洞跟蹤器,版本控制器,持續集成和代碼審查系統;由SAST發現的缺陷應立即自動推送給相關開發人員;自動化的SAST將通過降低昂貴的人工成本並提高速度,例如代碼審查、軟件測試、安全漏洞評估以及隱私審覈。
分析精度 SAST工具將通過準確識別質量、安全性和隱私缺陷來提供價值;嘗試對積壓的漏洞進行分類時,誤報率的降低減少噪聲以及消除“大海撈針”式問題;開發自定義規則,以豐富出現的安全缺陷類別,並及時響應影響您軟件產品的安全事件(應急響應)。
指標驅動的決策 應該統計SAST缺陷趨勢,並進行質量把控,確保沒有未解決的嚴重缺陷;對SAST的合理性應當基於具體且可測量的數據,例如漏洞數量,嚴重性和平均修復時間。
持續優化 定期統計SAST工具的準確性,並採取措施提高結果的準確性;爲了減少歷史遺留漏洞,以減輕分流帶來的負擔。應當採用分類的方式處理(例如:首先是嚴重漏洞);爲保證用戶的方便性,應提供高水平的修復方案。
用戶教育 應對用戶進行有關SAST使用以及如何修復常見漏洞的培訓。
{% endraw %}

與安全開發生命週期結合

根據上述最佳實踐方法,明顯的看出,成功的SAST部署必須在整個軟件開發過程中集成。此外,必須在安全開發生命週期的每個階段中進行SAST活動。作爲經典SDLC的一部分,靜態分析工具是開發人員實現階段最常用的工具,但也可以在其他SDLC階段有效使用,例如,在驗證階段由質量團隊使用,或在部署期間由事件響應團隊使用。遵循Microsofa用於安全開發生命週期的7種模型和結構,我們將說明何處以及如何將SAST用作SDLC每個階段的基本要素。
{% raw %}

過程 具體實施
培訓 爲開發、測試人員創建SAST培訓計劃。
需求 建立與SAST相關的質量標準和漏洞記錄。
設計 審查攻擊面,並開發自定義SAST模型。
實現 將SAST與開發流程工具打通。
驗證 對SAST漏洞進行分類,以方便區分遺留的或嚴重的漏洞。
發佈 在發佈準備階段,檢查SAST質量指標。
響應 使用SAST進行漏洞快速響應。
{% endraw %}

安全培訓

通常,培訓是將SAST集成到軟件開發過程中的重要組成部分,工程師應該熟悉SAST解決方案的功能及其侷限性。在相關漏洞修復前,開發人員緊急修復他們的代碼是不夠的。開發人員必須瞭解檢測到漏洞類別的根本原因,並且能夠開發適當的補丁程序。不完整的修復一次又一次的出現,例如最近 Android Stagefright 漏洞的修復,被證明是非常不完善的。在組織中部署SAST時,對開發人員和測試人員進行培訓非常重要。培訓的主題應涵蓋:

  • 什麼是靜態分析?
  • 常見的缺陷類別有哪些?最佳的修復方案是什麼?
  • 解決誤報的最佳實踐是什麼?
  • SAST如何與開發系統集成?
  • 爲適應SAST進行了哪些流程更改?

大多數SAST提供商都提供現場、網絡或遠程的培訓,此外,大多數靜態分析工具都附帶有大量的在線文檔、教程,你還可以要求定製培訓內容,或尋求第三方的獨立指導。

需求

在傳統SDLC的需求階段,通常需要建立質量把控和漏洞準則,這些公認的內部標準有助於定義在交付軟件產品之前必須滿足的嚴格的安全性、隱私以及質量標準。這些標準中應包括來自SAST的測試結果,例如,你可能希望在解決由SAST確定的所有關鍵漏洞解決之前,將不發佈任何產品。對於遵循敏捷開發的團隊,SAST指標應該成爲獲取用戶的標準的一部分。

設計

在SDLC的設計階段中,最佳實踐表明應該建立設計要求,分析軟件的攻擊面並進行威脅建模,這些建模輸出可以幫助確定產品中可能需要SAST給予更多關注的風險區域。例如,你可能發現使用了新技術、軟件堆棧或第三方庫,必須在靜態分析引擎中對這些組件進行研究並充分建模,以確保產生最準確的結果。

實現

實施階段是衆所周知的難點,在此,應該在整個開發過程中集成SAST:集成開發環境、持續集成系統、代碼審查系統、漏洞追蹤器及版本控制系統。
通過這種廣泛的集成,你的組織可以在產品開發週期的早期發現並解決安全、隱私和質量問題,此時這些缺陷是最容易修復的。實際上,你應該在開發人員引入軟件缺陷時,甚至提交代碼前確定漏洞。通過縮小在引入錯誤及解決錯誤之間的時間間隔,你可以減少質量保障、代碼審查、漏洞評估及隱私審查相關的下游成本。最終目標應該是通過透明地與這些系統集成而使SAST無處不在,而不會在開發人員和工具之間造成摩擦,SAST應該分析每次提交,而且應該引入“沒有新警告”的策略。

驗證

不僅僅是開發團隊使用靜態分析工具,質量保障團隊也需要承擔責任,驗證階段是QA的閃亮時刻。在驗證期間,QA團隊應對SAST漏洞進行分類,識別在實現階段可能被忽略或推遲的關鍵問題,在發佈軟件之前,不允許任何嚴重的缺陷被繞過。QA團隊還應該分析SAST服務提出的總體缺陷趨勢,這包括追蹤代碼中高於平均缺陷密度的典型缺陷,或隔離觸發異常高的誤報率的規則集。然後,QA應能夠自定義分析引擎來抑制誤報,或者編寫自定義規則以檢測新的缺陷類別。

發佈

在典型的SDLC發佈階段,將進行最終的安全檢查,以檢查所執行的所有安全任務並確定軟件是否已準備就緒。與其他任何質量指標一樣,SAST應該成爲此發佈準備決策過程的一部分。您將要確保你的軟件產品符合你在需求階段之前建立的質量把控與漏洞準則。

響應與維持

作爲SDLC階段的一部分,必須準備通過執行產品事件響應計劃來應對安全緊急情況,健康的事件響應過程將利用SAST工具和自動化。首先,應該考慮審覈SAST報告,以瞭解外部報告的缺陷是否以前是工程團隊已知的,如果是這樣,那就太好了。但是現在又遇到了另一個問題:爲什麼他們不在發佈前修復該問題?當在外部發現繞過的缺陷時,可能會很尷尬。從過程改進的角度來看,這些見解可能非常有價值。另一方面,如果SAST工具未發現漏洞,則必須採取糾正措施。事件響應調查過程的一部分應包括尋找缺陷的變體,在這裏,靜態分析是一項巨大而寶貴的資產。可以開發自定義規則集來對漏洞的模式和根本原因進行建模,並且應該使用該規則集掃描整個代碼庫。這種“發現一次、永久修復”的態度是整個安全開發生命週期中維護的重要思想。

評估與部署SAST解決方案

當SAST與各種開發支持系統透明的結合到一起時,其部署是最有效的。通過減少開發人員與工具之間的摩擦,這有助於提高使用率。高度的用戶參與度是任何SAST部署成功與否的關鍵因素,並將促使SAST發現更多的安全、隱私及質量缺陷。NASA的《軟件工程手冊》中有關靜態代碼分析的部分有效的說明了部署SAST的問題:
在現有的開發過程中引入靜態分析工具是個非常棘手的問題,即使軟件團隊相信此工具帶來的好處,項目也會謹慎行事,並儘量避免引入靜態分析。
本節將描述評估和選擇最適合你的軟件開發過程和所用支持系統的現成商用或開源的靜態代碼分析解決方案的標準。你將要考慮SAST工具是否支持多個編譯器以及對多種編程語言的分析,該解決方案如何與你的開發支持系統集成,以及SAST分析引擎整體的準確性和可配置性。在進行任何購買之前,第一步必須是評估多個SAST解決方案,商業SAST供應商將很樂意爲此目的而提供臨時的許可證。你應該根據自己的評估而不是供應商演示來決定購買商業靜態分析工具,獲得試用許可證後,你可以根據以下概述的條件開始評估每個工具。

語言的支持

爲你的組織選擇SAST解決方案時,最重要的問題可能是它是否支持開發團隊使用的所有編程語言和平臺。例如,如果你的組織開發了一個Android應用程序,那麼具有Android API的靜態分析器要優於僅支持 C/C++ 和 Java 的靜態分析器。你還需要詢問該工具支持編程語言的時間,這可以指示成熟度,以及供應商是否對語言語法的特性以及標準庫和API的使用進行了全面建模。

選擇語言和人工代碼庫

針對代碼庫的SAST解決方案的初始設置可能會非常麻煩,這些工具可能會很挑剔,需要對各種環境和編譯器選項進行仔細的預設置。在完成整個分析工作之前,可能需要嘗試幾次運行該工具,確保不會遇到無法恢復的解析錯誤。此外,靜態分析工具通常會在構建過程中引入2~10倍的運行時開銷。可以理解的是,當SAST工具在一夜之間編譯並分析代碼後,在凌晨3:00發生故障時,將非常令人沮喪。因此,在SAST評估過程中,應選擇少數候選代碼庫,這些候選代碼庫必須足夠小並通常在30分鐘或更短時間內完成編譯。這樣,你可以調整工具設置,並逐步實現理想的配置,而無需在運行時等待數小時或數天。候選代碼庫應該能夠代表總體代碼庫,這將使你對SAST解決方案的功能有最佳的瞭解,因爲不同的軟件產品將具有獨特且有趣的缺陷配置文件。除了分析原生代碼(nature code)之外,你還應該考慮分析分析測試代碼。Juliet測試套件是一個很好的選擇,該套件由軟件保障度量和工具評估(SAMATE)項目創建,部分由NIST贊助。豐田汽車信息技術中心(ITC)的研究人員針對基準SAST工具發佈了類似的一組代碼庫。這兩個測試套件一起,包含數百個精心設計以展示各種缺陷的微型C/C++和Java程序。通過掃描原生代碼和測試代碼,你將準確瞭解SAST解決方案的整體檢測功能。

開發系統支持

通常,SAST解決方案的成熟度依賴於它與軟件開發過程的集成程度,最完善的解決方案是提供各種集成選項,以及如何靈活的在內部部署該工具。一些解決方案與桌面IDE(集成開發環境)集成,並在編譯錯誤的時候輸出警告,而其他解決方案則部署到構建環境、集成系統或託管服務。爲組織選擇SAST解決方案時,最重要的是該工具是否支持用於創建和交付各種軟件產品的開發環境,這包括編譯器、構建系統、IDE、持續集成系統、代碼審計系統、版本控制和漏洞追蹤器。對這些系統和工具的廣泛支持將使你在整個開發過程中透明地集成SAST,以支持成熟的安全開發生命週期。在計劃SAST部署時,還必須切實瞭解DecOps團隊的能力,許多SAST和DecOps工具具有豐富的API,但是你的團隊是否有技能和時間通過自定義腳本將他們組合在一起,在整個SAST部署過程中,你必須仔細決定是自己構建集成還是尋求獨立的建議和支持。

編譯與構建系統

一些靜態分析工具能夠方便地監視構建過程,並監視編譯器和鏈接器的調用。在許多情況下,可以通過在構建命令前加上SAST前綴來設置,例如“SastWrapper make target”,這樣可以輕鬆消除啓動服務所需的許多初始配置,因此你可以更快地查看分析結果。當然,只有在SAST工具能夠識別你的構建環境和編譯器的情況下才有可能,通常,這種類型的設置對於重命名的構建系統或編譯可執行文件是脆弱的。確保你的編譯器和構建系統得到顯示的支持是至關重要的,並且當不支持它們時,必須確定是否可以將SAST工具配置爲識別其他編譯器。通過監視構建過程,SAST工具可以準確查看哪些源文件被編譯到目標中,許多大型項目通常都有很多未使用的源文件,因此從分析結果中排除這些文件非常方便。沒有工程師願意花時間對死代碼中錯誤進行分類。除了查看編譯的源文件外,SAST工具還可以查看這些文件的編譯方式(即,編譯器和鏈接器標誌),這非常重要,因爲如果SAST工具可以對目標體系結果進行更準確的假設(例如x86與ARM,32位與64位),以產生更好的結果。但是,還應該指出,並非所有SAST解決方案都能夠囊括你的構建過程,有些工具需要你自己的構建腳本,這可能會成爲維護的噩夢。其他SAST工具在編譯器和構建環境方面是完全不知的,他們僅分析位於提供的目錄中的所有源文件。這種靜態分析工具更可能造成誤報,因爲他們對於預處理指令及編譯時傳遞的路徑不可見。最後,有時SAST工具對支持混合語言版本很有用,如果在你的構建環境中,一次調用“make”將同時編譯C和Java代碼,則此功能非常有用。許多工具不支持此功能,因此你不得不將Java源文件與C/C++文件分開。修改舊版構建腳本來完成此任務可能非常困難,而且這樣做可能會帶來維護的問題。

集成開發環境

成熟的SAST解決方案通常會隨附用於各種IDE(如Eclipse、Visual Studio、IntelliJ等)的預製插件,這些插件將分析軟件工程師本地的更改,並在編譯錯誤時發出警告。這非常方便,因爲它鼓勵軟件工程師將SAST用作日常工作的一部分。這時對開發人員修復代碼總是方便的,因爲代碼開發者心中還是記憶猶新的。商業供應商有時將此功能稱爲“增量”分析或“快速”分析,它依賴於一種有趣的技術,即中央SAST服務器託管此分析的副產品,或稱之爲基準。當你在本地分析時,IDE插件將確定由於本地更改而需要重新計算哪些中間產品。然後重新分析這些源文件,並按原樣使用其餘基線,通常,將本地更改限制在幾個源文件中時,將會大大加快分析速度。軟件開發人員往往對他們選擇的IDE有強烈的選擇,你永遠無法說服開發人員切換到其他IDE,因爲它不支持你正在部署的SAST工具。你選擇的SAST工具應支持開發組織最常用的IDE,如果沒有,則工具應提供一個API,使你能夠創建自己的IDE插件。

持續集成

Scrm/Agile的核心宗旨是使你的開發團隊能夠快速響應變化,持續集成(CI)系統通常是最有效的敏捷開發模型的一部分,因爲當提交中斷構建或導致測試失敗時,他們會爲開發人員提供即時反饋。因此如果你的組織使用CI系統,那麼想象將SAST與開發流程集成的方法就很重要。當前的最佳實踐是將CI系統用作觸發程序,以啓動靜態分析工具的運行。這樣,當開發人員提交違反SAST規則的更改,從而引入新的缺陷時,可以在提交後立即通知他們。成熟的SAST解決方案將提供功能強大的API或命令行界面,從而可以創建這些類型的自動化腳本。您應確保給開發團隊適當的時間來開發這些腳本,並習慣於將SAST用作常規開發過程的一部分。一旦SAST工具運行平穩,前期的投入將獲得回報。

代碼審計系統

SAST還應該與整個組織中的代碼審查系統集成,這些系統常見示例包括Gerrit、Code Collaborator和Review Board。你想利用工程師對技術的自豪感,使他們可以輕鬆地根據同行的意見來發現並修復代碼中發現的任何缺陷。將SAST與代碼檢查系統集成的典型方法是創建一個SAST的新賬戶,並將該賬戶設置爲發佈到服務器的每個代碼檢查的默認檢查者。創建新的代碼審閱時,CI觸發器應自動啓動分析作業,然後,應該建立連接,以允許將SAST代碼檢查賬戶從後端SAST服務器中讀取相關漏洞,並展示在代碼檢查系統中。此設置的一個補充是允許SAST賬戶進行 +1 或 -1 的代碼review,具體取決於提出的更改是否能夠被完全的修復。當代碼review是開發過程的必須部分時,這種類型的系統最有效。主要優點是爲開發人員提供了近乎即時的自動反饋,從而減輕了SAST對流程的壓力。開發人員無需諮詢外部SAST系統即可瞭解其代碼缺陷並進行更改,結果將在代碼review工具中呈現到他們面前。但是靜態分析有時會非常緩慢,SAST絕對不應該成爲代碼審查批准流程的卡點,因爲開發人員遇到的任何干擾都會削弱該工具的信譽。因此,最好在此階段僅運行快速而準確的規則集,以確保SAST工具在規定的時間範圍內完成分析。很少有SAST解決方案對代碼檢查系統具有現成的支持,你可能必須提供SAST API或命令行界面自己構建此集成。

日常構建

除了將SAST與你的持續集成和代碼審查系統集成外,你還可能希望將SAST與構建系統集成,這是必要的,因爲由於獨立提交趨向於交互,因此CI系統中運行的SAST不會捕獲一些少量的漏洞。可能兩個獨立的提交都沒有缺陷,只有將這些提交組合在一起才能發現漏洞,當然,獨立分析變更的CI系統會遺漏此類漏洞,這些漏洞通常被成爲“逃逸”漏洞。與代碼審查階段執行的分析(速度是最重要的)不同,構建階段具有大量的時間,如果針對速度優化了代碼檢查階段,則應將構建階段配置爲執行之前禁用的較慢的規則集。請注意,非常大的代碼庫可能無法在一夜之間完成分析,在這種情況下,你可能考慮到週末進行每週一次分析。當然,此解決方案有一個主要缺點:它生成的結果很少,這使開發人員將SAST與他們的日常工作集成起來更加困難。不管你執行每晚還是每週分析,都應考慮其他加速選項,例如分析作業的並行性。這可以通過將構建過程分成可以快速分析的小型獨立組件來實現,但是,如果無法修改內部版本,那麼你最後的選擇就是投入硬件解決該問題,並調查使用具有大內核和內存的分析服務器。

分佈式分析

你必須確保SAST永遠不會成爲開發過程中的瓶頸,如前所述,一種加速工具的方法是與集成開發或代碼review系統集成時禁用慢的規則集,實現此目的的另一種方法是研究動態彈性計算服務的使用。衆所周知,軟件開發的起伏是很難預測的,但是它對確保SAST服務滿足SLA所需的哪種計算基礎架構產生了巨大影響。(e.g. 必須在提交後30分鐘內分析所有更改,或者每晚分析必須在12小時內完成。)如果你構建基礎架構以匹配平均提交負載,那麼你的分析將在高峯時間無法滿足需求,如果你構建基礎架構以匹配負載,則分析服務器將在許多時間處於空閒狀態。在多個時區運行的大型軟件組織中,這種影響將進一步加劇 – CI服務器上永遠沒有任何空閒時間。一種解決方案依賴動態彈性計算基礎架構。這將需要一個與您的CI系統,每晚構建系統或代碼檢查系統對話的中央服務器。反過來,該中央服務器將把作業分發出去,使虛擬機進行實際分析。這要求每個VM都具有master分支的副本,以及開發人員的任何部分的提交。並非所有的商業SAST系統都容易支持這種類型的解決方案。您可能需要在這裏仔細進行調研。NCC Group建議您進行自己的實驗,對平均提交頻率和大小進行測量,以確定如何最佳地擴展系統。

漏洞追蹤

許多商業SAST工具附帶了對常見錯誤追蹤器(如JIRA、Bugzilla)的開箱即用的支持,這些插件可以將漏洞從SAST數據庫遷移到自己公司的漏洞追蹤器。通常爲了方便起見,這樣做是爲了使開發人員不必學習另一種錯誤分類系統,在許多情況下,這可以減少開發人員與SAST工具之間的摩擦。在決定是否以及如何將SAST與錯誤追蹤器集成時,務必格外小心,建議不要批量遷移所有漏洞缺陷,因爲針對新代碼庫的第一次靜態分析可能會產生數以萬計警告,其中許多警告可能是無關緊要的樣式問題或誤報。這將可能使開發團隊不堪重負,如果這樣做,很可能會破壞未來成功的可能性。僅當缺陷過於複雜而無法在簽入之前解決或在短代碼審查窗口範圍之內時,才應將缺陷遷移到錯誤跟蹤器。如果設置正確,則在構建中進行的靜態分析應捕獲這些逃逸的缺陷,並將它們自動記錄在錯誤跟蹤器中。

版本控制系統

與版本控制系統集成雖然不是很重要,但仍然是很有用的功能,許多SAST工具可以直接與你的源存儲庫進行交互,並提取可以補充缺陷報告的數據,例如,在根據受影響的源文件的提交歷史記錄自動將SAST缺陷分配給特定開發人員時,此功能最爲有用。但是,請注意,這種屬性的系統依賴於“最佳猜測”的啓發式方法,當問題是由代碼更改的組合而不是單個更改引起的時候,錯誤地將缺陷分配給錯誤的開發人員。如果缺陷分配的準確性非常重要,那麼最好避免這種方式與版本控制系統集成。

分析引擎

在後臺,SAST解決方案可以依賴於不同種類的代碼或二進制分析技術,範圍從類似grep的樸素模式匹配到語法感知的控制流分析,再到能夠通過構建抽象語法樹追蹤有價值數據的數據流分析。每種技術都有自身的優點和缺點,模式匹配可以作爲一種快速有效的方法來識別使用被禁止的API函數,數據流雖然往往是靜態分析的一種較慢的形式,但可以識別更復雜的過程間的缺陷,這種缺陷需要對變量的值(或值的範圍)有特定的瞭解。單個SAST解決方案中的分析引擎可以利用所有上述技術,因此,應該仔細研究引擎本身,以確保符合組織的需求。你應該檢查該工具是否能夠檢測廣泛的漏洞,是否準確,是否可以微調內置規則的敏感度,是否可以一直誤報以及是否可以自定義或者擴展引擎以檢測全新的漏洞類別。

缺陷類別

首先評估SAST解決方案時,必須仔細研究其內置規則集,需要確認該工具是否支持對常用語言中的各種安全、質量和隱私缺陷問題進行檢測。除了保證每種受支持語言的缺陷外,還必須確保分析引擎支持軟件產品所有依賴的框架,這在使用框架非常普遍的Web應用程序開發中尤其重要。框架經常會引入體系結構抽象,這些抽象概念可能會使普通的解析器感到困惑,或者鼓勵可能會產生意外安全後果的編程模式。SAST工具必須支持這些框架,因爲你希望獲得影響軟件產品的所有缺陷類別的最廣泛的覆蓋。還應該考慮比較和對比多個SAST解決方案之間的規則集,以便準確地指示典型漏洞的檢測支持。

準確度和精度

測試真實的準確性、誤報率及漏報率可能是具有挑戰性的,但是,在比較多個要購買的SAST解決方案時,瞭解這些數字至關重要。如前所述,必須注意不要讓誤報使軟件工程師不知所措,同樣,需要確保該工具不會忽略重要的安全漏洞。測量誤報率是可能的,進行這需要一些努力和時間。你應該將SAST工具指向你的自有代碼庫,並花一兩天時間對報告的缺陷進行分類,無需對所有缺陷進行分類,只需使用該工具報告的每個類別或規則集中的代表性樣本即可。完成後,你應該有一個真實和誤報的列表,並且能夠推斷出整個代碼庫的誤報率。通過此練習,還可以瞭解哪些規則比哪些規則更準確或更不準確。測量漏報率比較困難,因爲你無法測量不存在的東西,測量漏報率的一種方法是,將bug跟蹤程序中的一系列先前已知的缺陷與通過靜態代碼分析發現的缺陷進行對比,但是這是一個臨時過程,可能會非常耗時,自動化方法將是更理想的。基於這個原因,現在可以看看人工代碼庫了,先前提到的Juliet和Toyota ITC測試套件經過專門設計,可採用科學、有條理的方法來測量SAST工具的準確性和精密度。該套件包含一組“已知答案”綜合測試用例,包括“良好代碼”和“缺陷代碼”,通過檢查SAST工具是否在人工測試套件中檢測到缺陷,可以準確表示漏報率,NIST全面描述了進行此類評估的框架。

靈敏度

靜態分析引擎是否可以微調對其實用性有很大的影響,成熟的解決方案將允許針對各種規則對檢測靈敏度進行調整。通常,這是通過啓用其他過程間值跟蹤功能,啓用錯誤路徑修剪或通過修改統計閾值來實現的。在大多數情況下,更高的準確性會帶來分析速度慢的代價,在評估SAST系統以在整個組織中廣泛部署時,你將需要牢固地掌握是否以及如何調整引擎的靈敏度。你將需要向下調整,使工具更準確,換句話說,你想以更少的漏報爲代價爭取更少的誤報,這是違反常識的,但是你必須認識到,一般的開發人員將不希望被誤報困擾,當你在工程團隊中爭取較高的參與率時,最重要的是較低的誤報率。通過遵循此建議,你將引入更多的漏報,這些漏報不應該遺漏。在典型的質量保證活動中,測試和安全團隊將希望以最積極的方式運行SAST工具,以確保在開發中不會遺漏任何關鍵缺陷,這些團隊應該有能力應對更高的誤報率。

誤報控制

除了規則集的敏感性,減少SAST結果噪音的另一種方法是徹底抑制由於產品和團隊編碼風格的攻擊面或威脅模型而導致的誤報或缺陷類別。特別是,查看該工具如何抑制誤報至關重要,通常,你會看到四個抑制FP(誤報)的選項,每個選項都有優缺點:

  • 在命令行上將抑制標誌傳遞給分析引擎;
  • 通過分析服務器上的配置文件禁止警告;
  • 通過分類GUI將單個缺陷設置爲誤報;
  • 直接在代碼中放置特殊格式的註釋,以指示分析引擎忽略特定文件,函數或代碼行的特定警告類型。

最好使用命令行或者配置文件來實現對整個缺陷類別的大範圍抑制,此外,禁用規則的列表應歸中央靜態分析團隊所有,因爲將列表放在一個位置時更易於審覈。業務最方便的方法是抑制SAST工具的內置GUI中的誤報,這樣,任何人都可以審覈抑制設置,併爲標記爲FP的每個缺陷留下方便的記錄。此外,開發人員通常無法訪問服務的配置文件,也無法更改工具的命令行標誌。通過添加代碼級註釋來抑制規則或警告會很快失去控制,在不知不覺中,你將面臨維護方面的問題:這些抑制依然有效嘛?自添加註釋以來,代碼是否已重構?當代碼已經使用了多年,或者主要開發人員已經離開團隊時,這些問題幾乎無法回答。爲了避免濫用代碼級禁用註釋,應該恢復一個過程,要求在提交之前對所有這些註釋進行review。部署SAST解決方案時,你必須考慮抑制誤報的偏好,最佳實踐通常指出需要使用抑制層次結構,在這種情況下,最好是使用代碼級註釋或分類視圖GUI來抑制配置文件中的某些類型的警告,而在命令行抑制其他類型的警告,在組織中廣泛部署SAST之前,建立這些標準很重要。

處理遺留缺陷

Walter W. Schilling在題爲“將靜態分析集成到軟件開發中”的論文中很好地總結了處理遺留缺陷的問題:將靜態分析應用於舊代碼可能會非常困難,根據代碼的年代,工程師的編碼風格以及所使用的範例,如果不遵循嚴格的方法,則對現有代碼進行靜態分析的範圍可能困難到幾乎不可能。許多舊項目僅在工具第一次運行時產生10萬個或更多警告時才採用靜態分析來排除它,使用舊版代碼,通常無法消除所有靜態檢測出來的問題。換句話說,你必須制定一種策略來處理遺留缺陷,你必須牢記,儘管其中許多缺陷是合理的,但是嘗試開發補丁程序會帶來風險。例如,可能有一些遺留代碼的維護者離職,而其他軟件組件可能由於軟件測試覆蓋範圍不足而脆弱。所以你會怎麼做?最佳實踐有時指出,從開發團隊的角度來看,所有遺留缺陷都應隱藏或消除,再次,儘管違反直覺,這是減輕普通開發人員的負擔,並避免“大海撈針”這類問題。應該引入“零新缺陷”策略,該策略至少要求所有新軟件在你的SAST工具中進行掃描。最後,質量保證或安全團隊的任務應是搜尋遺留的缺陷,以隔離關鍵的安全漏洞,留下其他漏洞,這些策略應在整個組織中部署SAST之前建立。

創建自定義規則集

你必須考慮創建自定義規則集,這些規則集能夠檢測新的安全漏洞類別,或者僅捕獲開發團隊及其編碼風格指南所特有的缺陷。當對之前看不見的安全缺陷(例如在安全事件期間披露的缺陷)作出反應時,這通常很重要。在這種情況下,你將需要檢查新發現的有缺陷的編碼模式是否在代碼庫中重複出現,例如,近期,商業SAST供應商發現“Heartbleed”和“Goto Fail”漏洞表現出了一般模式。每當你的組織遇到安全事件時,你將需要創建一個自定義的規則集並尋找潛在缺陷的變體,靜態代碼分析在一次發現,永久修復(find-it-once-fix-it-forever)安全漏洞響應方法方面非常有效。你需要了解如何定義自定義規則集,甚至嘗試在評估期間自己編寫一些規則,通常,規則可以通過以下兩種方式編寫:

  • 通過使用SAST工具的分析引擎寫一些小的C或Java程序的規則;
  • 在XML或其他類型的文本中定義新規則文件。

擴展語言的靈活性至關重要,你將希望它支持多種規則類型,從簡單的類似於grep模式匹配到完整的過程內或過程間數據流分析。對於你創建的每個自定義規則,你還應該考慮編寫與Juliet和ITC測試套件具有相似目的的單元測試。每個測試都應是嘗試匹配的模式的變體,這將有助於控制誤報率和漏報率。當你希望瞭解是否保持了向後兼容性時,這些測試用例還將在評估SAST引擎的更新時爲您提供幫助。分析引擎還希望能夠覆蓋任何默認或內置規則和模型,例如,假如你的公司已經開發了自己的自定義堆實現,在這種情況下,你必須訓練引擎以識別自定義的mymalloc和myfree例程,否則它將永遠不會在代碼庫中捕獲任何堆溢出漏洞。能夠自定義分析引擎是減少誤報率和支持安全事件響應活動重要方面。

分析速度

多個SAST解決方案的比較還應考慮分析速度,一些打包和監視構建過程的工具會增加開銷,有時會使構建事件增加兩倍或更多。同樣,分析的速度也很重要,這個變化的範圍是巨大的,因爲工具每秒分析的代碼都是在成千上萬行代碼之間進行變化。SAST工具使用複雜的算法和分析方法,這些算法和分析方法的運行速度可能非常慢,或者會佔用大量內存,這些因素將導致分析緩慢或內存耗盡問題,你將被迫做出SAST配置決策,以犧牲精度爲代價。現在,許多商業化的SAST工具都支持並行分析,這對於加速流程有很大的幫助。商業SAST工具中即將出現的一個相對較新的功能稱爲“增量分析”,它也有助於加快分析時間。這可以通過緩存先前分析作業的中間輸出工作,從而避免每次要分析代碼時都需要執行整體清理構建過程。當開發人員在其臺式機上本地運行SAST或使用代碼審查系統集成時,速度是至關重要的。在針對自然和人工代碼庫進行實驗時,你應該測量SAST工具的速度,衡量配置更改的效果也非常有用,打開或關閉某些規則集可能會對運行時產生重大影響,當你希望實施將性能目標傳達給用戶的SLA或要對廣泛部署SAST工具所需的服務基礎結構投資做出預測時,這很有用。

缺陷分類成熟度

比較SAST解決方案時,還應該仔細研究內置缺陷分類流程的成熟度,以瞭解它是否與你現有的程序兼容。繁瑣或不靈活的分類工作流程可能會使用戶採用或破壞採用方式。以下各節總結了需要研究的分類工作流的各個方面。

嚴重性

某些SAST允許更改規則的默認嚴重性,這很有用,因爲你通常會不認同預定義的默認值。如果你希望創建諸如“在解決所有關鍵缺陷之前我們的產品將不發佈”之類的策略,那麼對於關鍵缺陷的實質含義,你必須與SAST工具保持一致,這一點很重要,以這種方式審計每個規則可能是一個繁瑣的過程,但是值得這麼做。

詳細的跟蹤和修復指南

影響分類診斷成熟度的另一個相關因素是SAST工具是否給出了詳細且全面的缺陷信息,以及修復指南是否清晰且可操作,你將需要查看SAST解決方案的內置缺陷分類方法,以確保該指南的全面、緊湊和精確。關於缺陷追蹤,某些系統不可避免地聲明“Defect xxx in file YYY on line #ZZZ”,這有很多不足之處。最有效的工具將包括一個詳細的追蹤,該追蹤描述了爲了到達漏洞而使用的每個條件分支,包括追蹤變量的值(或估值範圍),細節越多越好。你應該將修復指南視爲向開發人員介紹軟件安全性的機會,因此,必須提供清晰且可操作的文檔,每天使用SAST對他們的安全訓練非常有幫助。一些工具還提供指向外部補充指導的鏈接,例如OWASP策略,這也可以使開發人員受益。最後,實際上很少有解決方案可讓你修改修復指南,當你不同意預定的修復建議,或組織在修補某種類型的缺陷時希望工程師遵循額外的步驟時,這一點非常重要。

摺疊類似的缺陷

當SAST系統將相似或相同的缺陷智能地合併爲一個問題時,可以大大減少缺陷積壓和分類工作量。通常,尤其是首次運行該工具之後,你會發現可以用一個單行修復程序消除數十個或數百個缺陷,首先,隔離和修復這些缺陷可以幫助減少初次使用SAST的用戶經常遇到的麻煩。

支持多個分支

隨着GIT的興起,分支變得容易,並已成爲日常工作。你將要了解SAST工具如何支持多個分支以及它是否與你組織的分支策略兼容,許多SAST工具最近都嘗試解決多個分支的問題,但是這些功能尚未完全成熟。值得提出的問題是:如何確保我的SAST工具分析了所有分支?該工具是否會在分支之間合併相同代碼的重複缺陷?如果缺陷在一個分支中得到修復,是否仍在其他分支中報告?

分類工作流和多用戶協作

成熟的SAST解決方案將提供基於Web的GUI,該GUI充當缺陷數據庫之上的表示層。此GUI將強制執行一個分類工作流,該工作流可能與你團隊的缺陷分類兼容亦或不兼容。如果你發現此工作流程不兼容,則應該嘗試瞭解該工具的數據庫架構或報告生成API,因爲你可能需要將缺陷數據庫導出到備用工作追蹤系統中。如果你決定使用內置的分類處理的工作流程,瞭解多個用戶是否可以交互並針對單個缺陷發表評論將很有用。除了允許工程師進行協作,就像在Gerrit這樣的代碼審查系統一樣,當以後對結果進行審覈時,它還增加了有意義的可追蹤性,這樣可以確保重要的對話不會產生離線問題。

隔離用戶與開發者

並非所有用戶每次登錄SAST Web界面時都希望看到存儲庫中的每個缺陷,實際上,看到每個缺陷對於某些開發人員來說都是不知所措,SAST工具應提供用戶僅查看其負責的架構域中的缺陷信息。將目錄映射到團隊的另一個好處是,你可以基於哪些團隊使用SAST服務參與度高或缺陷數量最低的團隊生成指標,注意與用戶共享這些度量標準,因爲它們可能會充當不正當的誘因,從而觸發有利於玩統計數據但不利於提高軟件安全性的真正目標的行爲。

報告生成

僅部署SAST解決方案還不夠好,你將希望仔細測量該工具是否有效運行以及是否達到預期目的,很可能不是,因爲會存在一些參與度低的團隊,或誤報率特別高的代碼區域。您可能希望按嚴重程度或團隊衡量用戶參與度和採用率,以及誤報率和缺陷趨勢。通過仔細測量這些數據點,您的組織可以識別SAST部署中的問題,並迅速採取糾正措施。這種持續改進行爲是敏捷方法論的核心宗旨。SAST解決方案必須支持生成報告的功能,儘管該工具很可能不支持你感興趣的所有類型的報告的生成。因此另一個關鍵功能是能夠導出原始數據,以便你可以進行自己的分析,以下是一些示例報告,根據NCC Group的經驗,這些報告已被證明是有效的。
用戶參與度、採用率和感知度
{% raw %}

報告 糾正措施
測量由SAST掃描的總體代碼庫的百分比 對於每個未掃描的代碼區域,確定所有者,找出丟失代碼的原因,並在SAST的權限下進行遷移。
在SAST服務器上沒有賬號的每個團隊中的開發人員列表,或不定期登錄服務器的用戶的列表 確定可以作爲目標的其他人員或團隊,以進行安全培訓,或者也需要其他糾正措施,例如降低FP率
{% endraw %}

還可以考慮定期向組織的員工發送調查,調查應徵求有關感知、參與等方面的詳細信息。這種方法對於消除由於SAST如何影響日常工作的挫敗感方面非常有效。所有答覆都應認真對待,記住,SAST成功的唯一方法是贏得開發人員,而最好方法是消除開發人員與工具之間的摩擦。

安全和代碼質量指標
{% raw %}

報告 糾正錯誤
統計未解決缺陷的總數 對於每個產品或代碼庫,未解決缺陷的數量應始終呈現下降趨勢
統計用戶報告的誤報率 誤報率應保持在X%以下,如果比例過高,則應採取糾正措施以禁用誤報率較高的規則
統計觀察到的缺陷的類型和數量 如果某種缺陷普遍存在,這可能表示編碼風格指南不佳,或者你的工程人員需要進行鍼對性的培訓
測量缺陷密度(缺陷數 / KLOC) 缺陷密度應始終呈現下降趨勢,或保持在設定的閾值以下,如果不是這樣,則意味着開發人員正在引入新的缺陷,而忽略了SAST工具。
所有軟件產品發佈時0關鍵缺陷 必須設置這種類型的發佈質量指標,從上到下完成,管理人員必須認可靜態分析很重要,並且必須通過工具的結果來衡量產品質量。
{% endraw %}

服務水平協議
你必須向用戶保證,該工具將在需要時可用,並且爲糾正誤報會採取各種糾正措施。
{% raw %}

報告 糾正措施
SAST服務將在X%的時間內可用 你可能不需要6Sigma的正常運行時間,內部SAST服務的SLA,至少應確保在開發人員所在的所有時區的工作日內,該服務絕對不會關閉。
90%的更改將在創建代碼review後的30分鐘內進行分析 你永遠不希望SAST工具成爲代碼審查過程中的瓶頸,因此,你應該在此處設置積極的SLA。
誤報一經發現,將在X天內得到解決 誤報不應該放在積壓中,因爲它們只會提醒用戶有時SAST服務是不準確的,如果識別出誤報,則必須配置該工具以禁止顯示該警告類別。
{% endraw %}

每個SAST配置更改都會經過全面測試,以衡量對FP和FN速率的影響|如果創建自定義規則或修改SAST服務器配置,則必須在自然代碼和人工代碼上都測試你的更改,盲目地進行更改會增加引入FP和FN的風險。

供應商RoadMap

一個好的商業SAST供應商應該能夠向您展示其產品的路線圖。優秀的供應商將制定路線圖,並將其延伸到未來幾年。糟糕的或不願意分享的路線圖可能表明該工具願景不佳。畢竟,你將要在SAST解決方案的評估和部署上投入大量的金錢和時間,因此這些事情很重要。你希望確保在以後幾年可以繼續使用該工具,而不會被迫切換。你還應該要求查看最近幾個發行版的變更日誌。如果供應商進程破壞向後兼容性,很少提供客戶更新,或者很少改進缺陷檢測功能或分析引擎,則不建議使用。

結束語

本文介紹了作者在使用衆多靜態代碼分析工具方面的十年經驗。在大型軟件開發組織中廣泛部署SAST是一項艱鉅的任務,並且從一開始就應在整個部署過程中格外小心。解決方案必須快速,準確,並且最重要的是,它不應給要求使用該工具作爲日常工作的開發人員帶來負擔。這些問題並非不可克服,但他們確實需要警惕的規劃和創造性解決問題,因爲每個組織都有其軟件開發過程的獨特方法。換句話說,沒有任何一種商業SAST解決方案能一勞永逸。NCC Group相信,遵循此處概述的指導和最佳實踐,您更有可能在組織內使用靜態代碼分析取得成功。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章