他們說軟件會吃掉世界,但是Bug還沒解決掉

“9月25日周二下午,我們的工程團(tuán)隊發(fā)現(xiàn)了一個影響近5000萬個賬戶的安全問題,”Facebook的Guy Rosen在公司9月份的一次安全更新中表示到。

這個問題很嚴(yán)重。被盜的并不是密碼,而是訪問令牌(access token),這是一個不透明的字符串,用于標(biāo)識用戶,并授予對API的訪問權(quán),這里的API指的是應(yīng)用程序用戶訪問Facebook時使用的軟件接口。

獲得令牌后,攻擊者便可以以其他用戶的身份登錄Facebook,更糟糕的是,這些不法分子還可以使用偷來的Facebook用戶身份來驗(yàn)證登錄其他網(wǎng)站,不過目前尚不足清楚這種情況是否已經(jīng)發(fā)生,攻擊背后的幕后主使也不得而知。

這個安全災(zāi)難的原因是一個編程錯誤,或者更確切地說,是工程VP Pedro Canahuati 所述的,這是“三個bug的組合”。第一個是發(fā)生在視頻只讀API中的bug,第二個是視頻上傳API中的一個bug,后者生成一個具有廣泛權(quán)限(Facebook移動應(yīng)用程序權(quán)限)的訪問令牌。而第三個(可能也是最嚴(yán)重的)bug是生成的訪問令牌針對的不是當(dāng)前用戶,而是正在查看概要文件的另一個用戶。

該事件表明,bug永遠(yuǎn)無法避免,即使是那些資源最豐富的軟件項目,而且人們也很難發(fā)現(xiàn)那些不會立即影響功能的bug。雖然測試是今天軟件開發(fā)和部署中不可或缺的一步,但是沒有哪個測試可以試驗(yàn)所有可能的輸入組合,或者展現(xiàn)出所有可能的失敗。

這個案例還展示了當(dāng)今軟件bug的影響是如何被某些代碼的大量使用和放大的。在本例中,我們討論的是攻擊者可能會利用大約5000萬個帳戶,來訪問未知數(shù)量的第三方站點(diǎn)。

另一個近期的例子是: 2018年10月,微軟在沒有充分測試的情況下發(fā)布了Windows 10的特性更新,而其中的一個bug會在某些情況下會刪除用戶數(shù)據(jù)。在被下架之前,該更新已經(jīng)被安裝到了數(shù)千名用戶的系統(tǒng)中,微軟為此付出的聲譽(yù)、補(bǔ)救和支持成本可想而知。

時間往前推移一些,還有2014年發(fā)現(xiàn)的“心血”(Heartbleed)漏洞, 它源自O(shè)penSSL加密庫中的一行代碼:

memcpy(bp, pl, payload);

該代碼不會檢查數(shù)據(jù)的實(shí)際大小是否與復(fù)制的數(shù)量相匹配。因此,攻擊者可以在大小上進(jìn)行欺騙,并接收出現(xiàn)在內(nèi)存中的其他數(shù)據(jù)副本,其可能包括用戶名和密碼。這個bug影響了Apache和Nginx web服務(wù)器,而這些服務(wù)器又被世界上三分之二的活躍網(wǎng)絡(luò)站點(diǎn)以及無數(shù)其他網(wǎng)絡(luò)應(yīng)用程序使用著。

向前一步,退后兩步

2011年,風(fēng)險投資家Marc Andreessen因認(rèn)為軟件正在吃掉世界而登上新聞頭條。某種程度上,這個表述還算正確,但是我們可能都沒注意到軟件中的bug問題。早在二十年前,程序員及作家Steve McConnell 就認(rèn)為按行業(yè)平均水平,每1000行的代碼中就會存在15到50個bug,同時權(quán)威IT項目跟蹤機(jī)構(gòu)Standish Group也在報告中指出,1995年有三分之一的軟件項目最終取消,這帶來了810億美元的浪費(fèi)。McConnell和Standish Group簡直是軟件交付派對上的幽靈,他們進(jìn)一步加劇了軟件交付實(shí)踐質(zhì)量不佳的壞名聲。軟件項目總是會延期,而且總是會存在大量的bug。在那時,如果真的有軟件項目真的能按時、按預(yù)期并按預(yù)期運(yùn)行,那真可以用驚喜形容。

不過,那是上世紀(jì)90年代的舊事了,如今的軟件工具、開發(fā)實(shí)踐和文化自那時起已發(fā)生了很大變化。這類轉(zhuǎn)變的突出代表包括測試驅(qū)動型開發(fā)和源于極限編程方法論(Extreme Programming methodology)的代碼覆蓋概念(即測試期間執(zhí)行代碼的數(shù)量)。靜態(tài)代碼分析是另一個突破,該方法使用工具執(zhí)行編碼標(biāo)準(zhǔn),并捕捉比較明顯的bug。同時,編碼標(biāo)準(zhǔn)本身也在不斷發(fā)展,包含了使代碼變得更可靠的知識,例如保持代碼單元簡短。

