許多網路應用程式需要顯示由使用者控管的內容,方法非常簡單,只要提供使用者上傳的圖片 (例如個人資料相片) 或編寫複雜的 HTML (例如網路開發教學課程) 即可。難以安全地達成這個目的,因此我們不斷努力,尋找簡單又安全的解決方案,並將其應用於大多數的網路應用程式。
用來隔離不受信任內容的傳統解決方案
如要安全地提供使用者控管的內容,典型的解決方案就是使用「沙箱網域」。基本概念是,如果您的應用程式的主要網域為 example.com
,您就可以在 exampleusercontent.com
上提供所有不受信任的內容。由於這兩個網域為「跨網站」,因此 exampleusercontent.com
上的任何惡意內容都不會影響 example.com
。
這個方法可用來安全地提供各種不受信任的內容,包括圖片、下載內容和 HTML。儘管這可能不是必要用於圖片或下載內容,但這樣做有助於避免內容探查 (尤其是舊版瀏覽器) 的風險。
沙箱網域已廣泛用於業界,且使用長期下來。但有兩個主要缺點:
- 應用程式通常需要對單一使用者限制內容存取權,因此會需要驗證及授權。由於沙箱網域刻意不會與主要應用程式網域共用 Cookie,因此要安全地進行這項作業。為支援驗證功能,網站必須使用功能網址,或是必須為沙箱網域設定個別的驗證 Cookie。許多瀏覽器預設會限制跨網站 Cookie,這在現代網路中格外造成問題。
- 雖然使用者的內容與主網站之間有所區隔,但並未與其他使用者內容區隔開來。這可能會導致惡意使用者的內容攻擊沙箱網域上的其他資料 (例如透過讀取相同來源的資料)。
另外值得注意的是,由於資源清楚區隔至獨立的網域,沙箱網域有助於降低網路釣魚風險。
提供使用者內容的現代化解決方案
網路的發展日新月異,現在使用者能以更簡便、更安全的方式,提供不受信任的內容。貴公司有許多不同的做法,以下將概述 Google 目前廣泛採用的解決方案。
方法 1:提供不活躍的使用者內容
如果網站只需要提供無效使用者內容 (非 HTML 或 JavaScript 的內容,例如圖片和下載項目),現在不需要隔離的沙箱網域就可以安全進行此作業。有以下兩個重要步驟:
- 請務必將
Content-Type
標頭設為所有瀏覽器支援的知名 MIME 類型,而且保證不要包含有效內容 (如有疑問,application/octet-stream
是安全的選擇)。 - 此外,請一律設定下列回應標頭,以確保瀏覽器能完全隔離回應。
回應標頭 | 目的 |
---|---|
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 或彈出式視窗至
$RANDOM_VALUE.exampleusercontent.com/shim
,並使用postMessage
將不受信任的內容傳送至填充碼進行算繪。 - 轉譯的內容會轉換成 Blob,並在沙箱的 iframe 中轉譯。
與傳統的沙箱網域方法相較,這個方式能確保所有內容都能在一個專屬網站上完全隔離。此外,由於主要應用程式會擷取要轉譯的資料,因此不再需要使用功能網址。
結論
這兩個解決方案搭配使用,能讓您從 googleusercontent.com
等傳統版沙箱網域,遷出更安全且與第三方 Cookie 封鎖功能相容的解決方案。Google 已經為許多產品改用這些解決方案,並預計明年展開更多遷移作業。