返回概览 更多文章

WebGL 指纹:你的显卡在向每个网站透露什么

正在通过 WebGL 读取你的 GPU……

任何网页都可以向你的浏览器打听你显卡的名字。不弹授权提示,也没有 cookie 横幅,几行 JavaScript 就够了。在一台典型的 Windows 笔记本上,拿到的答案大概长这样:ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 (0x00002503) Direct3D11 vs_5_0 ps_5_0, D3D11)。本页的小工具会告诉你,你的浏览器报的是什么。

这就是 WebGL 指纹识别。也正因如此,指纹检测工具会打印出 “WebGL fingerprinting is present”(存在 WebGL 指纹)这样的提示,或者更吓人的 “WebGL renderer info is spoofed”(WebGL 渲染器信息被伪造)。前一条对地球上几乎每一个浏览器都成立。后一条则说明你的浏览器被抓到了自相矛盾,而罪魁祸首通常是你自己装的某个扩展。

简而言之:WebGL 会把你的 GPU 暴露两次:一次是名字(未屏蔽的渲染器字符串),一次是像素(你的 GPU 如何绘制一个测试场景)。"WebGL fingerprinting is present" 只说明 WebGL 开着,这再正常不过。"Spoofed" 则意味着这两套说法互相矛盾,或者和浏览器的其他信息对不上。而把名字藏得很拙劣,比压根不藏还要扎眼。

WebGL 指纹测试会从你的浏览器里读取什么

WebGL 是浏览器调用 GPU 绘制 3D 图形的 API。Google 地图、网页游戏和 3D 商品定制器都靠它运转,而要干好这份活,它就必须跟真实的硬件打交道。指纹脚本会从两个方向利用它。

它会问。 WEBGL_debug_renderer_info 扩展增加了两个常量:UNMASKED_VENDOR_WEBGL 和 UNMASKED_RENDERER_WEBGL。这名字有点言过其实:这个扩展什么也没”揭开”,它只是返回驱动报告的 GPU 名称,而不是 “WebKit WebGL” 这类占位符。与它并列的还有几十项能力参数:最大纹理尺寸、支持的扩展、着色器精度,这些数值在不同的 GPU 家族和驱动版本之间各不相同。合在一起,它们读取成本极低,而且几个月都不会变。

它会看。 脚本在屏幕外画一个小场景,用 readPixels 把像素读回来,再算出哈希。不同的 GPU 和驱动在颜色取整、边缘混合和着色器运算上都有细微差别,所以哈希也会跟着不同。这和 canvas 指纹 是同一个思路,只是离硬件又近了一层。

人们想象中的那个名字,大概是”Intel 显卡”这种含糊的说法。真实的字符串读起来却像一张参数表:

一个字符串能泄露多少
ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 (0x00002503) Direct3D11 vs_5_0 ps_5_0, D3D11)
  • ANGLE:把 WebGL 转换成 Direct3D、Metal 或 OpenGL 调用的中间层。Chrome 在所有桌面操作系统上都通过它绘图,Firefox 只在 Windows 上如此;这种确切的格式是 Chrome 独有的。
  • GPU 厂商
  • 确切的显卡芯片,顺带还暗示了这台机器有多贵
  • PCI 设备 ID:用来区分以同一名称销售的不同芯片版本
  • Direct3D:只存在于 Windows 上
这是 Chrome 为 UNMASKED_RENDERER_WEBGL 返回的内容,不需要任何授权。通常仅凭图形 API 就能看出操作系统。

Direct3D 只存在于 Windows 上,Metal 只存在于苹果硬件上,所以在大多数机器上,光凭 GPU 字符串就能把操作系统这个问题一锤定音,不管你的 User-Agent 怎么说。这和我们在 一个浏览器,五种操作系统声明 中讲过的交叉核对是同一回事。

WebGL 指纹有多独特?

单看它自己,没你担心的那么独特。拥有 RTX 3060 的人数以百万计,每一台 M2 MacBook 报告的都是同一个字符串。WebGL 只能把你归进某个硬件分组,而指纹正是靠把一个个分组叠起来构建的。RTX 3060 很常见。可一块 RTX 3060,配一块 1440p 屏幕,处在阿姆斯特丹时区,语言设为荷兰语和英语,这样的人就只剩一小撮了。

它对追踪者的价值在于持久:你可以换浏览器、清空所有 cookie,可你的 GPU 还是那块 GPU。研究人员走得更远。2022 年的 DrawnApart 研究通过测量微小工作负载在 GPU 各个执行单元上的耗时,能把硬件完全相同、渲染器字符串也完全相同的机器区分开来。

“WebGL fingerprinting is present” 不是警告

当检测工具说 “WebGL fingerprinting is present” 时,意思只有一个:WebGL 已开启,并且可以读取。每一款主流浏览器在每一台电脑和手机上都是这个状态。这并不说明哪里出了问题,WebGL 本身也不是你需要防范的东西:隐私上的代价在于指纹,而指纹正是本文余下部分要讲的。

最诱人的修复办法是关掉 WebGL。别这么干。关掉它,等于把一块和几百万人共用的 GPU,换成一个几乎没人有的特征,还会让所有用 GPU 绘图的网站统统罢工。一个拒绝标准 API 的浏览器,也正是那种会给你招来更多 CAPTCHA 的怪胎。

