容器分頁只隔離 Cookie 與網站儲存空間,並不隔離裝置本身;本文說明容器真正隔離了什麼、哪些訊號完全不變,以及跨容器仍會被追蹤到的原因。
Firefox 正把容器分頁(container tabs)收編進瀏覽器本體——過去得靠 Multi-Account Containers 這款擴充功能才能做到的功能,如今正變成內建的原生選項。這正是一個好時機,把「容器到底做了什麼」這件事講清楚,因為多數人腦中的心智模型都錯得相當關鍵:容器是一個獨立的Cookie 罐,不是一個獨立的瀏覽器。以下所有內容都建立在這一個區別之上——如果讀者誤以為並非如此,就會把容器信任成一個它從來就不是為此而生的工具。
核心要點
- 容器是一個獨立的 Cookie 罐,不是獨立的瀏覽器實體——MDN 的
contextualIdentities參考文件講得很直白:「每個身分都會取得一個不與其他分頁共用的 Cookie 儲存區。」在 Firefox 上,這道隔離也一併延伸到網站的其他儲存空間。 - 儲存層以下的一切都是共用的:你的 IP 位址、TLS/HTTP/2 交握特徵、Canvas/WebGL/音訊輸出、已安裝字型、螢幕參數與時區,在同一個瀏覽器的每個容器裡都完全相同。
- 靠指紋辨識的追蹤者只會看到一個訪客,而不是兩個——對讀取 Cookie 的網站來說像是兩個不同身分的容器,一旦網站改用指紋而非儲存空間來辨識,就會立刻被合併回同一份檔案。
- 容器確實能擋下依賴 Cookie 串接的跨站身分辨識:仰賴共用 Cookie 罐的登入狀態探測與重新導向式追蹤,一旦 Cookie 罐被拆成互相隔離的多個,就失去了賴以運作的基礎。
- 容器只是一整個隔離工具家族裡的一員——隱私視窗、獨立瀏覽器設定檔、VPN,各自隔離的是不同的層級,而搞混某個工具究竟隔離了哪一層,正是大家對自己的防護過度信任最常見的原因。
容器實際上分割了什麼
Firefox 的情境身分(contextual identities)功能——也就是 Multi-Account Containers 背後的機制,如今也是原生容器背後的機制——會替每個分頁指派一個容器身分,並把網站儲存空間依這個身分建立索引。MDN 的 contextualIdentities API 參考文件對儲存這一半講得很精確:「在內部,每個身分都會取得一個不與其他分頁共用的 Cookie 儲存區」,並以 cookieStoreId 定址。在 Firefox 中,容器 id 會隨著「來源屬性(origin attributes)」一起附在儲存請求上,所以實際被拆開的不只有 Cookie——localStorage、IndexedDB 以及網站的其他儲存空間,同樣會依容器落進不同的桶子裡。
在「工作」容器和「個人」容器裡分別開啟同一個網站,網站看到的會是兩個完全獨立的儲存空間——一邊設定的 Cookie 不會外洩到另一邊,在其中一個容器裡開始的登入工作階段,也不會延續到另一個容器。
有一件事必須跟上面分清楚:Firefox 還會沿著另一條完全不同的軸線分割狀態。MDN 的狀態分割(State Partitioning)指南描述的是瀏覽器如何「依所載入資源的來源(origin)與頂層網站(top-level site)對所有用戶端狀態進行雙重索引」——涵蓋儲存類 API(localStorage、sessionStorage、IndexedDB、Service Worker)與網路狀態(HTTP 快取、圖片快取、DNS、TLS 工作階段識別碼、HSTS)。那份文件談的是跨站隔離,索引鍵是網址列上的那個網站,它完全沒有提到容器。在 Firefox 上這兩套機制是同時運作的,而且誰也取代不了誰:一套擋的是追蹤者跨網站跟著你走,另一套擋的是你自己的幾個身分互相看見。
但不論走哪一條軸線,這兩套機制都停在儲存層。它們是真實而有用的邊界——同時也是全部的邊界。它們都不會觸及瀏覽器對於自己所在裝置或網路所透露出的任何資訊。
所有容器之間依然完全相同的東西
這正是 Firefox 官方公告沒有多談的部分,也是讀者最容易自行腦補出錯誤假設的地方。容器分割完全只作用在儲存層。任何來自你的瀏覽器與連線如何運作、而非網站儲存了什麼的訊號,都完全不受影響:
- 你的 IP 位址與網路路徑——容器不會改變流量的路由方式,也不會改變伺服器看到你的連線是從哪裡來的。
- TLS 與 HTTP/2 交握特徵——不論請求是由哪個容器發出,送出去的協商順序與參數都完全一樣。
- Canvas、WebGL 與音訊輸出——每個容器底層用的都是同一顆 GPU、同一套驅動程式堆疊,算繪出來的像素和音訊情境產生的波形完全一樣。
- 已安裝字型與螢幕幾何參數——即時從作業系統與顯示器讀取,不是任何容器能夠劃定範圍的東西。
- 時區與地區設定——直接從作業系統設定回報,每個分頁裡都完全一致。
把這些訊號組合起來,就是一份瀏覽器指紋——而指紋根本不在乎請求是哪個容器發出的。如果網站是靠指紋而不是讀取 Cookie 來辨識訪客,同一台機器上的兩個容器會產生完全相同的指紋,不管你把它們的 Cookie 罐分得多乾淨,最後都會被合併回同一個被追蹤的身分。我們在瀏覽器指紋熵與匿名集詳解一文中談過,即使完全不涉及任何 Cookie,光靠這些訊號中的極少數幾項,就足以讓一台裝置變得獨一無二、可被辨識。不想只憑文字相信,想親眼確認一下?在兩個不同的容器裡開啟同一個網頁,分別執行 BrowserInsight 的指紋檢測——得到的雜湊值會完全一樣。如果不一樣,那也是某種反指紋模式在對 Canvas 這類訊號逐站加雜訊,而不是容器邊界發揮了作用。
容器與其他隔離模式的比較
容器只是瀏覽器隔離工具這個小家族裡的其中一員,而家族裡的每一種工具,隔離的其實都是真正不同的層級。把它們搞混,正是大部分「過度信任」的根源。
| 隔離模式 | 分開了什麼 | 依然共用什麼 |
|---|---|---|
| 容器分頁 | 依情境身分分開的 Cookie 與網站層級儲存空間 | 裝置/網路指紋、IP 位址——也就是上一節提到的一切 |
| 隱私/無痕視窗 | 一個暫用的儲存罐,關閉視窗即清除 | 裝置/網路指紋;視窗本身通常還能透過另一套獨立的儲存配額行為,被偵測出是隱私視窗 |
| 獨立瀏覽器設定檔 | Cookie、儲存空間、擴充功能與瀏覽器層級設定 | 仍是同一個 IP 位址,也仍是同一套底層硬體指紋 |
| VPN 或代理 | 你的網路路徑,以及伺服器觀察到的 IP | 所有瀏覽器端訊號——Cookie、指紋,網路層以上的一切 |
橫向讀完這張表,規律其實很清楚:沒有任何一種工具能同時涵蓋一列以上。容器搭配 VPN 一起使用,才會同時處理到兩個真正不同的層級,這才比較接近大家原本以為「光是容器分頁」就能提供的效果。
容器真正有效的地方
這些都不代表容器沒有用——它們只是精確劃出了容器真正的價值所在。容器專門對付的是仰賴共用 Cookie 罐的追蹤手法,而確實有相當一部分追蹤剛好就落在這個描述之內。
跨站登入偵測——網站藉由探測與你現有工作階段 Cookie 綁在一起的時序、錯誤事件或重新導向行為,來推斷你還登入了哪些其他服務——一旦這些工作階段分別活在不同的容器裡,它賴以運作的訊號就會消失。如果你在某個容器裡根本沒登入某個服務,就沒有共用的 Cookie 狀態可供探測。
彈跳追蹤失效的原因在結構上是一樣的。它靠重新導向期間讓追蹤者自己的網域短暫變成第一方,藉此植入或讀取一個以 Cookie 為基礎的識別碼——而它植入的識別碼,正是情境身分會刻意分開存放的那種逐容器儲存空間,所以它沒辦法把一個容器裡的造訪跟另一個容器裡的造訪串連起來。對這兩種手法來說,把身分拆進各自獨立的 Cookie 罐,正好移除了它們賴以運作的那個機制。
容器邊界仍會洩漏的東西
以 Cookie 為基礎的追蹤,並不是網站唯一能仰賴的儲存手段,也不是所有能持續保存狀態的東西,都用跟 Cookie 一樣的方式劃定範圍。ETag 與快取超級 Cookie 把識別碼藏在普通的 HTTP 快取重新驗證標頭裡,而不是放進 Cookie 儲存空間。
在這裡,前面那兩套機制的方向並不一致。HTTP 快取就在狀態分割文件所列、Firefox 會永久依頂層網站建立索引的網路狀態之中,所以這套手法的跨站版本,不管有沒有容器都已經被封死。但兩份 MDN 文件都沒有對跨容器的那一版說過任何話——某個具體瀏覽器與版本究竟怎麼依情境身分劃分自己的 HTTP 快取,根本不像 Cookie 隔離那樣是寫進文件的保證。比較安全的假設是:容器邊界對 Cookie 以及 MDN 有記載的那些儲存空間是經過驗證的;除此之外的其他東西,在你用自己實際在用的瀏覽器親自確認之前,都不能視為理所當然。
容器是分艙隔離工具,不是匿名工具
最誠實的總結,其實是 Firefox 官方公告沒有明講、卻隱含其中的那句話:容器讓你在同一台裝置上的各個身分彼此分開——工作用的登入永遠看不到個人登入的 Cookie,購物工作階段也不會把廣告再行銷狀態帶進毫不相關的分頁。這就是分艙隔離(compartmentalization),而它對這個目的來說,確實非常有用。
但它不是用來躲避正在監視你的網站的匿名工具。一個讀取 Cookie 的網站,會在你的各個容器裡看到不同的訪客;一個靠指紋辨識的網站,看到的則只有一個。如果你在思考究竟要不要把這件事交給某個瀏覽器擴充功能來做,我們的瀏覽器擴展隱私風險一文,探討了一套已安裝軟體不論身旁搭配哪一種內建隔離功能、究竟能看到什麼這個更大的問題。把這兩個目標在腦中分清楚,容器就會準確做到它承諾的事——不多,也不少。
常見問題
容器分頁會隱藏我的指紋嗎?
不會。容器分頁只是依情境身分分割 Cookie 與網站層級的儲存空間;對你的 IP 位址、TLS 交握、Canvas/WebGL 輸出、字型、螢幕參數或時區完全沒有作用。這些訊號在同一個瀏覽器的每個容器裡都完全相同,而它們正是指紋賴以組成的原料。
網站看得出我在用容器嗎?
並沒有哪個對網頁開放的 API 會主動宣告這件事:contextualIdentities 是給擴充功能用的 WebExtensions API,你造訪的網站根本呼叫不到。網站真正看得到的是結果——一個空的 Cookie 罐——而這跟一個剛清掉 Cookie 的訪客看起來一模一樣。問題在於「儲存空間是空的、指紋卻很眼熟」本身也是一種模式,這正是為什麼容器的設計目標是讓各個容器之間無法透過儲存空間互相串連,而不是隱藏這個功能本身的存在。
Firefox 把容器變成原生功能,會改變它隔離的範圍嗎?
不會。Firefox 153 的原生容器,把 Multi-Account Containers 的功能收編進了瀏覽器本體,但底層機制——也就是 contextualIdentities 一直以來所描述的那套情境身分儲存分割——並沒有改變。不管是哪一種形式,隔離邊界都跟本文所描述的完全一樣。
容器跟隱私/無痕視窗是同一回事嗎?
不是。隱私視窗用的是單一一個暫用儲存罐,視窗關閉就會清除;容器則是同時提供多個並排運作、彼此分開的持久儲存罐。隱私視窗還有自己一套可被偵測出來的特殊行為——參見網站如何偵測無痕模式——這些特性完全不適用於容器。
已經在用容器了,還需要 VPN 嗎?
它們解決的是不同的問題。容器是靠隔離儲存空間,把你在同一台裝置上的各個身分彼此分開;VPN 改變的則是伺服器看到的網路路徑與 IP 位址,而這完全不是容器會碰到的範圍。兩者互不能取代——容器補不到的網路側那一半,可參見 BrowserInsight 的 VPN/代理檢測。


