返回部落格

User-Agent 技術詳解:從 UA 字串、瀏覽器指紋到 Client Hints

從 HTTP 語義和真實 UA 拆解出發,結合瀏覽器指紋論文解釋 UA 的資訊量、偽裝一致性風險、Chrome UA Reduction 與 Client Hints,並給出開發和多環境管理的實踐方法。

User-Agent 技術詳解:從 UA 字串、瀏覽器指紋到 Client Hints

開啟瀏覽器開發者工具,在網路請求里幾乎總能看到一行 User-Agent。 它看起來像瀏覽器的「自我介紹」:使用什麼瀏覽器、運行在哪個系統、版本是多少。 於是很多人會自然地把它理解成設備身份證,甚至認為改掉這一行,就能變成另一台設備。

這兩個理解都只對了一半。

User-Agent(下文簡稱 UA)首先是一段由客戶端主動聲明的相容資訊。 它不是可信身份憑證,內容可以被修改; 但它又不是孤立存在的。 網站可以把 UA 與 Client Hints、JavaScript API、螢幕、字體、Canvas、WebGL、網路和行為信號放在一起分析。 真正值得研究的,不是“UA 能不能改”,而是它在整套瀏覽器可觀察面中扮演什麼角色。

本文從 HTTP 標準和瀏覽器指紋論文出發,回答四個核心問題:

  1. 一條 UA 字串為什麼像「瀏覽器考古現場」?
  2. UA 單獨能提供多少識別資訊,論文數據該如何解讀?
  3. 為什麼只改 UA 可能產生更明顯的矛盾?
  4. UA Reduction 與 User-Agent Client Hints 到底改變了什麼?

本文所說的 UA 主要指 HTTP 請求頭 User-Agent,同時會討論 JavaScript 中的 navigator.userAgentnavigator.userAgentData。 它們屬於相鄰但不完全等價的介面,不能在所有瀏覽器和場景中假定內容永久一致。

1. User-Agent 到底是什麼?

