返回知识中心
指纹

webgl_debug_renderer_info:GPU 向页面暴露了什么

WEBGL_debug_renderer_info 扩展返回 GPU 厂商和渲染器字符串。了解页面能读到什么、读不到什么,以及如何在自己的浏览器里验证。

BotBrowser Team

文档中心

想直接看维护中的产品文档?

这篇文章对应的主题已经有文档中心页面。需要规范流程、当前参数和长期参考时,优先看 docs。

要点: WebGL 会暴露 GPU 身份、能力参数和渲染输出。BotBrowser 支持用于授权测试的文档化配置文件控制,但不保证渲染器值、不阻止所有 WebGL 信号,也不认证硬件身份。

观看受控 WebGL 演示

这段英文视频展示了一次受控的本地演示:更改渲染器标签,并比较选定的 WebGL 读数和渲染像素。音轨为英文。

内容导航

简介

要点

WebGL(Web 图形库)在浏览器中实现硬件加速的 3D 渲染。网站将其用于游戏、数据可视化、地图和交互内容。但 WebGL 也暴露了关于 GPU 的详细信息:供应商名称、渲染器字符串、支持的扩展、精度格式以及渲染操作的像素级输出。追踪系统收集这些值来构建高度稳定且难以更改的 GPU 指纹。因为 GPU 配置在设备间差异很大,WebGL 指纹识别即使在其他信号相同的情况下也能区分用户。

W3C 定义并由 MDN 记录的 WebGL API,可用于在授权上下文中检查这些能力和隐私信号。BotBrowser 支持使用指定配置文件进行授权指纹测试所需的文档化 WebGL 控制,但不保证 GPU 渲染器值、不阻止所有 WebGL 信号,也不认证硬件身份。

隐私影响

WebGL 指纹采集面:GPU 身份、能力参数和渲染输出汇聚为复合指纹。

WebGL 指纹识别是可用的最强大追踪信号之一。Inria 和鲁汶天主教大学的研究发现,仅 GPU 渲染器字符串就能将用户群体缩小到少于 100 人的组。当与渲染输出结合时(绘制特定场景并回读像素数据),唯一性大幅增加。

伊利诺伊大学 2020 年的研究表明,WebGL 渲染产生设备特定的输出,因为 GPU 以微小的硬件级差异实现浮点算术、纹理样本总和以及着色器执行。来自不同制造商的两个 GPU,即使运行相同的着色器代码,也产生视觉上相似但数值上不同的帧缓冲区。

部署规模很大。根据普林斯顿 Web 透明度和问责项目,WebGL 指纹识别脚本在 Alexa 排名前 10,000 的网站中超过 7% 上被发现。该技术已成为商业追踪库中的标准组件,与 Canvas、音频和字体指纹识别一起使用来构建复合标识符。

WebGL 指纹通过三条独立的采集面到达 GPU。下图展示跟踪方从每条采集面拿到什么,以及三股数据如何汇成一个复合标识符。

第三个采集面才是 WebGL 指纹难以保持一致的原因。字符串和参数可以用 JavaScript 改写,但 readPixels 输出来自真实 GPU 计算。一个返回"Mac GPU vendor"字符串、却让 framebuffer 带着"Intel iGPU"像素特征的方案,会被任何同时同时比较两侧的交叉检验发现。

技术背景

WebGL 通过多种机制暴露 GPU 身份。

渲染器和供应商字符串

最直接的暴露来自 WEBGL_debug_renderer_info 扩展:

gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)
// "ANGLE (NVIDIA GeForce RTX 3080, D3D11)"

gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL)
// "Google Inc. (NVIDIA)"

这些字符串揭示了 GPU 制造商、型号,有时还有图形驱动版本。它们的唯一性足以显著缩小用户群体。

渲染输出

WebGL 渲染输出因硬件差异而在像素级别变化。指纹识别脚本可能绘制一个具有特定着色器、渐变和透明度的复杂场景,然后用 readPixels() 回读帧缓冲区。生成的像素数据被比较以评估结果稳定性。

渲染变化的来源包括:

  • 浮点精度。 不同 GPU 以不同的舍入行为处理浮点运算,特别是在片段着色器中。
  • 纹理过滤。 双线性和三线性过滤实现在供应商间不同。
  • 抗锯齿。 默认 MSAA 实现在 GPU 架构间不同。
  • 驱动级优化。 GPU 驱动应用影响像素输出的供应商特定优化。

参数查询

WebGL 通过 getParameter() 暴露数十个能力参数:

  • MAX_TEXTURE_SIZE、MAX_VIEWPORT_DIMS、MAX_RENDERBUFFER_SIZE
  • MAX_VERTEX_ATTRIBS、MAX_VARYING_VECTORS、MAX_FRAGMENT_UNIFORM_VECTORS
  • ALIASED_LINE_WIDTH_RANGE、ALIASED_POINT_SIZE_RANGE
  • 支持的压缩纹理格式、着色器精度格式和扩展

