若 Firefox 開發延伸套件時,應該會知道 Firefox 對於外掛並沒有安全防護機制的,只要你能裝進系統,大約就可以使用所有的元件或存取系統資源。延伸套件被視為可信賴的軟體,開發者應負起各延伸套件的安全性。
對此,Firefox 在 Java Script 開發環境的安全設計主要分為賦權與未賦權的兩種安全模式。賦權的環境中,軟體可以存取所有的 XPCOM,沒有任何限制,於是它可以讀取或修改使用者的歷史紀錄、Cookie 等,甚至存取所有系統檔案。而 non-privileged 則僅提供限制嚴格的 HTML DOM API 權限,Script 的存取也依照其網址與網域名稱給予嚴格限制,避免 XSS 或本地檔案讀取等安全問題發生。
無論是外部的網頁,或者是 XUL 軟體,都是使用 XML/HTML/Java Script/CSS 來撰寫,因此概念上都是由 Window 載入 XML 文件,並透過 Java Script 來存取 DOM API。
開發延伸套件時,凡是在 XUL Overlays 或 XPCOM Components 中的程式碼,都是給予完全的存取權限。而從外部網頁載入的內容,應該給於其未賦權的權限。這種安全模式的設計,乃是防止網頁上的程式可以任意存取系統資源,是一道安全保護牆。
由於 Mozilla 社群並未對安全模式定義名詞,這裡暫區分稱呼如下兩種安全模式
- Web content document (non-privileged)
- Chrome document (privileged)
各個程式的安全模式可依照該載入網址作區別,例如 chrome:// 有完全權限、http://example.com 則可存取 example.com、file:/// 則可存取本地檔案。
你也可在利用 PrivilegeManager 詢問使用者後存取 XPCOM 或者讓 XMLHttpRequest 跨網域存取。除了預設依照網址判斷外,開發者可以設計不同的內容使用安全模式,開發者可以決定直接載入網路資料後在 Chrome Document 中執行,或者利用 type=”content” 之方式使其載為 web content document.
但是剪下貼上是一個開發者都會犯的錯誤,最常見的錯誤之一就是直接把外面抓回來的資料,用 innerHTML 直接塞進 chrome document 中。有時候資料中會含有一些 java script,雖然 <script /> 中的語法不會被執行,但是 <img onerror=”alert(‘xss’)”> 這種程式碼還是會被觸發,外部資料中夾帶程式碼的狀況還是相當多,因此凡是處理外部連結都要小心。
Security Assessment 的 Roberto Suggi Liverani 與 Nick Freeman 在上個月初於印度舉辦的 SecurityByte & OWASP AppSec Conference 中,與今年年中的 DefCon 17,發表了幾個 Mozilla 上的零時差漏洞。根據他們的文章與簡報,最常見的就是如 RSS Feeds 中的 <description> 的程式碼會被觸發執行、或者像是 FireFTP 1.1.4 以下的版本,會執行伺服器上的歡迎頁面。或者是熱門的 ScribeFire 3.4.3 以下版本,會以 chrome document 執行 <img onLoad=”alert(‘xss’)”>。
避免這些錯誤的方法之一是盡量使用 DOM manipulation methods 來塞入內容。在 Security best practices in extensions 一文中,講解了數個開發安全延伸套件的方法與注意事項,像是無論如何得執行他人的 Script,那就用 evalInSandbox 來執行。
另外你若得在兩種安全模式間互傳資料,正確的作法應該是盡量利用 DOM Event.