更安全的編程語言也在提供幫助。具有自動內(nèi)存管理且不直接使用指針的高級語言,如1996年首次發(fā)布的Java,它使開發(fā)人員更容易避免一些錯誤。在最近,像GitHub這樣的云托管工具的出現(xiàn),也使得各個團(tuán)隊的中軟件生命周期管理工具變得更加易用。

開發(fā)人員是否因此保持了代碼的“清潔”?

隨著軟件變得越來越普遍,答案應(yīng)該是肯定的。軟件不再僅僅是工作場所(Windows個人電腦和服務(wù)器)的專利,也不再是為晦澀難懂的工業(yè)控制系統(tǒng)編寫的復(fù)雜流程。但同時軟件缺陷帶來的風(fēng)險,也不再是僅存在于公司的服務(wù)器中了。

據(jù)2017年Mitre常見缺陷列表(CWE)所示,實(shí)際情況并不樂觀。首先就是注入攻擊(injection attack),它包括SQL注入在內(nèi),在此情況眾,用戶輸入可以執(zhí)行未經(jīng)授權(quán)的命令。 多年來,該缺陷一直為人所知,并不斷引發(fā)問題。

CWE列表中收錄的另一大缺陷是“使用具有已知漏洞的組件”。軟件開發(fā)人員一直依賴于代碼庫;而任何項目中的大多數(shù)代碼都是由其他人編寫的。但是,正如Heartbleed所顯示的那樣,庫和組件并不能避免漏洞。當(dāng)庫或組件中的錯誤被發(fā)現(xiàn)時,它將被修復(fù)。

不過,修補(bǔ)所有正在使用的應(yīng)用程序中的bug是非常具有挑戰(zhàn)性的。許多受到影響的應(yīng)用程序可能得不到良好地開發(fā),一些bug還可能存在于永遠(yuǎn)得不到修補(bǔ)的網(wǎng)絡(luò)設(shè)備固件中。因而物聯(lián)網(wǎng)變成了“bug網(wǎng)”,除非有自動補(bǔ)丁存在,同時供應(yīng)商也提供細(xì)致的補(bǔ)丁管理。

此外,bug不僅很昂貴,而且還性命攸關(guān)??突仿〈髮W(xué)教授Phil Koopman專門研究嵌入式軟件的質(zhì)量,比如自動駕駛汽車和其他類汽車軟件安全等,在最近的一篇關(guān)于汽車軟件缺陷與潛在致命性的文章中,Koopman列出了50個令人不安的缺陷報告,如突然加速、無法脫離自動駕駛控制以及妨礙司機(jī)進(jìn)行轉(zhuǎn)向控制等。

降低代碼復(fù)雜度

Koopman指出,提高軟件質(zhì)量在很大程度上就是觀察最佳實(shí)踐。

這包括降低代碼復(fù)雜性、使用靜態(tài)分析工具和零警告編譯、認(rèn)真檢查實(shí)時代碼調(diào)度、嚴(yán)格軟件測試以及使用基本工具(包括配置管理、版本控制和bug跟蹤等)。

CAST Research Labs在2017年發(fā)表了一篇關(guān)于應(yīng)用軟件健康程度的報告,該報告基于遍及8個國家和329個組織的1850個“大型、多層、多語言的商用程序”,一共具有10億行代碼。該報告基于五個健康因素:穩(wěn)定性、安全性、效率、可更改性(代碼修改難度)和可轉(zhuǎn)移性(對于剛接觸代碼的開發(fā)人員來說理解代碼有多難)。

CAST的報告令人鼓舞,所有類別的總體平均得分在3.0或以上,其中安全性最好在3.22分,可移植性最差在3.0分。這種相當(dāng)高的質(zhì)量水平反映了這樣一個事實(shí),即這些應(yīng)用程序通常會在資源豐富的部門中起關(guān)鍵作用。

但這些結(jié)論仍值得再推敲一下。比如安全評分差異較大,這說明缺乏安全編碼實(shí)踐仍然是一個問題。在團(tuán)隊規(guī)模方面,CAST認(rèn)為超過20名開發(fā)人員的團(tuán)隊得分較低,并建議最佳團(tuán)隊規(guī)模應(yīng)該在10人或更少。

另一個有趣的地方是,最佳評分項目背后的方法既不是敏捷性的(強(qiáng)調(diào)迭代開發(fā)),也不是瀑布式的(強(qiáng)調(diào)預(yù)先計劃),而是一種混合方法,它具有廣泛的預(yù)先分析,然后是簡短的迭代編碼沖刺。

CAST還指出,涉及“跨應(yīng)用程序的多層多組件”的軟件架構(gòu)類的代碼質(zhì)量更難測試;但結(jié)構(gòu)質(zhì)量才是導(dǎo)致大多數(shù)運(yùn)營問題的原因。