每个值反映 GPU 的能力并对整体指纹做出贡献。

WebGL2 扩展

WebGL2 增加了额外的暴露面。MAX_3D_TEXTURE_SIZE、MAX_ARRAY_TEXTURE_LAYERS 和 MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 等参数进一步区分硬件。getShaderPrecisionFormat() 方法返回每种着色器类型的精度细节,在 GPU 系列间不同。

下图显示同一段 WebGL 测试代码在四种常见 GPU 上产生的不同指纹。每一行都是真实部署里跟踪方在数据库中能看到的样本。

常见保护方法及其局限性

完全阻止 WebGL 防止了指纹识别但破坏了大量现代 Web。地图、3D 产品查看器、数据仪表板和游戏都依赖 WebGL。禁用它使你的浏览器功能更少,也创建了独特的指纹信号:WebGL 的缺失本身就是不常见且可追踪的。

伪装渲染器字符串可以改变 UNMASKED_RENDERER_WEBGL 返回的内容,但这只解决了指纹的一部分。实际渲染输出仍然来自真实 GPU。网站可以绘制测试场景、回读像素,并从渲染特征确定你的实际 GPU 类别。报告的字符串和渲染行为之间的不匹配本身就是强信号。

向 readPixels 输出添加噪声修改了返回的帧缓冲区数据。但噪声注入是可检测的:两次渲染相同场景应产生相同输出。如果不同,说明存在噪声注入。

使用软件渲染(如 SwiftShader 或 Mesa llvmpipe)在硬件间产生一致的输出,但创建了自己独特的指纹。软件渲染器具有识别它们的特征精度行为和参数值。

核心挑战在于 WebGL 指纹识别结合了报告的参数和实际渲染输出。有效的保护必须同时控制两者。

BotBrowser 的浏览器渲染行为方法

BotBrowser 在 Chromium 浏览器渲染流程中控制 WebGL 身份,确保报告的参数和实际渲染输出都与加载的配置文件一致。

下图把四种常见 WebGL 防御方案与现代指纹识别系统的交叉验证逻辑放在一起对比。渲染层之上的方案都会在字符串、参数和像素之间留下可测量的不一致。

GPU 身份控制

当加载指纹配置文件时,BotBrowser 配置 WebGL 子系统报告配置文件 GPU 的身份:

  • 渲染器和供应商字符串匹配目标设备。Intel UHD 630 系统的配置文件报告该 GPU 的精确渲染器和供应商字符串。
  • 参数值(最大纹理大小、视口尺寸、精度格式等)都匹配配置文件 GPU 的能力。这些不是随机值。它们对应真实硬件配置。
  • 扩展列表报告配置文件 GPU 支持的精确扩展。与真实设备相比,不添加也不移除扩展。

渲染输出一致性

BotBrowser 的配置文件系统包含目标 GPU 渲染特征的信息。与 --bot-noise-seed 标志结合时,渲染输出变得确定性且与配置文件设备一致。引擎应用受控变化,产生看起来真实的像素数据而不暴露你的实际 GPU。

WebGL2 覆盖

相同的控制适用于 WebGL2。参数、扩展和渲染行为都从配置文件派生。WebGL1 和 WebGL2 保护之间没有差距。

跨 API 一致性

在兼容配置文件下,BotBrowser 旨在让 WebGL 数据与其他配置文件信号对齐。WebGL 报告的 GPU 应与 navigator.userAgentData、Canvas 渲染和启用时的 WebGPU 保持一致;请按加载的配置文件验证这些关系。

配置和使用

基本 WebGL 保护

加载配置文件以配置所有 WebGL 参数:

chrome --bot-profile="path/to/profile.enc" \
       --user-data-dir="$(mktemp -d)"

WebGL 配置覆盖

独立控制 WebGL 行为:

# 使用配置文件的 WebGL 设置(默认)
chrome --bot-profile="path/to/profile.enc" \
       --bot-webgl=profile

# 使用真实系统 GPU(无 WebGL 保护)
chrome --bot-profile="path/to/profile.enc" \
       --bot-webgl=real

# 完全禁用 WebGL
chrome --bot-profile="path/to/profile.enc" \
       --bot-webgl=disabled

使用噪声种子实现确定性渲染

chrome --bot-profile="path/to/profile.enc" \
       --bot-noise-seed=42 \
       --user-data-dir="$(mktemp -d)"

Playwright 集成

const { chromium } = require('playwright');

const browser = await chromium.launch({
  executablePath: 'path/to/botbrowser/chrome',
  args: ['--bot-profile=path/to/profile.enc', '--bot-webgl=profile', '--bot-noise-seed=42'],
});

const page = await browser.newPage();
await page.goto('https://example.com');

Puppeteer 集成

const puppeteer = require('puppeteer');

const browser = await puppeteer.launch({
  executablePath: 'path/to/botbrowser/chrome',
  defaultViewport: null,
  args: ['--bot-profile=path/to/profile.enc', '--bot-webgl=profile', '--bot-noise-seed=42'],
});

