一個(gè)有趣的小Bug避免了一場(chǎng)大災(zāi)難
我要講述的這個(gè)故事是,在一個(gè)下午,視頻游戲中的小bug造成的故障,如何促使我去清除來(lái)自于軟件的潛在危險(xiǎn)漏洞,而該軟件被來(lái)自于世界各地的企業(yè)和政府使用,這么還讓我明白了一個(gè)實(shí)踐教訓(xùn),即你為什么要將代碼中發(fā)現(xiàn)的問(wèn)題報(bào)告上去,即使一開(kāi)始它們看上去那么微不足道。
這一切都始于這個(gè)秋天一個(gè)下午,我正在哈佛商學(xué)院上關(guān)于創(chuàng)業(yè)的本科課程。我們正在學(xué)習(xí)如何用小組的形式來(lái)有效地工作,途徑是通過(guò)參與一個(gè)商學(xué)院的模擬游戲,這個(gè)模擬游戲是用來(lái)教授團(tuán)隊(duì)協(xié)作專業(yè)管理課程的。
我們被分為五組,并被告知我們的目標(biāo)是共同努力作為一個(gè)團(tuán)隊(duì)登頂一座山峰。此外,還給了我們每個(gè)人到模擬網(wǎng)站的鏈接,一旦我們登錄網(wǎng)站,里面就會(huì)有 一個(gè)屏幕告訴我們,我們?cè)谶@個(gè)團(tuán)隊(duì)中需要扮演的獨(dú)特角色。一個(gè)是領(lǐng)導(dǎo)者,一個(gè)是經(jīng)驗(yàn)豐富的登山者,一個(gè)是醫(yī)護(hù)人員,而我則是極其有用的環(huán)境保護(hù)者,嘿嘿
從根本上而言,模擬是一個(gè)老式的、回合制的菜單游戲,用Javascript和HTML在瀏覽器中實(shí)現(xiàn)。就像是《龍與地下城》的高級(jí)訓(xùn)練版本,在每 個(gè)回合中,每個(gè)玩家都需要對(duì)往山上的哪里走,以及如何使用他們的設(shè)備做出選擇。完成共同的團(tuán)隊(duì)目標(biāo)和特定個(gè)人目標(biāo)還可以獲得積分(我的目標(biāo)自然就是通過(guò)清 理山上的垃圾來(lái)保護(hù)自然了,哈哈)。
整個(gè)游戲是通過(guò)網(wǎng)站上的一系列表格運(yùn)行的,但除此之外,還有一個(gè)一直保持在頁(yè)面頂部的對(duì)話框,它允許你直接發(fā)送即時(shí)消息給其他玩家,或整個(gè)團(tuán)隊(duì)。當(dāng)我的隊(duì)友對(duì)虛擬用品產(chǎn)生爭(zhēng)執(zhí)時(shí),我開(kāi)始擺弄對(duì)話框,并很快意識(shí)到,它會(huì)換碼任何我輸入的HTML。
這意味著,我可以通過(guò)跨站點(diǎn)腳本,對(duì)任意我的隊(duì)友的模擬頁(yè)面運(yùn)行我想要的Javascript代碼(如果你不知道跨站點(diǎn)腳本以及為什么換碼HTML的重要性,那么我極力推薦這個(gè)視頻)。
因?yàn)橛辛诉@個(gè)新的權(quán)力,于是我發(fā)送代碼給我的隊(duì)友們——在他們的屏幕上彈出消息,通知他們?nèi)绻謇砩缴系睦?,就?huì)有獎(jiǎng)勵(lì)積分,以及扮演醫(yī)護(hù)人員角 色的人(特別好斗)并不需要登上山頂。我們很快就收集好了虛擬垃圾,同時(shí)也放棄了醫(yī)護(hù)人員。我置身于模擬游戲之外,轉(zhuǎn)而讓我的隊(duì)友們互相競(jìng)逐積分,并陶醉 在隨之而來(lái)的混亂中。
利用模擬網(wǎng)站中的bug,我制造了很多混亂(當(dāng)然所有的混亂又都是有趣的),但這絕非嚴(yán)重問(wèn)題。因?yàn)閱?wèn)題內(nèi)置于游戲,所以即便是最壞的情況,心思不 正的學(xué)生也只能用來(lái)干擾同學(xué),而不能用它來(lái)竊取重要信息,也不能像其他著名的跨站腳本漏洞一樣劫持帳戶。我琢磨著,創(chuàng)造這個(gè)游戲的商學(xué)院教授,后期將這個(gè) 網(wǎng)站等的所有事宜都扔給了一個(gè)學(xué)生去做,而這個(gè)學(xué)生則匆匆忙忙地在一個(gè)喝著咖啡熬夜的夜晚,因?yàn)槭韬龆z漏了這個(gè)bug。
我本來(lái)可以就此放手,隨它去,但我一想到,如果有這樣一個(gè)漏洞在我寫的代碼中,我會(huì)希望別人能夠告訴我。所以,我決定負(fù)責(zé)到底,在課后報(bào)告bug。
這就是事情變得有趣的地方了。
我寫了一封電子郵件給哈佛商學(xué)院出版社,因?yàn)樗鼡碛杏螒虻某霭鏅?quán)。我告訴他們,我在這個(gè)軟件中找到了一個(gè)跨站點(diǎn)腳本問(wèn)題,然后他們要求我能夠與他們 負(fù)責(zé)維護(hù)模擬優(yōu)秀的人接觸,這樣以便于我告知他們漏洞的細(xì)節(jié)。他們告訴我,此模擬實(shí)際上是由第三方軟件開(kāi)發(fā)公司創(chuàng)建的,他們會(huì)把我提供的消息告知這個(gè)第三 方軟件開(kāi)發(fā)公司,以便于該開(kāi)發(fā)公司可以直接跟進(jìn)。
好吧,事情跟我想得不大一樣。bug不是由粗心學(xué)生引進(jìn)的,它的始作俑者是一家專業(yè)公司里的專業(yè)開(kāi)發(fā)人員。
現(xiàn)在,你可能會(huì)想,這有什么大不了的呢?這只是一個(gè)游戲而已。就算有里面有bug,也不會(huì)導(dǎo)致什么不好的事情。問(wèn)題不在于游戲有bug,問(wèn)題在于, 當(dāng)一個(gè)專業(yè)的軟件公司犯了這樣的錯(cuò)誤時(shí),往往不會(huì)是一次性的。很有可能這家公司所使用的質(zhì)量保證流程,根本不能捕捉這個(gè)這個(gè)bug,于是乎,他們甚至有可 能正在將這段缺陷代碼用于其他客戶的項(xiàng)目中,從而導(dǎo)致更多的安全漏洞。
我等了兩個(gè)星期,也沒(méi)有收到那家公司任何有關(guān)的后續(xù)郵件,因此我給哈佛商學(xué)院出版社發(fā)了另一條消息,想要知道這家公司的名字以及負(fù)責(zé)人的聯(lián)系方式。然后出版社告知了我這家公司的名稱以及公司CTO的郵件地址。
幸運(yùn)的是,當(dāng)我告知CTO bug的時(shí)候,他非常敏銳地認(rèn)識(shí)到了問(wèn)題的嚴(yán)重性,快速跑去驗(yàn)證并解決問(wèn)題。他證實(shí)了公司通過(guò)使用由一系列通用工具和模 塊組成的平臺(tái)來(lái)創(chuàng)建軟件,這意味著他們會(huì)天然地復(fù)制組件,例如不同產(chǎn)品中的即時(shí)通訊系統(tǒng),但他向我保證,所有的bug實(shí)例都會(huì)被修復(fù)。
由于這家公司通過(guò)重用模塊來(lái)創(chuàng)建軟件,因此在其產(chǎn)品中的任何一個(gè)問(wèn)題都很有可能存在于其他很多產(chǎn)品中,作為缺陷代碼被重用。此外,事實(shí)證明該公司使 用該平臺(tái)并不只是為學(xué)校教育構(gòu)建了模擬軟件。他們還開(kāi)發(fā)了為“世界各地的企業(yè)和政府機(jī)構(gòu)”提供共享和可視化數(shù)據(jù)的軟件,并期望通過(guò)瀏覽他們網(wǎng)站的“案例” 部分,許多他們面向業(yè)務(wù)的應(yīng)用程序趨向于囊括用戶之間的消息功能。這意味著,我們課堂軟件中的那個(gè)低風(fēng)險(xiǎn)bug,可能會(huì)成為實(shí)時(shí)應(yīng)用程序處理政府或企業(yè)的 敏感數(shù)據(jù)時(shí)的高風(fēng)險(xiǎn)bug,導(dǎo)致消息系統(tǒng)易受攻擊。
每一個(gè)程序員都會(huì)犯錯(cuò),而且像這樣的跨站點(diǎn)腳本問(wèn)題是不可避免的。質(zhì)量保證流程可能會(huì)錯(cuò)過(guò)類似于這樣的bug,原因或許是因?yàn)閳F(tuán)隊(duì)正火燒眉毛地沖刺最后的截止時(shí)間,所以 規(guī)避質(zhì)量保證能為他們爭(zhēng)取時(shí)間,而且他們的代碼將在系統(tǒng)的低風(fēng)險(xiǎn)部分使用。但是,如果你正在構(gòu)建軟件模塊化它,然而卻沒(méi)有重新測(cè)試缺陷組件,就把它用到了 其他地方,從而讓其他地方也出現(xiàn)安全隱患,就可能會(huì)造成實(shí)實(shí)在在的災(zāi)難。
當(dāng)然,不要誤解我的意思,我并不是說(shuō)重用代碼不好,重用代碼是一件了不起的事情,它能讓我們更快速地構(gòu)建系統(tǒng),而且通常正確率更高。這個(gè)真實(shí)的故事 告訴我們,得益于重用代碼的巨大好處,因此幾乎我們使用的所有軟件都不可能存在于真空中,同時(shí)一個(gè)無(wú)聊游戲中的bug實(shí)際上可能也會(huì)導(dǎo)致嚴(yán)重的系統(tǒng)漏洞, 防微杜漸,刻不容緩。
譯文鏈接:http://www.codeceo.com/article/little-bug-avert-disaster.html
英文原文:How Finding a Fun Little Bug Can Avert Disaster