防偵測瀏覽器如何運作:完整技術解析

指紋表面、一致的身分生成、磁碟上的儲存隔離、每個設定檔獨立的路由,以及這套做法坦白說的極限。
防偵測瀏覽器做四件事。它把每個設定檔的瀏覽資料分開儲存、控制每個設定檔回報的裝置身分、讓每個設定檔的流量各自走不同的路由,並讓這三者隨時間保持一致。本文從機制層面逐一說明這四件事怎麼做到,最後談談這套做法做不到的事。
指紋表面
先從網頁能讀到什麼談起,因為其他一切都是對此的回應。任何網站上的腳本都能向瀏覽器提問,而答案描述了這台機器。這些表面自然可以分成幾組。
| 表面 | 網頁讀到什麼 |
|---|---|
| Navigator | 瀏覽器名稱與版本、平台、語言清單、回報的處理器數量與記憶體、觸控支援 |
| 螢幕 | 寬度、高度、可用工作區、色彩深度、裝置像素比 |
| Canvas | 在畫面外繪製文字與圖形所產生的精確像素,雜湊成一個穩定的值 |
| WebGL | 顯示卡廠商與渲染器字串,以及渲染場景的雜湊值 |
| 音訊 | 振盪器經過音訊處理圖後的輸出,會因軟硬體堆疊而異 |
| 字型 | 安裝了哪些字型,由文字測量結果推斷 |
| 時區與時鐘 | 回報的時區與偏移量,並與流量的來源地比對 |
| 網路 | 位址本身、WebRTC 看到的連線候選項,以及 TLS 交握的形態 |
單獨一列無法識別一台機器,組合才可以,而組合也是謊言被抓到的地方:無法屬於同一台真實機器的數值,比任何單一數值都更響亮地洩漏訊號。
蒐集既便宜又無聲。表中的每個值,任何網頁都能透過公開文件化的 API 取得,不需要任何權限提示,而且大部分在造訪的第一秒內就送達。不論你對這種做法持什麼立場,它都是現代網路的既定事實,也是防偵測瀏覽器設計時所針對的基準。
如何生成一致的身分
天真的做法是攔截每個問題,並隨機化答案。這在結構上就行不通。這些答案描述的是同一台機器,所以彼此相關,而各自獨立的隨機答案會破壞這些關聯。Windows 的 User-Agent 搭配只有 macOS 才內建的字型、沒有任何筆電出貨過的螢幕尺寸、從未與所宣稱平台並存過的顯示卡字串:每一種都是檢查程式能輕易測試出來的矛盾。
所以可行的防偵測瀏覽器會把身分當成一個整體來生成。它從一種真實而常見的機器類型出發,所有數值都由這個選擇推導而來。平台決定合理的字型清單、顯示卡字串與觸控支援;螢幕取自該類機器實際出貨的尺寸;語言與時區則來自設定檔預定的地區。這些數值彼此吻合,因為它們是依據同一台機器的同一份描述一起選出的。
第二個特性同樣重要:這組數值是被儲存下來的。它在設定檔建立時就寫入設定檔,之後每個工作階段都回報相同的值,因為在兩次造訪之間不斷改變的裝置,描述的是沒有人擁有的硬體。穩定性就是合理性的大半。
磁碟上的儲存隔離
儲存這項工作最不起眼,卻也最絕對。每個設定檔擁有一個目錄,瀏覽器持久化的一切都放在裡面:Cookie 資料庫、Local Storage、IndexedDB、HTTP 快取、Service Worker 註冊、擴充功能狀態、歷史紀錄與已儲存的憑證。兩個設定檔就是兩個互不相交的目錄,每個執行中的瀏覽器都指向自己的那個。
該檢查的特性是完全不相交,因為部分隔離會悄悄失效。Cookie 很容易分開,但快取可以透過它保留的資源辨認出回訪的瀏覽器;Service Worker 可以持有識別碼,並在兩次造訪之間持續執行;IndexedDB 則是現代應用程式存放它們真正信任的紀錄之處。如果隔離涵蓋了那些有名的儲存區,卻共用了其他任何一個,那只是隔離了問題顯眼的那一部分。
持久性是另一半。工作階段會累積價值:完成的安全驗證、已建立的登入歷史、回訪者的樣貌。設定檔在不同工作階段之間保有自己的目錄,這才使帳號作業成為可能。關閉時的寫出讓目錄得以持久,這也是為什麼在工作階段進行中強制終止設定檔的程序,可能會讓剛建立的工作階段付諸東流。
網路路由
每個設定檔都帶有自己的路由,在瀏覽器啟動時套用,因此流量會經由該設定檔的代理離開,而不會動到系統設定或任何其他設定檔的路由。
- 代理是依設定檔附加,而非依機器。一般瀏覽器使用系統代理;在這裡,每個執行中的設定檔都透過自己的端點連線。
- 名稱解析也經過該路由,因為請求來自一個國家、查詢卻來自另一個國家,是網路層的矛盾。
- WebRTC 被限制為與路由一致。若放任不管,它可能會露出代理從未經手的連線候選項。
- 時區與語言會配合路由所在的國家,因為位址是唯一無法生成的值,所以故事的其餘部分必須與它吻合。
路由也是最值得獨立驗證的環節,因為它是向第三方購買的。在指派之前先測試端點,並讀取實際觀察到的位址而不是宣稱的位址,就能在問題還只是設定問題、尚未變成帳號問題時抓出故障。
瀏覽器本身改變了什麼
工具有兩個地方可以改變網頁收到的答案,兩者的差異是這個主題中最具技術性的分岔點。
| 做法 | 運作方式 | 弱點 |
|---|---|---|
| 腳本注入 | 擴充功能或注入的腳本覆寫網頁呼叫的函式,使 Canvas 讀取與 navigator 查詢回傳被替換的值 | 覆寫本身是看得見的。被修補過的函式可以被認出已被修補,而注入程式遺漏的任何表面仍會回答真實的值 |
| 在瀏覽器自己的程式碼內 | 瀏覽器的實作在產生真實值的程式路徑上,以設定檔儲存的值作答 | 建置與維護的工作量大得多,這也是專用工具與擴充功能的分野 |
注入式做法是這個類別的起點,它的天花板也廣為人知:網頁可以檢查原生函式看起來是否仍像原生的,也可以透過注入沒有涵蓋到的路徑存取同一個表面。因此專用的防偵測瀏覽器把修改做在瀏覽器內部,讓儲存的身分就是實作透過每一條讀取路徑所回報的內容。
開啟設定檔實際做了什麼
- 載入儲存的身分:一組一致的裝置數值,與上次完全相同。
- 瀏覽器針對設定檔自己的目錄啟動,因此每個持久儲存區都是該設定檔專屬的。
- 套用路由:代理、經由代理的名稱解析,以及受其約束的 WebRTC。
- 工作階段執行,並在目錄內累積狀態。
- 關閉時寫出狀態,讓下次開啟時延續相同的裝置、相同的儲存與相同的路由。
這份清單的每一部分都能從外部檢查。兩次開啟指紋測試頁面並比較數值;查看磁碟上的設定檔目錄;讀取實際觀察到的位址。這個類別的工具應當歡迎這種檢查,因為機制就是產品本身。
坦白說的極限
這套做法有邊界,了解邊界是熟練運用的一部分。
- 它無法讓瀏覽器變得不可能被識別,而且沒有人能衡量這樣的宣稱。務實的目標是讓設定檔看起來像一台普通、內部一致的機器,並保持穩定。
- 它無法修正你自己引入的矛盾。路由在一個國家、時區在另一個國家,是設定上的錯誤,工具只能讓正確的設定變得容易做到。
- 它不涵蓋行為。時間點、數量與節奏會和環境一起被解讀,一群步調一致的帳號,不論每個環境多乾淨,都會暴露自己。
- 它不涵蓋申報的身分。共用的救援資訊、共用的付款工具與重複使用的文字,會透過平台自己的紀錄把帳號連結起來,那是遠在瀏覽器之上的層級。
- 它不改變平台規則。隔離分開的是合法的環境;平台允許什麼,由平台決定,我們不對自己無法掌控的平台上的任何結果作出承諾。
把這些極限當成一種定義,而不是失望。防偵測瀏覽器是一件一致性的工具:分開的儲存、穩定而合理的身分、相符的路由,依設定檔結合在一起,並在每次開啟時一模一樣地重現。這就是整個機制,關於這個類別的其他一切說法,都只是它的變體。