const page = await browser.newPage();
await page.goto('https://example.com');

单独控制 WebGL 图像噪声

# 禁用 WebGL 图像噪声同时保持其他 WebGL 保护
chrome --bot-profile="path/to/profile.enc" \
       --bot-noise-webgl-image=false

验证

渲染器字符串检查。 打开浏览器控制台查询 UNMASKED_RENDERER_WEBGL。值应匹配配置文件的目标 GPU,而不是你的实际硬件。

参数一致性。 检查几个 WebGL 参数(MAX_TEXTURE_SIZE、精度格式、扩展列表)并确认它们匹配配置文件 GPU 的预期值。

跨会话稳定性。 使用相同配置文件和噪声种子在两个会话中运行相同的 WebGL 指纹识别例程。结果应完全相同。

跨机器稳定性。 在不同硬件上使用相同配置文件和种子运行测试。WebGL 指纹应匹配。

访问 independent WebGL diagnostics、independent WebGL diagnostics 或类似的指纹测试网站,将你的 WebGL 输出与配置文件的预期值进行比较。

下面这张验证矩阵展示同一配置文件在三台不同主机上跑出来的"成功状态"。无论底层硬件是什么,UNMASKED 字符串相同、WebGL1 和 WebGL2 的 readPixels 结果相同、扩展列表也相同。

最佳实践

  • 使用 --bot-webgl=profile(默认)。 这确保所有 WebGL 参数来自配置文件。只在特别需要原生 GPU 访问时切换到 real。
  • 与 --bot-noise-seed 结合以获得确定性输出。 没有种子,WebGL 渲染噪声在会话间变化。固定种子确保可复现性。
  • 匹配 WebGL 和 WebGPU 设置。 如果配置文件同时包含 WebGL 和 WebGPU 数据,将两者都保持在 profile 以保持一致性。WebGL 和 WebGPU 报告的 GPU 不匹配是可检测的不一致。
  • 不要手动覆盖渲染器字符串。 BotBrowser 通过配置文件处理这个。手动设置渲染器字符串而不匹配渲染行为会产生不一致。
  • 使用指纹检查网站测试。 在部署到生产之前验证你的 WebGL 指纹符合预期。

常见问题

Q: 没有 WEBGL_debug_renderer_info 扩展,WebGL 指纹识别还有效吗? A: 部分有效。没有该扩展,渲染器和供应商字符串不可用,但渲染输出、参数值和精度格式仍然因 GPU 而异。仅基于渲染的指纹通常足以缩小用户群体。

Q: 我可以在 WebGL 密集型应用如 3D 游戏中使用 BotBrowser 吗? A: 可以。BotBrowser 的 WebGL 控制在身份和指纹级别操作。渲染性能来自你的实际 GPU。游戏和 3D 应用正常工作。

Q: WebGL 保护是否影响 Canvas 指纹识别? A: Canvas 2D 和 WebGL 使用不同的渲染路径,但 BotBrowser 通过配置文件控制两者。它们产生与相同配置文件设备一致的结果。

Q: 如果网站请求不在我的配置文件中的 WebGL 扩展会怎样? A: BotBrowser 只报告配置文件中列出的扩展。不支持扩展的请求返回 null,与配置文件 GPU 的行为一致。

Q: WebGL2 是否与 WebGL1 分开保护? A: 两者都由相同的配置文件和配置控制。--bot-webgl 标志同时适用于 WebGL1 和 WebGL2 上下文。

Q: BotBrowser 如何处理 Web Workers 中的 WebGL? A: Workers 中的 OffscreenCanvas WebGL 上下文受到与主线程上下文相同的浏览器渲染层控制。指纹在两者间保持一致。

相关延伸阅读:文本测量指纹识别:亚像素追踪技术。

结论

WebGL 指纹识别结合了 GPU 身份字符串、能力参数和像素级渲染输出来创建强大的追踪信号。因为它深入硬件层,基于 JavaScript 的保护无法完全解决它。BotBrowser 在 Chromium 浏览器渲染层别控制 WebGL 身份和渲染,确保每个 API 面返回与加载的指纹配置文件一致的值。结合 --bot-noise-seed 实现确定性输出和 --bot-webgl 实现显式控制,BotBrowser 提供完整的 WebGL 指纹保护。

相关主题请参阅什么是浏览器指纹识别、WebGPU 指纹保护、Canvas 指纹识别和。

公开来源

BotBrowser 支持文档化的 WebGL 配置用于授权测试;它不能保证渲染器值、阻止所有 WebGL 信号或证明硬件身份。

#Webgl#浏览器指纹识别#Gpu#隐私#Webgl2

本文属于指南: 什么是浏览器指纹?原理、风险、信号与隐私边界

让 BotBrowser 从研究走向生产

先用这些指南理解模型,再进入跨平台验证、隔离上下文和面向规模化的浏览器部署。