为什么检测工具会说 “WebGL renderer info is spoofed”

这句话最常出现在 Cloudflare Turnstile 的故障排查工具里,挂在一项名为 “Graphics Information Appears Fake”(图形信息疑似伪造)的检查下面。人们往往是在某个验证反复转圈、死活不放行之后才翻到它的。谁也没法直接看到你的 GPU,所以检测工具无法证明你用的是什么硬件。它能做的,是把各种声明拿来互相比对,而伪造的数值很少能挺过这一关。下面就是这些测试,本页的小工具会运行前四项:

  • 图形 API 和操作系统对不上。 渲染器字符串里写着 Metal,发出它的浏览器的 User-Agent 却说自己是 Windows。
  • 供应商和渲染器各说各话。 供应商(vendor)字段还写着 NVIDIA,因为伪造只改写了渲染器字符串。
  • WebGL 函数被打了补丁。 要改变 getParameter 的返回值,扩展就得把它替换掉,而一个被粗暴替换的内置函数就不再报告 [native code] 了。藏得更好的补丁需要更精细的检查。在我们的 机器人检测测试 里,同一个陷阱也会逮住自动化工具。
  • 像素每次读取都不一样。 实际情况是,真实的 GPU 把同一个场景画两遍,返回的像素一模一样。有些反指纹扩展会在每次读取时注入新的随机噪声,于是画两次就得到两个哈希。作为一项特征,这种不稳定比市面上任何一款 GPU 都罕见。
  • 名字和像素对不上。 反欺诈厂商可以把你的渲染输出和已知设备的输出做比对。自称 RTX 3060,画出来却像 Intel 核显,渲染哈希就会把你出卖。单个浏览器没法运行这项检查,所以小工具跳过了它。

在几种配置之间切换,看看每一种会露出哪些破绽:

伪造检测工具看到了什么
上报的渲染器 ANGLE (Apple, ANGLE Metal Renderer: Apple M2, Unspecified Version)
  • 已标记
    图形 API 与操作系统相符
    Windows User-Agent 配 Metal
  • 已标记
    供应商与渲染器一致
    供应商仍写着 NVIDIA
  • 已标记
    WebGL 函数均为原生
    getParameter 已被替换
  • 通过
    同一幅画,同样的像素
    画两次,同一个哈希
换个名字,一下子就触发三项检查:新名字属于另一个操作系统,供应商字段忘了改,而替换这个动作本身就是一个被打过补丁的函数。

两种伪造配置里,GPU 本身都没毛病;每一个标记都出自伪造本身。如果你从没想过伪造什么,却收到了 “spoofed” 警告,去翻翻你的扩展列表,看看有没有 WebGL 或 canvas 的”防护”类扩展。它通常就是元凶,Cloudflare 的故障排查工具甚至直接点了其中一个的名:WebGL Fingerprint Defender。

什么时候警告是误报

不是每个标记都意味着有人动过你的浏览器。有几种再普通不过的配置也会触发检测工具:

  • 远程桌面和虚拟机。 没有真实 GPU 可用时,浏览器会退回到软件渲染器,比如 llvmpipe 或微软的 Basic Render Driver,或者干脆彻底失去 WebGL。运行机器人的服务器看起来也是这副样子,所以检测工具会对此心存怀疑。
  • 双显卡笔记本。 同时配有核显和独显的笔记本,可能因电源设置、或浏览器被分配到的显卡不同,而报告不同的 GPU。
  • 有意保护你的浏览器。 Safari 对每个网站都报告一个笼统的 “Apple GPU”。Firefox 会把渲染器名称粗化成一个宽泛的系列。Brave 给所有用户同一个通用的 GPU 名称,并给其他 WebGL 输出加上按站点变化的微小扰动,它管这叫 farbling。好的检测工具会把这些列入白名单,偷懒的照样标记。

这些情况和伪造的区别在于一致性。Safari 在苹果设备上说 “Apple GPU”,是一个大家共用的诚实回答。一个 Windows 浏览器声称自己有 Apple GPU,那就是自相矛盾。

如何修改或屏蔽你的 WebGL 指纹

  1. 保持 WebGL 开启。 禁用它只会让你更稀有,而不是更安全,还会把正经网站搞坏。
  2. 卸掉 WebGL 伪造扩展。 改名工具和噪声注入工具,恰恰制造出了检测工具要找的那种矛盾。如果上面的小工具标记出被打补丁的函数或不稳定的像素,头号嫌疑人通常就是某个扩展。
  3. 如果你需要换一个身份,就把它的每一部分都换掉。 为广告核验、电商或社交媒体运营多个账号,意味着每个配置文件都需要一块与其操作系统相符的 GPU、一个与其渲染器相符的供应商,以及与其 GPU 相符的像素。这在 JavaScript 里很难伪造,所以防关联浏览器会在引擎内部完成这件事。Incogniton 在浏览器层面为每个配置文件提供一套一致的 WebGL 身份,没有任何被打过补丁的函数可供检测工具揪出来。

然后运行一次 完整浏览器扫描,看看你的 GPU 和浏览器报告的其他一切(从时区到字体)是否对得上。

Incogniton 徽标

提升你的隐私保护

箭头