慢編碼

編寫防彈代碼的速度依然較慢,因此開發(fā)時成本較高,這也是軟件質(zhì)量仍然如此參齊不齊的一個原因。眾所周知,缺陷發(fā)現(xiàn)得越晚,修復(fù)缺陷的成本就會越高,不過,由于差異很大,很難給出缺陷造成具體多大影響的通用數(shù)字。

在web應(yīng)用程序的DevOps流程中,我們可以進(jìn)行代碼更改、自動測試并快速部署到生產(chǎn)環(huán)境中,所以修復(fù)最近發(fā)現(xiàn)的bug的成本可能不算太高。但這里有個極端的例子,1996年阿麗亞娜5號火箭(Ariane 5) 在發(fā)射時發(fā)生了爆炸,這是由64位變量轉(zhuǎn)換為16位變量后數(shù)量太大導(dǎo)致系統(tǒng)無法容納引起的,這個bug的直接經(jīng)濟(jì)損失約為5億美元。

而日常生活中呢?根據(jù)IT軟件質(zhì)量聯(lián)盟(Consortium for IT Software Quality)的數(shù)據(jù),除去技術(shù)債務(wù)后,所謂的“低質(zhì)量”軟件給美國經(jīng)濟(jì)造成2.26萬億美元的損失。再細(xì)分一下,軟件故障造成的損失占該數(shù)字的37.46%,查找和修復(fù)缺陷的任務(wù)占16.87%。

對于任何公司來說,在生產(chǎn)過程之前,找到bug并進(jìn)行修復(fù)是一個優(yōu)先事項,因?yàn)樾迯?fù)bug或處理后續(xù)問題所涉及的成本會隨著時長的延長而增加。

因此,生產(chǎn)過程中的bug可能會帶來嚴(yán)重的長期成本。如果bug出現(xiàn)在其他軟件所依賴的軟件或固件中,例如API,那么第三方開發(fā)人員可能必須要圍繞該bug編寫代碼。然后這就會出現(xiàn)兼容性問題,因?yàn)樾迯?fù)這個bug可能會破壞其他軟件。

當(dāng)今互聯(lián)時代與早期軟件開發(fā)時代的一個關(guān)鍵區(qū)別是,部署補(bǔ)丁很容易,而且通常是自動化的。由于使用了一些技術(shù),例如提示用戶將崩潰數(shù)據(jù)提交回開發(fā)人員,或者使用“飛行記錄器”代理捕獲應(yīng)用程序狀態(tài)并準(zhǔn)確記錄崩潰時正在執(zhí)行的代碼,現(xiàn)在人們更容易跟蹤導(dǎo)致崩潰的bug。通過快速發(fā)現(xiàn)和修復(fù),可以減輕明顯的缺陷。

在McConnell的言論發(fā)表了幾十年后,盡管經(jīng)歷了許多變化,但我們遇到的軟件質(zhì)量挫敗仍然存在:編寫可靠代碼所需的是知識和工具,但包括財務(wù),截止日期,錯誤管理,技能短缺和處理遺留代碼與系統(tǒng)的人為因素仍意味著代碼質(zhì)量的不均衡。

考慮到軟件的巨大和日益增長的重要性,bug的持續(xù)肆虐既發(fā)人深省又令人不安。實(shí)現(xiàn)最小化部署補(bǔ)丁的負(fù)擔(dān)的系統(tǒng)當(dāng)然是有幫助的,但是從源頭上提高軟件質(zhì)量才是最關(guān)鍵的。

免責(zé)聲明:此文內(nèi)容為第三方自媒體作者發(fā)布的觀察或評論性文章,所有文字和圖片版權(quán)歸作者所有,且僅代表作者個人觀點(diǎn),與極客網(wǎng)無關(guān)。文章僅供讀者參考,并請自行核實(shí)相關(guān)內(nèi)容。投訴郵箱:editor@fromgeek.com。

極客網(wǎng)企業(yè)會員

免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請進(jìn)一步核實(shí),并對任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對有關(guān)資料所引致的錯誤、不確或遺漏,概不負(fù)任何法律責(zé)任。任何單位或個人認(rèn)為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識產(chǎn)權(quán)或存在不實(shí)內(nèi)容時,應(yīng)及時向本網(wǎng)站提出書面權(quán)利通知或不實(shí)情況說明,并提供身份證明、權(quán)屬證明及詳細(xì)侵權(quán)或不實(shí)情況證明。本網(wǎng)站在收到上述法律文件后,將會依法盡快聯(lián)系相關(guān)文章源頭核實(shí),溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。

2018-12-22
他們說軟件會吃掉世界,但是Bug還沒解決掉
“9月25日周二下午,我們的工程團(tuán)隊發(fā)現(xiàn)了一個影響近5000萬個賬戶的安全問題,”Facebook的GuyRosen在公司9月份的一次安全更新中表示到。

長按掃碼 閱讀全文