[RFC 9110 第 10.1.5 節](https://www.rfc-editor.org/rfc/rfc9110.html#name-user-agent)User-Agent 定義為要求方用於說明自身產品資訊的欄位。 其簡化語法是:

User-Agent = product *( RWS ( product / comment ) )
product    = token [ "/" product-version ]

換成日常語言,就是:先寫一個產品名,可以帶版本; 後面繼續追加產品或註釋。 標準允許它用於相容性處理、問題診斷和統計,同時明確提醒實現方不要無必要地暴露過細資訊,因為更長、更具體的 UA 會增加延遲和指紋風險。

一條現代 Chromium 桌面瀏覽器 UA 可能類似:

Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/145.0.0.0 Safari/537.36

將它按空格拆開,會發現很多看似「不屬於 Chrome」的名字:

片段今天通常表達什麼容易產生的誤解
Mozilla/5.0歷史相容標記使用了 Firefox 或 Mozilla 瀏覽器
Windows NT 10.0Windows 平台類別; 在縮減策略下不能可靠區分 Windows 10/11一定是 Windows 10
Win64; x6464 位 Windows / x86-64 架構線索足以證明真實 CPU 型號
AppleWebKit/537.36相容性與引擎譜系標記當前 Chrome 仍直接使用 Safari 的完整實現
KHTML, like Gecko歷史相容標記同時運行 KHTML 和 Gecko
Chrome/145.0.0.0Chrome/Chromium 品牌與主版本; 后三段可能被縮減能得到精確補丁版本
Safari/537.36為兼容舊網站保留的標記這一定是 Safari

UA 之所以冗長,是因為早期網站經常按瀏覽器名稱分支。 新瀏覽器為了拿到正確頁面,只能聲明自己“也相容”舊瀏覽器。 相容標記逐層累積,最終形成一條不能按自然語言直讀的歷史記錄。

所以,解析 UA 的第一原則是:**它是一種相容協定,不是一句嚴格的設備描述。 **

2. 網站為什麼仍然使用 UA?

UA 並非只服務於追蹤。 合理用途包括:

  • 對確實存在差異的舊瀏覽器提供相容頁面;
  • 選擇合適的安裝包或下載格式;
  • 在錯誤日誌中定位特定瀏覽器版本的問題;
  • 粗粒度統計瀏覽器家族、平台類別和版本分佈;
  • 發現明顯不可能的自動化或惡意請求組合。

問題在於,UA 嗅探(UA sniffing)很容易從“相容兜底”滑向“根據名稱猜能力”。 例如,代碼看到 Chrome 就假定某個 API 一定存在,遇到內嵌 WebView、衍生瀏覽器、凍結版本或偽造 UA 時便會出錯。

更穩妥的順序是:

  1. 能做功能檢測時,直接檢查 API 或行為是否可用;
  2. 確需識別瀏覽器時,使用維護中的解析庫,不手寫脆弱正則;
  3. 只保留業務真正需要的粗粒度分類;
  4. 為未知品牌、未知版本和缺失欄位準備回退路徑。

3. UA 是瀏覽器指紋嗎?

準確說,UA 是瀏覽器指紋的一項輸入,通常不是完整指紋。

瀏覽器指紋的核心不是讀取某個秘密編號,而是測量一組相對穩定、具有區分度的可觀察屬性。UA 可能提供瀏覽器家族、版本和平台線索; 螢幕尺寸、字體、時區、Canvas、WebGL、AudioContext 等信號則從其他介面補充資訊。

[Laperdrix 等人的瀏覽器指紋綜述](https://arxiv.org/abs/1905.01051)將這類技術放在無狀態識別的框架下討論:網站不一定要先在設備上寫入 Cookie,也可以根據瀏覽器暴露的屬性組合來關聯訪問。 這裡的“無狀態”不代表網站完全不保存數據,而是識別材料不必依賴用戶端持久標識符。

1. 論文中的 10 bit 應該怎樣理解?

Peter Eckersley 在 2010 年的 Panopticlick 研究 [《How Unique Is Your Web Browser?》](https://www.freehaven.net/anonbib/papers/pets2010/p1-eckersley.pdf)中,對約 47 萬份瀏覽器指紋樣本進行了測量。 論文報告:

  • 完整指紋在該樣本中的平均資訊量約為 18.1 bit;
  • 換算成直觀概率,平均約為 286,777 個瀏覽器中才出現一次同樣組合;
  • 表格中,UA 字串這一項的平均資訊量約為 10.0 bit;
  • 在啟用 Flash 或 Java 的瀏覽器中,94.2% 的完整指紋是唯一的。

資訊量常用自資訊表示:

I(x) = -log₂ P(x)

如果某種 UA 在總體中出現概率為 1/1024,它對應的資訊量就是 10 bit。 這裡的 10 bit 不等於 UA 有 1024 種,也不等於它能唯一識別某個人; 它表達的是觀察到這一取值后,不確定性平均減少了多少。

2. 為什麼不能把 2010 年數據直接當作今天的常數?

這組結果非常重要,但使用時至少要加上三層限定:

  • 樣本來自主動訪問隱私測試頁面的人群,不是全球互聯網的隨機抽樣;
  • 2010 年的瀏覽器、外掛程式生態和 UA 版本顆粒度與今天不同;
  • Chrome 的 UA Reduction、外掛程式介面收縮以及瀏覽器的反指紋策略已經改變了屬性分佈。

因此,論文數據適合證明“UA 與其他屬性能夠貢獻可測量的區分資訊”,不適合被改寫成“今天 UA 固定有 10 bit 熵”。 指紋能力取決於樣本總體、時間視窗、瀏覽器策略和信號組合。

4. 為什麼只修改 UA 可能適得其反?

UA 是用戶端聲明,不帶密碼學證明。 服務端無法從這一行直接讀取一台設備的「出廠真相」。 但是,網站可以檢查不同信號是否合理相容。

User-Agent 與其他瀏覽器信號的一致性模型

例如,一條 UA 聲稱自己是移動瀏覽器,頁面卻觀察到沒有觸控點、視窗尺寸長期像桌面顯示器、相關 Client Hints 又報告桌面平臺。 單項數據都可能有正常例外,但多個穩定矛盾疊加,會形成可分類的模式。

早在 Panopticlick 論文中,研究者就觀察到類似現象:有瀏覽器自稱 iPhone 卻支援 Flash,也有 Firefox UA 與僅 Internet Explorer 支援的存儲特徵同時出現。 2018 年的 [FP-Scanner 研究](https://www.usenix.org/conference/usenixsecurity18/presentation/vastel)進一步系統化了這一問題:一些反指紋擴展或偽裝工具會在不同介面間留下不一致,檢測器可以識別屬性被修改,有時還能推斷原始瀏覽器或操作系統類別。

這並不意味著所有不一致都是惡意行為。 遠端桌面、輔助功能、企業策略、相容層和特殊硬體都可能產生少見組合。 嚴謹的風控系統應做概率判斷,而不是用一條規則直接封禁使用者。

從環境管理角度看,真正需要關注的是三件事:

  • 內部一致性:UA、Client Hints、平臺、架構、觸控和螢幕等資訊不要明顯互相否定;
  • 時間穩定性:同一個長期環境不應在每次啟動時無緣無故劇烈變化;
  • 合理多樣性:不同環境可以不同,但罕見且機械生成的組合未必更安全。

[FP-STALKER](https://doi.org/10.1109/SP.2018.00008)研究瀏覽器指紋隨時間演化時也說明,屬性變化並不自動破壞關聯。 跟蹤模型可以利用穩定屬性與可解釋的版本變化,將前後指紋重新連接起來。

5. UA Reduction 解決了什麼問題?

傳統 UA 預設隨每次請求發送,任何收到請求的第一方或第三方資源都能被動讀取。 欄位越具體,所有接收方獲得的區分資訊越多。

Chromium 的 [User-Agent Reduction 計劃](https://www.chromium.org/updates/ua-reduction/)採用了“減少預設顆粒度”的思路:

  • 從 Chrome 101 開始,將桌面 UA 的次版本、構建號和補丁號縮減為 0.0.0;
  • 後續階段逐步統一桌面操作系統版本、CPU 和 Android 設備資訊;
  • Android 的縮減 UA 使用固定的平臺與機型表示,例如 Android 10; K;
  • 需要更細資訊的網站改用 User-Agent Client Hints 按需請求。

縮減後的典型格式可以抽象為:

Mozilla/5.0 (<统一后的平台信息>)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/<主版本>.0.0.0 Safari/537.36

這項改變降低了傳統 UA 的被動指紋面,但沒有消滅瀏覽器指紋。 主版本、平台類別和行動裝置標記仍可能可見; 網頁也仍可從其他 API、網路和行為中獲得資訊。

6. User-Agent Client Hints 如何工作?

Client Hints 的基本機制由 [RFC 8942](https://www.rfc-editor.org/rfc/rfc8942.html)定義;UA 專用欄位由 WICG 的 [User-Agent Client Hints 草案](https://wicg.github.io/ua-client-hints/)繼續描述。 它把原來塞在一條非結構化字串里的資訊拆成結構化字段,並區分預設可發送的低熵提示與需要網站請求的高熵提示。

UA Reduction 與 User-Agent Client Hints 的請求流程

簡化互動可能是:

GET /download HTTP/1.1
User-Agent: Mozilla/5.0 (...) Chrome/145.0.0.0 Safari/537.36
Sec-CH-UA: "Chromium";v="145", "Not_A Brand";v="99"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "Windows"

伺服器確實需要架構與位數來選擇安裝包時,可以在響應中聲明:

HTTP/1.1 200 OK
Accept-CH: Sec-CH-UA-Arch, Sec-CH-UA-Bitness
Vary: Sec-CH-UA-Arch, Sec-CH-UA-Bitness

瀏覽器在支援該機制、滿足安全與策略要求時,可以在後續請求中附帶:

Sec-CH-UA-Arch: "x86"
Sec-CH-UA-Bitness: "64"

常見 UA Client Hints 包括:

欄位典型用途信息級別
Sec-CH-UA品牌及主要版本清單通常為低熵
Sec-CH-UA-Mobile是否偏向行動裝置通常為低熵
Sec-CH-UA-Platform平台類別通常為低熵
Sec-CH-UA-ArchCPU 架構高熵,按需請求
Sec-CH-UA-Bitness體系結構位數高熵,按需請求
Sec-CH-UA-Platform-Version平臺版本高熵,按需請求
Sec-CH-UA-Full-Version-List各品牌完整版本高熵,按需請求
Sec-CH-UA-Model設備型號高熵,按需請求

這裡有三個容易被忽略的工程細節。

1. Client Hints 不是所有請求都自動完整發送

低熵提示可能默認出現,高熵提示通常需要網站通過 Accept-CH 請求。 首次導航、子資源、許可權策略、HTTPS 環境和瀏覽器支持情況都會影響實際結果,因此服務端必須允許字段缺失。

2. 品牌清單故意要求解析器更健壯

Sec-CH-UA 可能包含多個品牌和一個用於測試相容性的非真實品牌。 代碼不能假定第一個品牌永遠是產品名,也不能因為出現未知品牌就報錯。 正確做法是解析結構化欄位、忽略不認識的項,併為未來品牌保留擴展空間。

3. 用 Client Hints 改變回應時要處理緩存

如果伺服器根據架構、平臺等提示返回不同內容,應正確設置 Vary 或採用等價的緩存鍵策略。 否則,共用緩存可能把為一種設備生成的回應錯誤地發給另一種設備。

7. Client Hints 是否比傳統 UA 更隱私?

答案是:**它改善了資訊暴露方式,但不是隱私免疫機制。 **

傳統 UA 的問題在於「預設、被動、一次性暴露一大串」。。Client Hints 的改進是將資訊拆分,讓高熵欄位的請求更顯式,也讓瀏覽器有機會實施預算、許可權或策略控制。

但從指紋角度看,只要網站獲得架構、完整版本、平臺版本和設備型號,這些欄位仍可能增加可區分度。RFC 8942 也把隱私與性能影響列為設計約束。 開發者應問的不是「能不能拿到」,而是:

  • 當前功能是否真的需要這個欄位?
  • 能否用能力檢測或用戶選擇替代?
  • 是否可以只保存粗粒度分類?
  • 原始值保存多久,哪些人員或系統可以訪問?
  • 第三方腳本是否也會收到這些提示?

8. 服務端解析 UA 的工程建議

1. 不要把 UA 當作許可權或身份依據

UA 可以用於展示提示和相容回退,但不能單獨決定登錄身份、授權範圍、支付信任或安全級別。 任何可以由用戶端修改的欄位都不應成為許可權邊界。

2. 優先能力檢測,而不是瀏覽器名單

前端需要某個 API 時,應測試該能力是否存在:

if ('share' in navigator) {
  // 提供系统分享能力
} else {
  // 提供复制链接等回退方案
}

相比“如果是 Chrome 145 就啟用”,能力檢測能更好地處理衍生瀏覽器、實驗功能、企業策略和未來版本。

3. 同時接受傳統 UA、Client Hints 與未知狀態

在遷移期,服務端可能遇到三類請求:只有傳統 UA、同時包含 UA 與 Client Hints、兩者都高度縮減。 數據模型應允許 unknown,不要為了填滿字段而猜測精確系統或型號。

4. 降低日誌顆粒度

如果統計只需要“桌面 / 移動、主流瀏覽器家族、主版本”,就不必長期保存原始 UA 和全部高熵提示。 最小化日誌既降低隱私風險,也減少分析系統把正常細微差異誤當重要維度的機會。

5. 把異常當作信號,不當作判決

“UA 聲稱 Windows,但某個介面看起來不像 Windows”最多是一項風險特徵。 企業環境、虛擬化、遠程會話、相容層和輔助技術都可能產生合理異常。 將單項矛盾直接等同於欺詐,會製造大量誤報。

9. 多環境管理中,UA 應該如何配置?

對於跨地區測試、廣告預覽、賬號運營和隱私隔離場景,UA 配置的目標不應是「越新奇越好」,而應是可解釋、穩定且與環境相容。

建議按以下順序檢查:

  1. 瀏覽器版本:UA 主版本應與實際內核能力處於合理範圍,不要聲明一個內核不可能支援的版本;
  2. 操作系統:UA 平臺、Client Hints 平臺和 JavaScript 暴露的平台類別應互相相容;
  3. 架構與位數:不要讓 UA、Client Hints 和可執行環境出現明顯衝突;
  4. 設備形態:移動標記應與觸控、視口、圖元比和交互方式整體合理;
  5. 區域資訊:語言、時區、地理位置和代理出口不必機械一致,但應符合真實業務場景;
  6. 環境穩定性:同一賬號或測試身份長期複用同一環境時,避免無理由頻繁切換平臺和主版本。

PurpleMark的當前環境轉換會把所選操作系統映射為內核 UA 平臺,並優先從配置中的 Chrome/CriOS/ 片段提取瀏覽器版本; 沒有可用版本時,再按當前內核主版本生成合理回退。 這樣做的重點不是偽造一條孤立字串,而是讓 UA 配置進入統一的瀏覽器環境模型。

使用時仍需注意:環境隔離和參數一致性只能降低技術層面的關聯與測試偏差,不能保證帳號不被關聯,也不能替代平臺規則、賬號資料、支付資訊和操作行為管理。 相關能力應只用於合法的隱私保護、授權測試與合規業務。

10. 常見問題FAQ

Q1:修改 UA 后,瀏覽器就真的變成另一個瀏覽器了嗎?

不會。UA 改變的是對外聲明的一部分資訊,不會自動替換 JavaScript 引擎、渲染管線、網路棧和支援的Web API。

Q2:網站能讀取「真實 UA」嗎?

不存在一個所有網站都能繞過瀏覽器直接讀取的硬體級「真實 UA」。 但網站可以通過 Client Hints、能力檢測和其他指紋信號發現聲明與行為不相容,並據此做概率推斷。

Q3:UA Reduction 后,網站還能判斷 Windows 10 和 Windows 11 嗎?

僅靠縮減後的傳統 UA 通常不能可靠區分,因為兩者可能都顯示 Windows NT 10.0。 支援 UA Client Hints 的瀏覽器在網站按需請求后,可能提供更細的平臺版本資訊; 服務端仍應允許缺失和映射差異。

Q4:關閉 JavaScript 就能阻止 UA 暴露嗎?

不能完全阻止。HTTP User-Agent 是請求頭,發送頁面請求時就可能出現,不依賴頁面 JavaScript。 關閉 JavaScript 會減少部分可採集信號,但也會嚴重影響現代網站功能。

Q5:Client Hints 會徹底取代 User-Agent 嗎?

短期內不應這樣假設。 傳統 UA 仍被大量用戶端和伺服器用於相容;UA Client Hints 的支援也並不一致。 工程上應把它視為漸進增強:優先使用結構化提示,但始終準備傳統 UA 和未知狀態的回退。

Q6:隨機生成 UA 能提高匿名性嗎?

未必。 隨機 UA 可能讓單個字段變化,卻同時製造版本、平臺、觸控和渲染信號之間的矛盾。 對長期環境而言,穩定、常見且內部相容的配置通常比高頻隨機更可解釋。

11. 結語

User-Agent 從來不是可靠身份憑證,也不是無關緊要的普通字串。 它處在 Web 相容、隱私與風控的交界處:對開發者,它是歷史包袱沉重的相容輸入; 對指紋研究者,它是具有統計資訊量的一項屬性; 對瀏覽器廠商,它又是需要減少預設暴露的隱私表面。

理解 UA 的關鍵,可以壓縮成三句話:

  • 不要按自然語言直讀 UA,裡面有大量歷史相容標記;
  • 不要孤立評價 UA,真正的識別能力來自多個信號的組合與時間演化;
  • 不要把 Client Hints 理解成“更多 UA 字段”,它的價值在於結構化、按需和可治理的資訊暴露。

當系統設計從“識別瀏覽器名字”轉向“檢測需要的能力”,從“盡可能多地採集”轉向“只請求必要資訊”,UA 才會從脆弱的判斷依據,回到它更合適的位置:相容性線索,而不是身份真相。

參考文獻與標準

  1. Peter Eckersley. How Unique Is Your Web Browser?. Privacy Enhancing Technologies Symposium, 2010.
  2. Pierre Laperdrix, Nataliia Bielova, Benoit Baudry, Gildas Avoine. Browser Fingerprinting: A Survey. ACM Transactions on the Web, 2020.
  3. Antoine Vastel, Pierre Laperdrix, Walter Rudametkin, Romain Rouvoy. FP-Scanner: The Privacy Implications of Browser Fingerprint Inconsistencies. USENIX Security Symposium, 2018.
  4. Antoine Vastel, Pierre Laperdrix, Walter Rudametkin, Romain Rouvoy. FP-STALKER: Tracking Browser Fingerprint Evolutions. IEEE Symposium on Security and Privacy, 2018.
  5. IETF. RFC 9110: HTTP Semantics, 2022.
  6. IETF. RFC 8942: HTTP Client Hints, 2021.
  7. WICG. User-Agent Client Hints, Draft Community Group Report.
  8. Chromium. User-Agent Reduction.
  9. Chrome for Developers. Improve user privacy and developer experience with User-Agent Client Hints.