許多網路應用程式都需要顯示使用者控制的內容。這類內容可能很簡單,例如提供使用者上傳的圖片 (例如個人資料相片),也可能很複雜,例如算繪使用者控制的 HTML (例如網頁開發教學課程)。安全地執行這項操作一直很困難,因此我們致力於尋找簡單但安全的解決方案,適用於大多數類型的網路應用程式。
隔離不受信任內容的傳統解決方案
安全放送使用者控管內容的傳統解決方案是使用所謂的沙箱網域。基本概念是,如果應用程式的主網域是 example.com,您可以在 exampleusercontent.com 上提供所有不受信任的內容。由於這兩個網域是跨網站,exampleusercontent.com 上的任何惡意內容都不會影響 example.com。
這種方法可用於安全地提供各種不受信任的內容,包括圖片、下載內容和 HTML。雖然圖片或下載內容似乎不需要使用這項功能,但這麼做有助於避免內容嗅探帶來的風險,尤其是在舊版瀏覽器中。
沙箱網域在業界廣為使用,且長期以來運作良好。但這類方法有兩大缺點:
- 應用程式通常需要限制單一使用者存取內容,因此必須實作驗證和授權。由於沙箱網域不會與主要應用程式網域共用 Cookie,因此很難安全地執行這項操作。如要支援驗證,網站必須依賴功能網址,或為沙箱網域設定個別的驗證 Cookie。在現代網路中,許多瀏覽器預設會限制跨網站 Cookie,因此第二種方法特別容易出問題。
- 使用者內容會與主要網站隔離,但不會與其他使用者內容隔離。這會造成風險,惡意使用者內容可能會攻擊沙箱網域上的其他資料 (例如讀取相同來源的資料)。
此外,沙箱網域有助於降低網路釣魚風險,因為資源會明確區隔到獨立網域。
提供使用者內容的現代化解決方案
隨著網路演進,現在有更簡單、更安全的方式提供不受信任的內容。這方面有很多不同的做法,因此我們將說明 Google 使用的兩種解決方案。
方法 1:提供非活躍使用者內容
如果網站只需要提供非使用中使用者內容 (也就是非 HTML 或 JavaScript 的內容,例如圖片和下載項目),現在可以安全地執行這項操作,不必使用獨立的沙箱網域。主要有兩個步驟:
- 請務必將
Content-Type標頭設為所有瀏覽器都支援的知名 MIME 類型,且不含動態內容。不確定時,建議選擇application/octet-stream。 - 此外,請務必設定回應標頭,確保瀏覽器完全隔離回應。
| 回應標頭 | Purpose |
|---|---|
X-Content-Type-Options: nosniff |
防止內容嗅探 |
Content-Disposition: attachment; filename="download" |
觸發下載而非轉譯 |
Content-Security-Policy: sandbox |
將內容放入沙箱,如同內容是在其他網域上提供一樣 |
Content-Security-Policy: default-src ‘none' |
停用 JavaScript 執行作業 (並排除任何子資源) |
Cross-Origin-Resource-Policy: same-site |
禁止在跨網站中加入網頁 |
這組標頭可確保回應只能由應用程式載入為子資源,或由使用者下載為檔案。此外,透過 CSP 沙箱標頭和 default-src 限制,標頭可提供多層防護,防範瀏覽器錯誤。整體而言,上述設定可確保以這種方式提供的回覆不會導致注入或隔離漏洞。
縱深防禦
雖然建議的解決方案通常足以防範 XSS,但您仍可採取多項額外的強化措施,提供額外的安全層級:
- 設定
X-Content-Security-Policy: sandbox標頭,確保與 IE11 相容。 - 設定
Content-Security-Policy: frame-ancestors 'none'標頭,禁止內嵌端點。 - 在隔離的子網域中,以以下方式將沙箱使用者內容設為安全:
- 在獨立子網域上放送使用者內容 (例如 Google 使用
product.usercontent.google.com等網域)。 - 將
Cross-Origin-Opener-Policy: same-origin和Cross-Origin-Embedder-Policy: require-corp設為啟用跨來源隔離。
- 在獨立子網域上放送使用者內容 (例如 Google 使用
方法 2:提供活躍使用者內容
您也可以安全地提供動態內容 (例如 HTML 或 SVG 圖片),且不會有傳統沙箱網域方法的缺點。
最簡單的做法是利用 Content-Security-Policy: sandbox 標頭,指示瀏覽器隔離回應。雖然並非所有網頁瀏覽器都會為沙箱文件實作程序隔離功能,但持續改良瀏覽器程序模型,可望提升沙箱內容與嵌入應用程式的分離程度。如果 SpectreJS 和渲染器遭入侵攻擊不在您的威脅模型中,使用 CSP 沙箱可能就足夠。Google 開發的解決方案可透過現代化沙箱網域的概念,完全隔離不受信任的動態內容。核心概念如下:
- 建立新的沙箱網域,並加入公開尾碼清單。舉例來說,只要在 PSL 中加入
exampleusercontent.com,即可確保foo.exampleusercontent.com和bar.exampleusercontent.com是跨網站,因此彼此完全隔離。 - 凡是與
*.exampleusercontent.com/shim相符的網址,都會一律導向靜態墊片檔案。這個墊片檔案包含簡短的 HTML 和 JavaScript 程式碼片段,可監聽message事件處理常式,並轉譯收到的任何內容。 - 如要使用這項功能,產品會建立 iframe 或對話方塊,並使用
postMessage將不受信任的內容傳送至墊片以進行算繪。$RANDOM_VALUE.exampleusercontent.com/shim - 系統會將算繪的內容轉換為 Blob,並在沙箱 iframe 中算繪。
相較於傳統的沙箱網域做法,這種做法可確保所有內容完全隔離在專屬網站上。此外,由於主要應用程式會處理要算繪的資料擷取作業,因此不再需要使用功能網址。
結論
這兩項解決方案可協助您從 googleusercontent.com 等傳統沙箱網域遷移,改用與第三方 Cookie 封鎖功能相容的更安全解決方案。Google 已將許多產品遷移至這些解決方案,並計畫在明年進行更多遷移作業。