偽裝 user-agent 可能反而縮小你的匿名集,並暴露與 Client Hints 的矛盾,讓你更容易被識別——熵悖論,以及偽裝何時才真正有效。
更改 user-agent 感覺是個顯而易見的隱私招數:告訴網站你用的是另一種瀏覽器,它就沒辦法揪出真正的那一個。但實際上,結果往往正好相反。一個偽裝過的 user-agent,可能比它取代掉的那個真實值更罕見,而且它幾乎總會和瀏覽器洩漏的其他資訊互相矛盾——這兩個問題都只會讓你更容易被單獨挑出來,而不是更難。這並不是要你永遠別碰 user-agent;而是提醒你,在依賴偽裝之前,得先搞清楚它到底改變了什麼。
核心要點
- 問題在於「罕見」,不在於「說謊」。 一個很少有其他訪客共用的偽裝 user-agent,可能比它取代掉的真實值帶來更多辨識用的熵——背後的原理請見熵與匿名集的數學關係。
- 這串字串很少單獨行動。 User-Agent Client Hints、
navigator.userAgentData,以及數十種引擎層級的行為,即便字串已經改了,仍會持續回報你真正的瀏覽器——這就製造出一個指令碼可以標記為「說謊」的矛盾。 - 偵測不需要證明你在說謊——只要有一個訊號與所聲稱的身分對不上就夠了,這正是如今網站偵測 user-agent 偽裝的方式。
- 偽裝唯有在把你推向一個常見、且內部一致的身分時才有幫助——而不是推向一個隨機或不尋常的身分。
- 統一勝過隨機化。 讓每個使用者看起來都一樣的工具,會縮小整個群體的總熵;而讓某個使用者看起來與眾不同的工具,只是換了個人來顯眼而已。
更改 User-Agent 實際上做了什麼
User-agent 字串是瀏覽器在每個請求中送出的一行文字,用來宣告自己的名稱、版本與平台。擴充功能或 DevTools 設定可以隨意改寫這行文字——沒有任何東西能阻止你在 Windows 桌機用 Chrome 瀏覽時,告訴伺服器自己其實是 iPhone 上的 Safari。但它改不了其他一切。渲染引擎、JavaScript 執行環境、HTTP 標頭組合、TLS 交握,以及數十種其他可被觀測的屬性,仍會表現得和真實瀏覽器一模一樣,因為它們沒有一個會讀取這串偽裝過的字串來決定怎麼運作。你只改變了一項關於自己身分的聲稱,而規模大得多的其他證據,仍在訴說真相。
熵悖論:問題在於「罕見」,而非「說謊」
抵抗指紋追蹤的重點不是隱藏資訊——而是不要顯眼。正如熵與匿名集的拆解所解釋的,指令碼能讀取的每一項屬性,都會依其數值的罕見程度貢獻若干位元的熵:常見的數值代價低,罕見的數值代價高,而來自獨立訊號的位元會彼此相加。EFF 最初的 Panopticlick 研究測得,光是 user-agent 字串就價值約 10 位元的熵——在讓一個指紋於全球獨一無二所需的約 33 位元中,佔了相當可觀的一部分(參見 EFF 對 Panopticlick 結果的總結)。
不過這 10 位元是歷史高點,而不是今天的數字。Chrome 的 User-Agent 縮減此後把這串字串削減成粗粒度、且大致凍結的形式,因此如今一個誠實的 Chrome 字串所攜帶的熵,遠少於 2010 年。這反而讓偽裝這筆帳更不划算:你要換掉的那個誠實字串如今格外便宜,而任何不符合縮減後應有形態的數值,則格外昂貴。
這正是偽裝出問題的地方。如果你偽造了一個很少有其他訪客會呈現的 user-agent——過時的瀏覽器版本、冷門的作業系統版本、不搭調的裝置類別——你並沒有擺脫這份熵的貢獻。你很可能反而增加了它,因為一個罕見的所聲稱身分,按定義就是把可能是你的人群範圍縮得更窄。挑一個流行、當前、毫不起眼的瀏覽器字串,是唯一不會把位元加回去的偽裝方式——而即便如此,也只有在你指紋的其餘部分不會立刻與之矛盾時才有效,這正是下一個問題。
矛盾偵測:當說法兜不攏的時候
即便是挑得很好的常見 user-agent 字串,也得禁得起與瀏覽器暴露的其他一切交叉比對——而大多數偽裝嘗試,正是敗在這一關。
User-Agent 與 Client Hints 的落差
Chromium 系瀏覽器透過 navigator.userAgentData 暴露 User-Agent Client Hints——這是一個結構化、可由指令碼讀取的來源,承載著與 user-agent 字串相同的瀏覽器與平台資訊,卻是透過一個完全獨立的 API 讀取。多數 user-agent 偽裝工具只修補字串就到此為止,於是 navigator.userAgentData 底下仍持續回報真正的 Chromium 品牌與平台,而字串卻聲稱自己是 Firefox 或 Safari——這兩種瀏覽器根本不會暴露 userAgentData。同時讀取兩者的伺服器或指令碼會看到:瀏覽器一邊聲稱自己是某種身分,另一邊有個更難偽造的獨立 API 堅持它是另一種身分。光是這一項矛盾,往往就足以讓這個工作階段被標記,這也是網站如何偵測 user-agent 偽裝的核心技巧之一。
「說謊」標記與跨訊號檢查
指紋研究工具直接把這個概念形式化。它們不會只讀取一次數值,而是透過不只一條路徑讀取同一項底層事實——一個屬性對照一項推導出的行為,主執行緒的結果對照別處的相同運算——並將不一致標記為說謊。這正是 CreepJS 這類專案背後的模型,它們評分的是瀏覽器的一致性,而非獨特性(一般機制請見「說謊」偵測如何抓出偽裝)。一個被覆寫的 navigator.userAgent getter,正是這類檢查專門設計來揪出的那種覆寫:字串說著一件事,而其餘十幾條通往同一事實的路徑,卻不斷說著另一件事。
偽裝何時有效,何時弄巧成拙
偽裝的效果,完全取決於它把你推往哪個方向——是推向人群,還是推離人群。
| 情境 | 對你匿名集的影響 |
|---|---|
| 偽裝成罕見或過時的瀏覽器字串 | 縮小——你現在對應到一個更小、更不尋常的族群 |
| 偽裝成一個流行、當前的字串,且與你真實的引擎行為相符 | 大致中性,前提是沒有其他訊號與之矛盾 |
| 只偽裝字串本身,卻沒動 Client Hints/引擎行為 | 縮小——這個落差本身就成了一項罕見、具辨識力的訊號 |
| 測試/相容性用途(檢視行動版排版、QA) | 沒問題——你並不是要打敗追蹤,只是在檢查渲染結果 |
| 每個工作階段或每個網站都隨機更換字串 | 縮小——跨次造訪不一致的身分,本身就是一種破綻 |
每一列呈現的規律都一樣:只有在結果既常見又內部一致時,偽裝才不會增加熵。任何讓你變得更罕見、或與其他訊號矛盾的做法,都會與它原本想達成的目標背道而馳。
融入人群原則
這正是為什麼最有效的反指紋工具,建立在統一性之上,而非逐一隨機化各項訊號。Firefox 的 resistFingerprinting 模式與 Tor Browser 並不試圖隱藏你的 user-agent——它們把 user-agent,連同時區、螢幕尺寸與 canvas 輸出,統一標準化成整個使用者群體回報的同一組數值。如果使用該模式的所有人都回報一模一樣的一組數值,那麼無論這組數值與底下「真實」的設定相比如何,它所攜帶的熵都接近於零。相反地,自行隨機化單一訊號,可能會像偽裝一樣弄巧成拙:一個怪異隨機的 canvas 雜湊值,或是每次造訪都會改變的 user-agent,本身就是一種可被偵測的模式——Canvas 雜訊 vs 真實雜湊:隨機化為何適得其反對此有深入探討。這個教訓也適用於 canvas 之外:孤立地改變一項訊號,卻沒有讓其他所有人也做同樣的事來對齊,往往只是把一種可見性換成了另一種。
檢查你自己的瀏覽器
你不必單憑信任接受這一切——你可以親眼看到這種矛盾。用擴充功能或 DevTools 裝置模擬偽裝你的 user-agent,然後打開主控台,比對 navigator.userAgent 與 navigator.userAgentData:在 Chromium 上,無論前者現在聲稱什麼,後者都會持續回報你真正的瀏覽器。BrowserInsight 的指紋檢測會展示指令碼可能組合起來的完整訊號集,而瀏覽器核心檢測則直接把你所聲稱的身分與實際的渲染引擎做比對。若想更全面地比較你匿名集的前後差異,EFF 的 Cover Your Tracks 工具會根據它自己彙整的資料集,回報一個「N 分之 1」的估計值——分別在啟用與停用你的偽裝工具時各跑一次,就能看出它實際上把你推往哪個方向。
常見問題
那我是不是永遠都不該更改 user-agent?
不是永遠不行——只是別把它當成獨立的隱私工具。為了相容性測試或檢視行動版排版而偽裝完全沒問題,因為你並不是在試圖打敗追蹤。但作為隱私措施,一個孤立的偽裝字串,若沒有搭配對應的 Client Hints 與引擎行為,通常會增加辨識用的熵,而不是減少它。
這是否代表會更改 user-agent 的隱私擴充功能都不好?
不一定——關鍵在於它們是否一致地更改整個身分。設計良好的工具會協調 user-agent、Client Hints 與相關訊號,共同朝向一個常見、共享的設定。只修補字串、或每次造訪都隨機更換的工具,往往會讓情況變得更糟——而且正是以上述那些方式變糟。
指紋熵悖論是不是 user-agent 偽裝獨有的?
不是——它適用於任何訊號。隨機化 canvas 雜湊值、螢幕解析度或字型清單,只要隨機化後的數值罕見或與其他一切不一致,就會出現同樣的失敗模式。user-agent 只是多數人最先想到、也最容易偽裝失敗的那個訊號。
如果不是偽裝,那什麼才真正能降低我的指紋?
是標準化,而不是偽裝。刻意讓大量使用者回報一模一樣數值的瀏覽器與模式——Tor Browser、Firefox 的 resistFingerprinting——確實能降低一般使用者的熵,因為你所融入的人群是真實且龐大的。這些工具需要協調的完整訊號集,請見完整的指紋技術指南。
結語
User-agent 字串只是數十項訊號中的一行,孤立地更改它並不會移除資訊——它只是新增了一項:這個聲稱是否與其他一切兜得起來。一個罕見的偽裝身分,會自己縮小你的匿名集;一個不一致的身分,則會給偵測器遞上一個容易辨認的破綻。真正有幫助的那種「偽裝」,其實已經不再像偽裝了——它對應到一個龐大、常見、內部一致的設定,而這正是每一款真正有效的反指紋工具背後的共同原則。
推薦閱讀:


