header

如何识别 Brave 浏览器

最近在访问 Lobste.rs 时(后面用 🦞 代替),网站会禁止 Brave 浏览器的访问。有一点我感到很困惑,因为 Brave 在隐藏用户特征方面做了很多努力,其中包括伪装用户代理信息。这让我产生了一个疑问:🦞 是如何识别出 Brave 的?其实我也在愁统计不到 Brave。

探索

利用前端 JavaScript 识别 Brave

起初,我以为 🦞 是通过前端 JS 进行识别的。因为在禁用 JS 后,我发现可以正常访问 🦞。Brave 浏览器提供了一些独特的 API,比如 Wallet,甚至还提供了一个 isBrave 函数。通过这些 API,很容易在前端检测到用户是否在使用 Brave 浏览器。

console.log(window.braveEthereum); // Brave 独有的 Wallet API
console.log(navigator.Brave.isBrave); // 检测是否为 Brave 浏览器

然而,在进一步分析中,我并未在页面发现任何 JS 代码。尤其是在未登录的情况下,🦞 不会加载任何 JS。表明这并非其识别手段。

基于链接参数移除的推断

在 🦞 相关的 Issue 中,我发现了一种基于链接参数的识别方法。Brave 的隐私保护策略之一是自动移除一些常见的跟踪参数。例如:

/detect-brave?gclid=3&fbclid=2&sub=marine

如果后端检测到 gclidfbclid 等参数被移除,可以推断用户可能使用的是 Brave 浏览器。

但这种方法并不可靠。其他工具(例如 Firefox 安装 ClearURLs 扩展后)也会移除这些参数,导致误判。

通过 Client Hint 的识别

在分析请求头时,我注意到了一组没见过的 Header —— sec-ch-ua 包含 Brave,这是 Client Hint 的一部分,用于替代传统的 User-Agent 字符串。目前也只有 Chromium 系浏览器支持,估计是作为 Privacy Sandbox 的一部分,遭到了 Mozilla 和 Apple 的反对。

Client Hint 的目的是为网站提供更精确的设备信息,例如屏幕宽度也能加到 Header。Client Hint 默认不会发送所有的信息,只有在服务器显式请求后,浏览器才会返回相关信息。但是浏览器和平台的信息默认是会发送的。

Client Hint 默认会提供的信息:

Sec-CH-UA: "Brave";v="131", "Chromium";v="131", "Not_A Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"

我通过 HTTPie 模拟了请求,结果证实 🦞 确实是通过 Sec-CH-UA 识别 Brave 浏览器的。

有趣的是,禁用 JavaScript 后,Brave 不再发送 Client Hint 的头,这也是为什么禁用 JS 后能够成功访问 🦞 的原因。

(伪装成 Chrome,但又没有完全伪装

尝试 Client Hint

之后我尝试用 Client Hint 统计浏览器,发现某些国产浏览器 (比如 UC) User-Agent 显示其正确名字,Sec-CH-UA 却返回一个 Chromium? like Chrome? 如果只用 Sec-CH-UA 的话目前比传统 UA 更不靠谱。

2024(确实 2024)年还能看到有网站在跟浏览器玩猫捉老鼠的游戏就挺搞的,最终不过是重复 Mozilla/5.0 的历史(大家都变成 Chrome 就好了,实际上也差不多了)。尽管我也很讨厌 Brave 塞的那些币圈垃圾。

Vivaldi 也是因为收到太多不兼容的报告,被迫默认改为跟 Chrome 一致的 UA。

中途我还发现 Brave 维护了一个长长的清单,禁止 Brave 的网站都会被拉到清单里,对清单里的网站会隐藏自身独特的 API 防止被检测到。

本作品采用知识共享署名-非商业性使用-相同方式共享 (CC BY-NC-SA) 协议进行许可。
评论
由于是静态页面,评论提交后不会立即显示,这里 查看提交的评论。