為什么代碼重用仍然是一個(gè)安全噩夢(mèng)
現(xiàn)代軟件應(yīng)用程序是由數(shù)以千計(jì)的從公共資源庫(kù)中獲取的第三方組件拼接而成的。這種代碼的重用對(duì)軟件行業(yè)有很大的好處,它減少了開(kāi)發(fā)時(shí)間和成本,使開(kāi)發(fā)人員能夠更快地增加功能,但由于復(fù)雜的依賴(lài)關(guān)系系統(tǒng)往往難以跟蹤,它也產(chǎn)生了重大的漏洞管理問(wèn)題。
繼承自第三方代碼的漏洞多年來(lái)一直困擾著應(yīng)用程序,但在政府贊助的軟件供應(yīng)鏈攻擊時(shí)代,這個(gè)問(wèn)題比以往任何時(shí)候都更有意義。軟件組合分析工具可以幫助發(fā)現(xiàn)其中的一些風(fēng)險(xiǎn),但微妙的依賴(lài)性盲點(diǎn)仍然存在,即使是有安全意識(shí)的開(kāi)發(fā)人員也很難抓住所有繼承的缺陷。
來(lái)自ReversingLabs的安全研究人員最近對(duì)NuGet倉(cāng)庫(kù)進(jìn)行了掃描,發(fā)現(xiàn)有5萬(wàn)個(gè)軟件包正在使用一個(gè)名為zlib的流行庫(kù)的過(guò)時(shí)和脆弱版本。他們中的許多人沒(méi)有明確地把它列為依賴(lài)關(guān)系。
依賴(lài)性跟蹤是一針見(jiàn)血的
為了發(fā)現(xiàn)所有的漏洞,開(kāi)發(fā)人員不僅需要跟蹤他們?cè)谧约旱膽?yīng)用程序中使用的組件,還需要跟蹤這些組件所基于的第三方庫(kù)和包。依賴(lài)關(guān)系鏈可以深入很多層。達(dá)姆施塔特大學(xué)的研究人員在2019年對(duì)npm資源庫(kù)進(jìn)行的分析發(fā)現(xiàn),平均來(lái)說(shuō),導(dǎo)入一個(gè)JavaScript包會(huì)對(duì)39個(gè)不同維護(hù)者的79個(gè)其他包引入隱性信任。當(dāng)時(shí),研究人員還發(fā)現(xiàn),近40%的軟件包依賴(lài)的代碼至少有一個(gè)公開(kāi)的漏洞。
一個(gè)問(wèn)題是,只有與同一存儲(chǔ)庫(kù)上的軟件包有關(guān)的依賴(lài)關(guān)系才會(huì)被軟件包存儲(chǔ)庫(kù)及其相應(yīng)的軟件包管理工具所追蹤。但這并不是第三方代碼進(jìn)入項(xiàng)目的唯一途徑。一些開(kāi)發(fā)者靜態(tài)鏈接庫(kù)或手動(dòng)編譯來(lái)自其他項(xiàng)目的代碼,這些代碼存在于軟件包庫(kù)之外,這些信息不容易用自動(dòng)掃描工具找到。
ReversingLabs發(fā)現(xiàn)超過(guò)50個(gè)NuGet軟件包包含主動(dòng)利用的漏洞,因?yàn)樗鼈兝壛诉^(guò)時(shí)的和脆弱的7Zip、WinSCP和PuTTYgen版本。這些都是流行的壓縮或網(wǎng)絡(luò)連接程序,它們不直接托管在NuGet上,但可能有其他開(kāi)發(fā)者在NuGet上為它們創(chuàng)建的包裝包。
NuGet是.NET編程語(yǔ)言的主要倉(cāng)庫(kù),那里托管的大多數(shù)組件都是以ZIP檔案的形式發(fā)送,擴(kuò)展名為.nupkg,包含預(yù)編譯的Windows .DLL庫(kù),旨在導(dǎo)入其他軟件項(xiàng)目中。
ReversingLabs發(fā)現(xiàn)的一個(gè)易受攻擊的NuGet包名為WinSCPHelper,是WinSCP的一個(gè)封裝庫(kù)。它允許集成它的應(yīng)用程序通過(guò)SFTP協(xié)議管理遠(yuǎn)程服務(wù)器上的文件。WinSCPHelper自2017年以來(lái)沒(méi)有在NuGet上更新過(guò),但最后一個(gè)版本自發(fā)布以來(lái)被下載了超過(guò)34000次,在過(guò)去6周內(nèi)被下載了約700次。最新的WinSCP版本是5.17.10,包含一個(gè)關(guān)鍵的遠(yuǎn)程代碼執(zhí)行漏洞的補(bǔ)丁,但與WinSCPHelper捆綁的版本是一個(gè)更老的版本--5.11.2。
"雖然在這種情況下,被分析的軟件包明確指出它使用了WinSCP,但它沒(méi)有在依賴(lài)列表中披露版本,你不能輕易發(fā)現(xiàn)哪些漏洞影響了它的基礎(chǔ)依賴(lài),"研究人員說(shuō)。"這是手工作業(yè),仍然可以做到,但需要一些努力"。
識(shí)別無(wú)聲的漏洞
但追蹤依賴(lài)關(guān)系可能比這更難。以zlib為例,它是最廣泛使用的開(kāi)源數(shù)據(jù)壓縮庫(kù)之一,最初寫(xiě)于1995年。這個(gè)庫(kù)幾乎已經(jīng)成為事實(shí)上的標(biāo)準(zhǔn),并由其維護(hù)者作為源代碼提供。這意味著開(kāi)發(fā)人員傾向于自己編譯它,并在他們的項(xiàng)目中靜態(tài)地鏈接它,由于它是如此無(wú)處不在,所以常常不提它的存在。
通過(guò)靜態(tài)文件分析,ReversingLabs發(fā)現(xiàn)超過(guò)5萬(wàn)個(gè)NuGet軟件包使用zlib 1.2.8版本,該版本發(fā)布于2013年,包含四個(gè)高度或嚴(yán)重的漏洞。一些被識(shí)別的軟件包通過(guò)其他沒(méi)有明確列出依賴(lài)關(guān)系的第三方組件繼承了這個(gè)舊的zlib版本和它的漏洞,促使研究人員把這些稱(chēng)為沉默的漏洞。
ReversingLabs提供的一個(gè)例子是一個(gè)名為DicomObjects的NuGet包,它實(shí)現(xiàn)了醫(yī)學(xué)中的數(shù)字成像和通信(DICOM)協(xié)議。DICOM是一個(gè)用于傳輸和管理醫(yī)學(xué)成像數(shù)據(jù)的標(biāo)準(zhǔn)。它在醫(yī)院中被廣泛使用,并被許多成像設(shè)備支持,如醫(yī)療掃描儀、打印機(jī)、服務(wù)器和工作站。
DicomObjects被醫(yī)療軟件開(kāi)發(fā)者用來(lái)輕松構(gòu)建DICOM解決方案,它有近54000次下載,由一家名為Medical Connections的英國(guó)公司維護(hù)。該軟件包將Microsoft.AspNet.WebApi.Client、Newtonsoft.Json和System.Net.Http列為依賴(lài)項(xiàng),但據(jù)ReversingLabs稱(chēng),它還捆綁了一個(gè)名為ceTe.DynamicPDF.Viewer.40.x86.dll的商業(yè)PDF庫(kù),但沒(méi)有明確提及。DynamicPDF Viewer在NuGet上被列為一個(gè)單獨(dú)的軟件包,但DicomObjects中捆綁的版本是一個(gè)更老的版本,包括zlib 1.2.8。
"這是最常見(jiàn)的軟件維護(hù)問(wèn)題之一,"研究人員說(shuō)。"開(kāi)發(fā)者創(chuàng)建了一個(gè)軟件包,決定使用第三方軟件,但在隨后的更新過(guò)程中,依賴(lài)性被忽略了。在這種情況下,事情就更糟糕了,因?yàn)槿魏蔚胤蕉紱](méi)有明確提到DicomObjects軟件包依賴(lài)于DynamicPDF.Viewer。我們沒(méi)有辦法知道DynamicPDF.Viewer依賴(lài)于有漏洞的zlib庫(kù)。以這種方式堆疊隱藏的依賴(lài)關(guān)系會(huì)導(dǎo)致多層次的無(wú)聲漏洞,并使軟件維護(hù)和審計(jì)的難度大大增加"。
Medical Connections沒(méi)有立即回應(yīng)評(píng)論請(qǐng)求。
另一個(gè)例子是一個(gè)叫做librdkafka.redist的高度流行的軟件包,這是一個(gè)實(shí)現(xiàn)Apache Kafka協(xié)議的C庫(kù)。Apache Kafka是一個(gè)開(kāi)源的高性能流處理框架,用于處理實(shí)時(shí)數(shù)據(jù)傳輸。librdkafka.redist包有1890萬(wàn)次下載,其中312000次是2個(gè)月前發(fā)布的最新版本1.7.0。這個(gè)版本的librdkafka.redist使用zlib 1.2.8,但在NuGet或GitHub的項(xiàng)目依賴(lài)列表中沒(méi)有明確說(shuō)明。
這個(gè)問(wèn)題在一年多以前就被報(bào)告在GitHub上的項(xiàng)目bug追蹤器上,目前被標(biāo)記為要在1.8.0版本中修復(fù)。該項(xiàng)目首席開(kāi)發(fā)者M(jìn)agnus Edenhill審查了這四個(gè)zlib漏洞,并表示其中只有兩個(gè)適用于librdkafka,通過(guò)Kafka消耗的消息成功利用這些漏洞的風(fēng)險(xiǎn)似乎非常低。Edenhill沒(méi)有立即回應(yīng)評(píng)論請(qǐng)求。
其他13個(gè)NuGet軟件包依賴(lài)于librdkafka.redist,包括一些由一家名為Confluent的數(shù)據(jù)基礎(chǔ)設(shè)施公司開(kāi)發(fā)的軟件包,該公司擁有許多大型企業(yè)客戶。
"安全軟件開(kāi)發(fā)是一個(gè)復(fù)雜的問(wèn)題,因?yàn)樗婕暗介_(kāi)發(fā)的多個(gè)階段的許多參與者,"ReversingLabs的研究人員說(shuō)。"無(wú)論你的公司生產(chǎn)什么類(lèi)型的軟件,遲早都需要將第三方的依賴(lài)關(guān)系納入你的解決方案。這將引入管理安全和代碼質(zhì)量風(fēng)險(xiǎn)的需要。軟件供應(yīng)鏈攻擊對(duì)網(wǎng)絡(luò)社區(qū)的威脅越來(lái)越大。它們是傳統(tǒng)漏洞的DDoS類(lèi)似物"。
供應(yīng)鏈風(fēng)險(xiǎn)
NuGet并不是唯一存在這種脆弱依賴(lài)問(wèn)題的軟件包庫(kù),人們可以說(shuō),不是由NuGet或其他庫(kù)來(lái)迫使開(kāi)發(fā)者更關(guān)注這些問(wèn)題。然而,有些平臺(tái)比其他平臺(tái)更積極主動(dòng)。GitHub積極掃描其平臺(tái)上托管的公共代碼庫(kù),分析它們的依賴(lài)關(guān)系,如果這些依賴(lài)關(guān)系中有任何已知的漏洞,就通知其所有者。該公司維護(hù)一個(gè)公共咨詢數(shù)據(jù)庫(kù),其中包括npm(JavaScript)、RubyGems(Ruby)、NuGet(.NET)、pip(Python)、Maven(Java)的已知漏洞,并剛剛宣布支持Go模塊。
開(kāi)源治理公司Sonatype在其《2020年軟件供應(yīng)鏈報(bào)告》中指出,下一代攻擊的數(shù)量同比增長(zhǎng)了430%,黑客試圖主動(dòng)向開(kāi)源軟件項(xiàng)目注入惡意軟件,試圖毒害其依賴(lài)鏈上的更多項(xiàng)目和應(yīng)用程序。黑客利用開(kāi)源組件中的已知漏洞的傳統(tǒng)攻擊仍然強(qiáng)勁,但利用的時(shí)間已經(jīng)減少,攻擊者在公開(kāi)披露的幾天內(nèi)就利用了新發(fā)現(xiàn)的漏洞。同時(shí),有一半的公司需要一周以上的時(shí)間來(lái)了解這些漏洞,并在一周或更長(zhǎng)時(shí)間后將緩解措施落實(shí)到位。
攻擊者顯然對(duì)利用軟件供應(yīng)鏈很感興趣,但成千上萬(wàn)的具有繼承性漏洞的軟件包仍在公共資源庫(kù)中,并作為企業(yè)軟件的基礎(chǔ)模塊。