Clojure的web安全比你想象的還要差
ClojureWest大會結束了,
Aaron Bedra發表了題為
Clojure.web/with-security的演說。如果你用Clojure開發web應用程式,你必須看這個視訊。現在就看。
這篇部落格綜合了Aaron的講話筆記和一些我自己的想法。
有多差?
“Clojure web應用程式是我曾經見過的、在安全方面做得最差的。”
“……像PHP級别……沒有架構級别,安全。”
—Aaron Bedra
Aaron宣稱,根據可供選擇的類庫來倒騰你自己的(web)棧,這種Clojure思想方法導緻了系統級的安全問題。我們有碎片,但是沒有把它們組合成一個強健的、可靠的架構。相反,開發者挑選不同的類庫,不是所有的類庫都提供了完整的覆寫或健全的安全預設項。
密碼管理
password/crypt相關操作的前三名類庫(
crypto-password,
friend和
lib-noir)不支援HMAC,不需要逐個更新就可以實作從一個模式遷移(MD5到SHA1到……),通常具備有限的選項。
Aaron推薦的不是要有多個選項可供選擇,而是Clojure社群緻力于一個(他推薦crypto-password),讓friend和lib-noir依賴它。我認為這是明智的想法。
會話管理
Clojure web應用程式通常依賴Ring處理會話管理。Ring不能提供持久會話管理(基于資料庫,儲存/驗證合法的會話cookie)來阻止重播攻擊(replay attack),會話cookie不能預設成http only辨別(允許XSS攻擊盜取cookie)。
對于Ring而言,安全的會話管理隻有非常少量的、被證明過的最佳實踐。
身份驗證
類庫就是基于Ring的web應用程式在身份驗證管理上的、事實上的類庫,它基本滿足了。不幸的是,friend不支援更加複雜的身份驗證政策,在基于Ring之外的情況下就表現不好了。
我們不要用你自己的獨立身份驗證類庫來填補這個空白,而應該回報給friend。這裡我被人提醒了Ruby的
omniauth。
XSS
數量龐大的Clojure HTML模闆類庫提高了持續防護XSS攻擊的難度(轉義HTML标簽,控制标簽被轉義或不被轉義)。
最終有太多的可供選擇的模闆類庫。開發組應該挑選一個并堅持用下去。在選擇一個模闆類庫時,要把XSS控制的支援做為一個考慮因素。
安全頭
在Clojure web應用程式,沒有集中的類庫來居中管理安全頭。安全頭可以在Ring裡手動設定,但是你不得不知道配置的正确位置。Aaron指出,Ruby的
secureheadersgem就是Clojure所需的一個例子。
更新:Dhruv Chandna已經為其Ring中間件類庫推出了一個更新,增加了安全頭:ring-secure-headers。做得不錯!随後我會詳細研究的。
總結
我的結論:開發安全性高(參考
OWASP Top Ten List of Security Issues OWASP Testing Guide)的Clojure web應用程式是幾乎不可能的,當你決定這樣做的時候,是很痛苦的。
建立安全的Clojure web應用程式需要更加容易點兒、需要內建了安全的架構,而不是孤立的類庫!我們已經有了一些标準部件(crypto-password,friend),但是更大的開發和內建仍然是有必要的。