不相容的惡性循環
原文由 Marcin Wichary 于 發布,訂閱此部落格
PortalRunner 一支有趣的 16 分鐘影片,前提是這樣的:
這是一個圖檔,裡面是我貓咪的照片。但如果我把它重新命名成 .MP4,它就變成影片檔——一樣是我那隻貓。如果改成 .PDF,它就變成一份文字文件,裡面是這支影片的逐字稿。它也可以是一個有效的網頁、一個 .ZIP 壓縮檔,或是一份 PowerPoint 簡報,全部都只要改個檔名就能做到。這類檔案有時被稱為「polyglot」(雖然這個詞通常是指能在多種程式語言中執行的程式碼)。

這種檔案在現實中大概用不到,但它很有趣地展示了各種檔案格式在檔頭與結構上的不同設計——這些是我們平常不太會去思考的東西。
影片中還藏著一個有趣的岔題:副檔名難道就只是把檔案交給正確應用程式的一種方式嗎?如果我把 .jpeg 改成 .gif,而兩者都會用 Pixelmator 開啟,那麼 Pixelmator 應該要盡力在底層偵測出它其實是個 JPEG,還是應該直接跳出「這看起來不像 GIF 檔」的錯誤訊息?
網路也有類似的難題,也就是MIME 嗅探——「MIME」算是網路世界裡相當於副檔名的東西,「sniffing」則是指單純從內容本身來判斷檔案類型,其他資訊一概不理——而這帶來了一些安全上的考量,因為它讓有心人士得以把惡意程式碼偽裝成看似無害的東西混進來……基本上就是影片裡為了好玩而做的事,只是這次被武器化了。
這些對這個部落格來說都有點太技術了,不過在 MIME sniffing 的維基百科條目裡,有一段話引起了我的注意:
[MIME sniffing is still used by some browsers. However,]由於它讓那些沒有正確設定 MIME 類型的網站,在這些瀏覽器上看起來仍能正常運作,反而無法鼓勵正確標示內容,進而使得內容嗅探對這些網站的運作成為必要,形成一個與網路標準及安全最佳實務不相容的惡性循環。
早在 MIME 嗅探出現的數十年前,Jon Postel 就以波斯塔爾法則(Postel’s Law)精準捕捉了這種思維的核心——「發送時要保守,接收時要寬容」——但儘管這個想法很吸引人,它也面臨與上述引言類似的難題:
一個缺陷可能會就此根深蒂固,成為事實上的標準。任何協定的實作都必須複製這種異常行為,否則就無法互通。[……]在這種環境下確保互通性,通常被稱為追求「bug-for-bug compatible」(連錯誤都要一模一樣地相容)。
雖然波斯塔爾法則談的是電腦系統中資料的流入與流出,但對我而言,它背後的前提是一個更歷久不衰的設計問題,可以套用到許多其他事物上。抱持「接收時寬容」的態度,感覺上很貼心,卻可能讓使用者養成壞習慣,並帶來更大的後果。對於任何適用這個原則的專案,都值得問問自己:我們該不該費盡心思去幫使用者收拾殘局,即使是他們自己搞砸了,還是應該更嚴格一點、教他們更確實地遵守規則,因為這對他們的未來更有好處?
Command Line Interface Guidelines是我之前介紹過的,裡面就有一個很棒的例子:
你可以詢問使用者是否要執行建議的指令,但不要幫他們強制執行。例如:
$ heroku pss
› Warning: pss is not a heroku command.
Did you mean ps? [y/n]:
與其建議修正後的語法,你可能會想乾脆直接幫他們執行,就當作他們一開始就打對了一樣。有時候這樣做是對的,但並非總是如此。首先,無效的輸入不一定只是單純的打字錯誤——它往往可能代表使用者犯了邏輯上的錯誤,或是誤用了 shell 變數。擅自揣測使用者的本意可能是危險的,尤其當接下來的動作會改變狀態時。
其次,要注意,如果你擅自改動使用者輸入的內容,他們就學不到正確的語法。實際上,你等於是在認定他們那樣輸入是有效且正確的,並且承諾要永遠支援那種寫法。做這個決定時要審慎,並且把兩種語法都記錄下來。
隨機一篇部落格
留言
登入後參與討論