該如何寫出更好的軟體?─ 系列訪談之二 (下)

此為 Mozilla Hacks  部落格的新系列訪談之二。如果你才剛看到這篇文章,當然不要錯過《該如何寫出更好的軟體?─ 系列訪談之二 (上)》與《(中)》篇。

網路安全是大家都應該注重的要點。(圖片來源:networkperformance.info)

網路安全是大家都應該注重的要點。(圖片來源:networkperformance.info)

Web 上有哪些常見問題違反了這些原則?

特別說到 Web 這個很有趣的環境。我們傾向使用記憶體安全的程式語言。

你指的是 Python 與JavaScript 嗎?

是的,我們想使用更物件導向、更獨立/隔離的東西。我在網路上發現的主要問題,就是沒有針對使用者的輸入進行驗證或清理;或沒有避免像是隱碼攻擊 (Injection attack) 的東西。

你已經算是程式碼審閱老手,例如「Persona」就曾由你負責審查。你自己在前、後端最常發現哪些問題?

大概就是跳脫特殊字元的部份 (escaping)、假設資料來源,還有一旦出現瑕疵,惡意駭客所能掌握的程度為何。

這也是你倡導能輕鬆追蹤系統內資料流向的理由嗎?

是的!如此能找出某部分的程式碼,透過背景執行的幾行簡易碼來看看一部分連線的元件,接著追蹤回實際上是由使用者所提交的參數。這樣不是很簡單明瞭嗎?你也可藉此知道駭客的掌握度,又能做到哪些出乎我們意料之外的事。當然,其簡易程度、透明/可見度、可追蹤的分析作業等都是關鍵。

要如何才能簡化資料流向的審查作業?

我想首先應該先把程式碼不同區塊之間的互動降至最低。讓各個區塊只負責小範圍的功能。

「多重防禦 (Defence in depth,DID)」到底是什麼?開發者又該如何在系統中使用?

只能說有點像是「皮帶與吊褲帶 (Belt and suspender)」的概念。如果一個地方出錯,至少還有其他部分可隨時頂上。但你如果同時穿著吊褲帶又繫著皮帶,看起來就有點傻。這兩樣東西雖然同樣是用來固定你的褲子,但其實是各自獨立的東西。有時候腰帶會斷;有時是吊褲帶脫落。不過這兩樣東西都能避免你當街出糗。所以 DID 一般是用以提醒「不要只依靠周邊安全 (Perimeter security)」。

意思是你應該檢查整個系統的資料嗎?

效能成本 (或稱複雜度成本) 往往都有其判斷準則。如果你的程式碼滿是完整性檢查 (Sanity checking),那麼閱讀你程式碼的人都會無法專心尋找真正產生功能的地方。如此將限制他們無法了解你的程式碼,也就無法正確使用程式碼並滿足需求。

根據周邊安全的概念,你很容易在程式外圍畫地自限,然後宣稱「在外面的都是壞人,裡面的才是好人」,接著在界線上搭建所有必要的防禦系統,而內部卻沒有其他機制。我曾和其他人討論過這個情形,他們認為是生物學與社會學演進的結果。某個部落內的人們彼此之間都有著血親關係。假設一個部落共有一百人,且各個部落互相獨立且距離甚遠。那麼基本規則就是你會相信血親,而到其他沒有血緣關係的部落出草。

這種情況可以相安無事一陣子,但你的社會結構必須保持一百人以內。我們把這個條件套用到電腦上:試想有「好人」與「壞人」,而我只要抵禦壞人。但我們並無法在網路上分辨這兩種人,而且好人偶爾也會犯錯。所以我們使用「最低權限 (Least authority) 原則」和「採用獨立軟體元件」的想法,再儘量限縮元件之間的互動。如果因為某人刻意毀損元件,或使元件進行意料之外的行為,或元件單純發生問題,就能夠控管傷害範圍。

你自己有特別可供他人觀摩學習的程式碼片段嗎?

我想可稍微拿出來炫耀的,應該就是我為 Tahoe-LAFS 所撰寫的 core share-downloading 迴圈吧。

在 Tahoe,檔案均上載到許多部分冗餘 (Partially-redundant) 的「分享」檔案;這些檔案也分配到多組伺服器上。以後你如果要下載檔案,只要取得「分享」的子集就可;如此可容忍多組伺服器發生錯誤的情況。

「分享」檔案包含許多保護完整性 (Integrity-protecting) 的「Merkle hash trees」,可協助檢驗你下載中的資料。而這些雜湊的位置並無法提前知道 (我們並沒有明確指定配置方式,所以其他實作的排列也有所差異)。但我們想以最少的資料來回 (Round-trips) 達到快速下載,所以我們猜測其位置並提取 (Fetch) 之。如果猜錯了,我們就會猜第二次並提取更多資料。

此程式碼很努力要提取最少的資料,因此使用壓縮過的資料 (bitmap,其中記錄了我們所要提取的位元組;希望這些就是正確的資料) 集合,也有我們真正需要或已經下載的位元組,並針對正確的位元組送出請求。

這個演算法讓我知道的另一件事,就是它太聰明了。在我們釋出之後才發現它的速度,其實比它取代的初階程式碼還要慢。「幾個大型區塊 (即使你提取了超乎自己需要的更多資料)」的讀取速度,高於「多個小型區段 (即使包含網路與磁碟 I/O 負載)」的讀取速度。我另外執行一系列的效能測試想找出問題,也打算下次要設法測得新演算法的速度。

你想推薦大家參與哪個開放源碼專案呢?

我個人興趣在於安全通訊工具,所以也想推薦大家 (特別是設計師與 UI/UX 工程師) 能進一步了解「Pond」、「TextSecure」,還有我自己的「Petmail」等工具。我也很高興現在有像是「GNU FreedomBox」,這種能讓你在家裡架設自己伺服器的系統。

大家要如何隨時了解你現正進行的事情呢?

你可隨時留意我在 https://github.com/warner 上的留言。我自己的東西幾乎都放在這上面了。

訪談逐字稿

Brian 和我發現單是一篇部落格文章,實在不足以提供所有素材。你也可到 GitHub 找到完整逐字稿,內含記憶體安全語言、撰寫 HTML 時的隱式型態轉換 (Implicit type conversion),以及 Brian 他自己常用的 Python 工具。

接下來的內容

下一篇訪談將介紹 Yvan Boiley 與 Peter deHaan 兩位。Yvan 會繼續為我們解說安全方面的主題。他本人負責帶領 Cloud Services Security Assurance 團隊,並將討論該團隊的安全檢查方式,並介紹網站常見問題的自我檢核工具;。

Peter 則是 Mozilla 的品質控管 (Quality Assurance,QA) 工程師之一,負責 Firefox Accounts 的運作無虞。Peter 將討論專案所使用的警告標示、程序、工具。

 

 

原文連結:How can we write better software? – Interview series, part 2 with Brian Warner

 

 

您可能也會喜歡

目前找不到相關文章

共 1 則讀者回應

  1. 參照: 該如何寫出更好的軟體?─ 系列訪談之二 (中) | 部落格 | Mozilla Taiwan

對此文章發表回應

你的電子郵件位址並不會被公開。 必要欄位標記為 *