到了2015年,為什么我們仍然在寫不安全的軟件?(節譯)
英文原文:It's 2015. Why do we still write insecure software?
我已經看了大量編程方面的博客,如果你在看本文,那么你可能也看了很多博客。讓我預先告訴你,這不是你通常的、歸結為“再加把勁兒!”的安全論 調。讓我們討論一下聰明的、有經驗的程序員,他們正在盡量編寫安全的代碼,即使他們本身不是安全方面的“專家”。這是重要的一群人,因為世界上要寫的安全 相關的軟件,比能夠被安全專家編寫的軟件要多得多。
在一個理想的世界,假定為目標群體將結束本文。你的瀏覽器滾動條出現在全屏視圖里,本文還要繼續一段時間。唉,數十年的經驗和被訓練過的相當高的智商,對于在當前編碼環境里去編寫安全的軟件,仍然是不充分的。
這也是最高量的資歷,可能承受任意合理的規模,那么,實際上這等同于說,在當前編碼環境編寫安全的軟件是不可能的。
讓我們討論下為什么這么難。我的觀點很簡單:
我編寫不安全的軟件,因為我們的編碼環境造成的,它使得編寫不安全的軟件比編寫安全的軟件更加容易。
不過搞清楚它的真正涵義,會把你帶到一些讓人驚奇的地方。當我盡量向你展示為什么這不是一般地真實的時候,請跟著我,不過實際上,這是徹頭徹尾 地真實。我們不是偶爾使用不安全的工具,比如被破壞的加密程序、或濫用 web 框架;我們是在不安全的海洋里游動的魚兒,我們侵泡得有多深就很明顯了。
首先,我必須確認……
編寫安全的程序是有難度的
我們在工作中都有有限的感知預算。我們多么想擁有搖滾歌星或武士的神秘力量,可惜我們都不是。不管我們變得多么有經驗,用 3 個 token 而不是 100 個,以花費較少的感知預算。想少些努力而盡可能完成一個任務,這不是“懶惰”,而是認識到資源總是有限的事實。
他們需要多少感知上的努力來編寫代碼,對此去檢查一下編碼環境,這是合理的事情。用這種方式彼此比較環境,是合理的。與工具無關、唯一相關的是程序員的技能,這種想法的論調要拋棄掉,這是合理的。
(花絮:在編程界,因為某種原因,大家對于格言“笨拙的工匠才會責怪他的工具”有著通常的誤解,他們認為責怪其工具的人恰恰被證明為笨拙的工 人。這句話的真正意思是,把糟糕工具放在首位的工匠才是笨拙的。技能嫻熟的工匠不會毫無怨言地使用鈍鋸子。他們會毫無怨言地找到或做一把好鋸子。使用笨拙 工具而沒有抱怨的工匠,甚至比只是抱怨的工匠還要糟糕!)
這里我們遇到一個問題,客觀地測量一種語言所引起的認知成本,變得困難了,但是我認為,在實踐中,“token 數”足夠接近,在某種程度上這不是真實的,隨著時間的發展,它越來越真實。(不幸的是,證明這一點將在另一篇文章介紹。超短版本:按照佛瑞德·布魯克斯 【注1】的觀點,在使用的常用語言,正在擠出它們偶爾的復雜性。因此讓我再次強調:足夠接近,而非完美。)因此大體上,正如我下面要討論的“輕松”和“工 作”,你能夠想象得到我正在討論的“token 數”。
畢竟它是小型的、世界范圍內可寫的變量
讓我們溫習一個沒有爭議的例子吧,認知上昂貴的正確事情,是如何導致開發人員去做簡單的錯誤事情:全局變量。正如我之前說過的,
所有程序員口頭上都認為全局變量是糟糕的,然而神秘的是,即使沒有人寫過它,它們還是繼續出現在代碼庫和資源庫里(我譴責邪惡的代碼精靈)。
現在我將解釋為什么它們一直都出現。
(破壞者:它不是代碼精靈。它們僅僅對 tab 和空格的混雜、以及偶爾的無禮的注釋負責。)
我認為那是由于所有語言讓全局變量單獨成行,剩下的工作使得它比任何正確的工作要容易得多。
此時,文章結構似乎要讓我向你展示設定一個全局變量是多么容易的例子,但是在大部分語言里,它是如此該死地瑣碎,以致于羞于展示。但是不要說我接受的正規教育被浪費了,因此一味遵從其準則,就是:
variable = "value";
JavaScript 可以直接使用它。在 Python 里,分號是不相關的、但它能用。我懷疑只需兩到三個 token,我就能搞定大部分命令式語言。甚至對于要求更多的語言,比如 Java,和做其它事情也是一樣容易,因為不管你做什么,你將口口聲聲地說到 class。
同時,用全局值去做“正確”的事情是相當有難度的。它不得不被收集,并在各種難度的前提下傳遞,潛在地能夠深入到數百行代碼里,如果你需要修改 傳遞的類型,這就不是一個簡單的問題了,這就是證據。沒有人“想”使用全局變量,但是如果你想使它比本地“正確答案”更加便利,不管怎樣,程序員將會使用 它們。甚至 Haskell 程序員們也抵制不了這個誘惑 unsafePerformIO $ newIORef 0。
相反,在很多語言里做正確的事情,超過了本文要討論的,因為它充滿了折衷,一定也涉及了很多 token。但是既然文章結構說到了這里,這里就是我為 Go 語言做的。看看它是多么容易地去做正確的事情,我都快眼暈了,然而,不可避免地它就是這么一行。(例如,Go 里的全局變量是:
var Global = "value"
放在最頂層。一個 var token 被加上了,名字不得不以大寫字母開始。仍然比任何“環境”的使用簡單。)
我借這個機會盡量去評判這個例子中的“token 數”的標準吧。當我們衡量一種語言在語法上怎樣簡單時,我們能夠分解出“開發者能力”的問題。我們可以只是批評開發者做了錯誤選擇,我們還能批評環境,因為它使得做錯誤選擇太有誘惑。每個人都迷失了!
開始這個話題的優勢在于,很少有人愿意公開贊同全局變量,大部分人都和我一樣,認為他們更容易把事情“做對”;我傲慢地對著剩下的人揮了揮手。 在我開始有意思的討論之前,請允許我花點兒時間重述一些我在這個沒有爭議的例子中的主要論點:不管我們都知道一個剛剛好的事實,它們更容易把事情做對,這 是錯誤的,我們仍然看到了如此多的全局變量。同時這可能聽起起來還算明顯,但是請注意,此時此刻所有事情都確定了,我們都在看待相同的事物,那就是我們正 在盯著一個兔子洞。
現在請穿上你的藍衣服和白圍裙,咱們開始吧。
哦……額……只需和平時一樣,這是互聯網,我看不到你。
(譯者注:以下略去,有興趣的讀者可以自行閱讀)
- 注1:佛瑞德·菲利普斯·布魯克斯二世(英語:Frederick Phillips Brooks, Jr.,1931 年 4 月 19 日-),又譯為弗雷德里克·布魯克斯,生于美國北卡羅來納州德罕軟件工程師、學者,曾任萬國商用機器公司(即 IBM 公司或國際商務用機器公司)系統部主任,主持開發過 OS/360 等大型電腦(計算機)用的操作系統軟體。后來,布魯克斯離開 IBM 公司,任教于北卡羅萊納大學教堂山分校,擔任計算機科學 Kenan 講座教授,并著書立說。他所著的《人月神話》一書,被視為是軟件工程的重要書籍之一。為 1999 年圖靈獎得主。http://zh.wikipedia.org/wiki/%E4%BD%9B%E7%91%9E%E5%BE%B7%C2%B7%E5%B8%83%E9%AD%AF%E5%85%8B%E6%96%AF
— END —
譯文: 《到了 2015 年,為什么我們仍然在寫不安全的軟件?(節譯) 》 臘八粥
</div>