編者按:圖表視圖流可以使我們能夠快速、有效和準確地找到最佳定位位置。本文通過圖表視圖將代碼可視化,幫助開發(fā)人員描繪出代碼的安全狀態(tài),查看修復不同位置漏洞的影響,自動將超大代碼庫的結(jié)果縮小到可管理的數(shù)量。
使用源代碼分析(SCA)工具最大的挑戰(zhàn)是如何有效地確定優(yōu)先級并進行大量修復行動。對此,一般開發(fā)人員都有點不知所措,他們試圖分析包含彼此獨立呈現(xiàn)結(jié)果的安全報告。
例如,WebGoat(OWASP將不安全的Web應用程序用作安全培訓的測試平臺)具有100多個跨站點腳本(XSS)漏洞,假設每個漏洞修復需要30 min,而驗證又需要30 min,那么我們的研究將至少需要3周的時間。
對于包含數(shù)千行代碼的大型項目而言,或者對于具有快速開發(fā)周期的環(huán)境(例如DevOps),這種周轉(zhuǎn)時間肯定太長而且成本昂貴,甚至不切實際。由于存在大量的漏洞,因此釋放易受攻擊且未修復的代碼也就不足為奇了。
在本文中,在介紹源代碼分析如何修復漏洞之前,先簡單介紹一下源代碼分析的主要優(yōu)勢,然后通過圖表視圖將代碼可視化,展示出如何幫助開發(fā)人員從漏洞到漏洞的直觀洞察力,描繪出那些代碼的安全狀態(tài),查看修復不同位置漏洞的影響,自動將超大代碼庫的結(jié)果縮小到可管理的數(shù)量。
實際上,使用這種方法,即使不查看代碼,也可以將WebGoat XSS漏洞的固定位置數(shù)量減少到僅有16個。
源代碼分析一般指源程序分析,源程序分析是對應某一個具體問題的軟件(計算、遍歷、查找及排序),分析程序功能的原子結(jié)構(gòu)、分子結(jié)構(gòu)(在數(shù)據(jù)結(jié)構(gòu)中稱為聚合結(jié)構(gòu)),最后用特定算法綜合得到程序框架。
靜態(tài)代碼分析是一種自動分析應用程序的源代碼和二進制代碼以查找安全漏洞的技術(shù)。根據(jù)Gartner的2011年靜態(tài)應用程序安全測試魔力象限(SAST),“對于所有開發(fā)或采購應用程序的IT組織,應將SAST視為強制性要求”。
實際上,近年來,我們已經(jīng)看到了應用程序安全性的轉(zhuǎn)變,而代碼分析已成為引入安全軟件開發(fā)和衡量固有軟件風險的標準方法之一。此領(lǐng)域中存在兩種類別:
(1)二進制或字節(jié)碼分析(BCA)
分析由編譯器創(chuàng)建的二進制或字節(jié)碼。
(2)源代碼分析(SCA)
分析程序的實際源代碼,而無需檢索所有代碼即可進行編譯。這兩種產(chǎn)品都承諾提供安全性以及將安全性納入軟件開發(fā)生命周期(SDLC)的要求。
一方面,BCA節(jié)省了一些代碼分析工作,因為編譯器使工作的一部分自動化,例如解析代碼符號。然而另一方面,具有諷刺意味的是,正是這種編譯器的卸載帶來了BCA的根本缺陷。為了使用BCA,必須在掃描所有代碼之前對其進行編譯。這就帶來了許多問題,這些問題使SDLC進程推遲,給安全性造成了不好的作用。
主要問題包括:
(1)漏洞在運行中暴露得太晚
由于必須在掃描之前編譯所有代碼,因此安全性在SDLC中被推到了相對較晚的階段。在這一點上,掃描通常發(fā)現(xiàn)要處理的漏洞太多,沒有時間修復,并且銷售和市場團隊要求發(fā)布產(chǎn)品。結(jié)果,這些漏洞(盡管已被發(fā)現(xiàn))被推送釋放。在實際項目中(例如在Linux OS發(fā)行版本中發(fā)生的掃描過程),實際的漏洞已經(jīng)在掃描過程中逐漸消失。
(2)編譯器優(yōu)化會損害結(jié)果的準確性
編譯器執(zhí)行的許多任務之一是根據(jù)效率和大小來優(yōu)化代碼。但是,這種優(yōu)化可能會犧牲結(jié)果的準確性。例如,編譯器可能會刪除所謂的“無關(guān)”行,也就是無效代碼。這些是開發(fā)人員在調(diào)試過程中插入的代碼行。在編譯器刪除這些代碼段的同時,它們可能包含違反公司標準的代碼。
(3)PaaS提供程序無法檢索字節(jié)碼
在云計算場景中,PaaS提供者負責程序的驗證、專有編譯和執(zhí)行。但是PaaS提供程序又無法檢索字節(jié)碼,或者沒有體現(xiàn)為字節(jié)碼或二進制。
通過掃描源代碼本身,可以將SCA順利集成到SDLC中,并提供有關(guān)代碼及其安全性的近乎實時的反饋。源代碼分析可以彌補BCA的不足,并提供有效、可行的替代方案。
(1)掃描代碼片段和非編譯代碼
SCA工具能夠掃描代碼片段,而不管由于語法或其他錯誤引起的編譯錯誤。審核員和開發(fā)人員都可以在開發(fā)過程中掃描不完整的代碼,而無需完成構(gòu)建,最終可以在軟件開發(fā)生命周期(SDLC)的更早階段發(fā)現(xiàn)漏洞。
(2)支持云編譯語言
在云計算場景下已經(jīng)開發(fā)了新的編碼語言。在這些情況下,開發(fā)人員使用PaaS提供程序的語言進行編碼,而PaaS提供程序負責驗證,專有編譯和執(zhí)行程序。在這些情況下,代碼既不表現(xiàn)為字節(jié)碼也不表現(xiàn)為二進制,并且SCA必須在源代碼本身上完成。
比較典型的示例是Sales force.com提供的Force.com平臺,該平臺基于被稱為Apex的基于服務器的語言和VisualForce的基于客戶端的語言。只有SCA產(chǎn)品才能支持此新范例。
(3)評估非鏈接代碼的安全性
如果代碼引用缺少其源代碼的基礎結(jié)構(gòu)庫,則BCA工具會立即在不幸的“缺少庫”消息上失敗??赡苄枰ㄙM幾天時間為這些缺失的部分構(gòu)建存根,如果只是為了使代碼得以編譯,這種大量的辛苦工作是沒有任何附加價值的。SCA產(chǎn)品可以輕松識別漏洞,例如SQL注入——即使缺少執(zhí)行SQL函數(shù)調(diào)用的實際庫代碼。
(4)不可知的編譯器
通常情況下,在代碼審核員和大型公司中找到的多編譯器環(huán)境中,SCA標準提供了一種適合所有人的解決方案。這與BCA完全相反,后者必須支持無數(shù)的編譯器和版本。原因是什么呢?
每個編譯器都將源代碼轉(zhuǎn)換為自己的二進制或字節(jié)代碼版本,從而迫使BCA工具讀取,理解和分析不同編譯器的不同輸出。但是,由于SCA工具是在代碼本身上運行的,而不是在編譯后運行的,因此SCA提供了與編譯器版本或編譯器升級無關(guān)的單個標準。
(5)與平臺無關(guān)
將SCA集成到SDLC中時,可以使用完全相同的工具在任何地方掃描代碼,而無需考慮操作系統(tǒng)或開發(fā)環(huán)境。這消除了BCA固有的冗余性,后者必須為每個平臺提供單獨的掃描工具。
“知道您的敵人”是任何安全專業(yè)人員的口頭禪。它定義了我們所面對的,以及如何面對它并采用何種策略,它為所有未來成果奠定了基礎。對開發(fā)人員而言也是如此——敵人是易受攻擊的代碼。應用程序安全操作方法如下:
在安全編碼的實踐中,開發(fā)人員應大致了解其代碼的安全狀況,代碼中包含的漏洞數(shù)量以及如何將自己表現(xiàn)出來以達到利用的目的。這是圖表視圖將代碼可視化的基礎。
(1)基礎知識:數(shù)據(jù)流
最好將數(shù)據(jù)流描述為從漏洞源到可以利用它的點(也稱為“接收器”)的代碼路徑的可視化。如圖1所示,流程中的每個步驟都反映為圖中的一個節(jié)點。
傳統(tǒng)上,每個漏洞結(jié)果只有一個數(shù)據(jù)流,與其他結(jié)果無關(guān)。因此,對于眾多結(jié)果(例如14個不同的漏洞發(fā)現(xiàn)),我們可以查看具有14個獨立流的圖表視圖,如圖2所示。
顯然,這樣的圖對理解如何確定修復的優(yōu)先次序沒有太大幫助。開發(fā)人員真正需要的是理解不同流程之間的關(guān)系,并盡可能簡化生成的圖表視圖。
(2)改善可見性:圖表視圖
圖表視圖采用這些單獨的數(shù)據(jù)流,并以易于呈現(xiàn)流之間關(guān)系的方式對其進行描述。建立圖表需要兩步的過程。
第一步:合并出現(xiàn)在多個路徑中的同一節(jié)點。換句話說,標識并合并實際上由同一數(shù)據(jù)流共享的那些代碼。從上方獲取14路徑圖,請考慮最左側(cè)的5個源共享同一節(jié)點的情況。反過來,此節(jié)點與位于其級別的另一個節(jié)點,共享一個更靠近接收器的節(jié)點,如圖3所示。
圖1 數(shù)據(jù)流流程示意圖
圖2 具有14個獨立流的圖表視圖
第二步:簡化圖表視圖以減少數(shù)據(jù)流級別的數(shù)量。這可以通過將看起來相似的數(shù)據(jù)流組合到單個節(jié)點來完成。對于熟悉圖論的人來說,您可能現(xiàn)在已經(jīng)意識到,我們正在構(gòu)建原始圖的“homeograph”,即結(jié)構(gòu)相同但表示簡化的圖。我們首先將節(jié)點分組,如圖4所示。
隨著我們繼續(xù)這一過程,最終的圖表視圖結(jié)果如圖5所示。
通過簡化的圖表視圖流,我們現(xiàn)在就可以直觀地看到代碼的安全性,不再僅僅看代碼位和看似完全不同的代碼缺陷,圖表流實際上使我們能夠看到漏洞之間的相關(guān)性。
圖3 合并出現(xiàn)在多個路徑中的同一節(jié)點
圖4 將節(jié)點分組并簡化圖表視圖
圖5 最終圖表視圖簡化結(jié)果
此外,快速瀏覽一下圖表視圖,可以使我們深入了解某個漏洞對其余代碼的影響。這種關(guān)系實在是太復雜了,無法通過代碼審查來理解。
(3)蝴蝶效應:考慮修復方案
如果您將代碼固定在某個位置怎么辦?這將如何影響代碼?在另一個地方怎么樣?如果有了圖表視圖,我們就可以考慮所有這些情況,快速查看整體效果,并自行決定采取哪種路線。
讓我們再次看一下原始示例的簡化視圖(又稱“homeograph”)。箭頭所指的單個節(jié)點的修復導致修復了兩個單獨的路徑。如圖6所示。
另一方面,圖7顯示了如果我們嘗試修復其他節(jié)點會發(fā)生什么。在這種情況下,箭頭所指的節(jié)點只會導致路徑的部分固定,原因是該代碼的底部“分支”也受到尚未修復的其他節(jié)點的影響。
圖6 單個節(jié)點的修復情況
圖7 修復其他節(jié)點的情況
圖8 理想情況下的“最佳固定”位置
我們可以繼續(xù)與圖進行交互,并考慮不同的“假設”場景。它們不僅會向我們展示修復特定漏洞的連鎖反應,而且會在一段時間后養(yǎng)成這種習慣,我們會在不知不覺中了解某些漏洞的影響,并且始終會開始認識到我們自己的“最佳修復位置”。
(4)這是最好的:優(yōu)化漏洞修復
在理想情況下,我們還希望能夠準確、自動地找出圖中的“最佳固定”位置。如圖8所示。
這要求采用圖表圖形論概念,特別是“最大流最小剪切”定理可幫助我們計算固定最大流量的最小節(jié)點更新量。將此計算應用于示例圖,我們就可以直觀地找到3個節(jié)點,這些節(jié)點如果固定就可以糾正整個流程圖。
考慮到我們從相當于70個節(jié)點的14路徑圖開始,是不是讓您感覺這真是太神奇了?
對于開發(fā)人員和安全專業(yè)人員而言,圖表視圖流是一種視覺上吸引人的一種非常好的方式,它可以完全理解代碼中不同部分之間的關(guān)系,以及受污染的代碼段向其接收器的傳播。
代碼的可視化提供了一個人機交互式的工具,它使開發(fā)人員可以主動考慮在不同位置修復各種漏洞的影響。最重要的是,圖表視圖流可以使我們能夠快速、有效和準確地找到最佳定位位置。