他們說(shuō)軟件會(huì)吃掉世界,但是Bug還沒(méi)解決掉

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

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

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

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

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

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

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

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

memcpy(bp, pl, payload);

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

向前一步,退后兩步

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

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

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

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

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

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

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

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

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

降低代碼復(fù)雜度

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

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

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

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

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

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

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

慢編碼

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

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

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

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

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

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

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

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

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

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

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

長(zhǎng)按掃碼 閱讀全文