Фингерпринтинг WebGL: контроль идентичности GPU
Как строки рендерера WebGL и вывод рендеринга раскрывают идентичность вашего GPU. Техники контроля сигналов отпечатка WebGL на уровне движка.
Нужна поддерживаемая продуктовая документация?
У этой статьи есть соответствующая страница в центре документации. Используйте docs для каноничного сценария настройки, актуальных флагов и долгосрочной справки.
Введение
WebGL (Web Graphics Library) обеспечивает аппаратно-ускоренный 3D-рендеринг внутри браузера. Веб-сайты используют его для игр, визуализации данных, карт и интерактивного контента. Однако WebGL также раскрывает подробную информацию о вашем GPU: название производителя, строку рендерера, поддерживаемые расширения, форматы точности и попиксельный вывод операций рендеринга. Системы отслеживания собирают эти значения для построения GPU-отпечатка, который является высокостабильным и трудноизменяемым. Поскольку конфигурации GPU сильно различаются между устройствами, фингерпринтинг WebGL может различать пользователей даже при идентичных других сигналах. В этой статье объясняется, как работает фингерпринтинг WebGL, почему распространённые защиты недостаточны и как BotBrowser контролирует GPU-идентичность на уровне движка рендеринга.
Влияние на приватность
Фингерпринтинг WebGL является одним из наиболее мощных доступных сигналов отслеживания. Исследование Inria и KU Leuven показало, что одни строки рендерера GPU могут сузить популяцию пользователей до групп менее 100 человек. В сочетании с выводом рендеринга (отрисовка конкретной сцены и считывание пиксельных данных) уникальность значительно возрастает.
Исследование 2020 года из Университета Иллинойса продемонстрировало, что WebGL-рендеринг производит специфичный для устройства вывод, поскольку GPU реализуют арифметику с плавающей точкой, сэмплирование текстур и выполнение шейдеров с незначительными различиями на аппаратном уровне. Два GPU от разных производителей, даже при запуске одного и того же кода шейдера, производят визуально похожие, но численно различные фреймбуферы.
Масштаб применения значителен. По данным проекта Princeton Web Transparency and Accountability Project, скрипты фингерпринтинга WebGL были обнаружены на более чем 7% сайтов из топ-10 000 Alexa. Техника стала стандартным компонентом коммерческих библиотек отслеживания и используется наряду с фингерпринтингом Canvas, аудио и шрифтов для построения составных идентификаторов.
Фингерпринтинг WebGL добирается до GPU через три независимые поверхности. Диаграмма ниже показывает, что трекер собирает с каждой поверхности и как три потока сводятся в один составной идентификатор.
Третья поверхность это то, что делает фингерпринтинг WebGL трудным для нейтрализации. Строки и параметры можно переписать через JavaScript, но вывод readPixels исходит от реального вычисления GPU. Защита, которая возвращает строку производителя GPU Mac, пока framebuffer несёт пиксельные паттерны iGPU Intel, обнаруживается любой перекрёстной проверкой, которая хеширует обе поверхности и сравнивает результат.
Техническая основа
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 выполняют float-операции с разным поведением округления, особенно во фрагментных шейдерах.
- Фильтрация текстур. Реализации билинейной и трилинейной фильтрации различаются между производителями.
- Сглаживание. Реализация MSAA по умолчанию различается между архитектурами GPU.
- Оптимизации на уровне драйвера. GPU-драйверы применяют вендор-специфичные оптимизации, влияющие на пиксельный вывод.
Запросы параметров
WebGL раскрывает десятки параметров возможностей через getParameter():
MAX_TEXTURE_SIZE,MAX_VIEWPORT_DIMS,MAX_RENDERBUFFER_SIZEMAX_VERTEX_ATTRIBS,MAX_VARYING_VECTORS,MAX_FRAGMENT_UNIFORM_VECTORSALIASED_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 предотвращает фингерпринтинг, но нарушает работу значительной части современного веба. Карты, 3D-просмотрщики продуктов, информационные панели и игры зависят от WebGL. Его отключение делает ваш браузер менее функциональным и также создаёт характерный сигнал отпечатка: отсутствие WebGL само по себе необычно и отслеживаемо.
Подмена строк рендерера через расширение браузера может изменить то, что возвращает UNMASKED_RENDERER_WEBGL, но это затрагивает только одну часть отпечатка. Фактический вывод рендеринга по-прежнему приходит от вашего реального GPU. Сайт может отрисовать тестовую сцену, считать пиксели и определить ваш реальный класс GPU по характеристикам рендеринга. Несоответствие между заявленной строкой и поведением рендеринга само по себе является сильным сигналом.
Добавление шума к выводу readPixels через JavaScript-перехват модифицирует возвращаемые данные фреймбуфера. Но инъекция шума обнаруживаема: рендеринг одной и той же сцены дважды должен давать идентичный вывод. Если нет, значит, присутствует инъекция шума. Некоторые расширения пытаются кешировать и воспроизводить шум, но этот подход нарушается при динамических сценах и разнообразных вызовах отрисовки.
Использование программного рендеринга (вроде SwiftShader или Mesa llvmpipe) даёт согласованный вывод на разном оборудовании, но создаёт собственный характерный отпечаток. Программные рендереры имеют характерное поведение точности и значения параметров, которые идентифицируют их специфически.
Основная сложность в том, что фингерпринтинг WebGL комбинирует заявленные параметры с реальным выводом рендеринга. Эффективная защита должна контролировать оба одновременно.
Подход BotBrowser на уровне движка
Диаграмма ниже сопоставляет четыре распространённые модели защиты WebGL с типом перекрёстной проверки, которую выполняет современный движок фингерпринтинга. Каждая модель над уровнем движка оставляет измеримое расхождение между строками, параметрами и пикселями.
BotBrowser контролирует идентичность WebGL на уровне движка рендеринга Chromium, обеспечивая согласованность заявленных параметров и реального вывода рендеринга с загруженным профилем.
Контроль GPU-идентичности
При загрузке профиля отпечатка BotBrowser настраивает подсистему WebGL для сообщения идентичности GPU из профиля:
- Строки рендерера и производителя соответствуют целевому устройству. Профиль для системы с Intel UHD 630 сообщает точные строки рендерера и производителя этого GPU.
- Значения параметров (максимальный размер текстуры, размеры viewport, форматы точности и т.д.) все соответствуют возможностям GPU из профиля. Это не случайные значения. Они соответствуют реальным аппаратным конфигурациям.
- Списки расширений сообщают именно те расширения, которые поддерживает GPU из профиля. Никакие расширения не добавляются и не удаляются по сравнению с реальным устройством.
Согласованность вывода рендеринга
Система профилей BotBrowser включает информацию о характеристиках рендеринга целевого GPU. В сочетании с флагом --bot-noise-seed вывод рендеринга становится детерминированным и согласованным с профилированным устройством. Движок применяет контролируемую вариацию, которая производит аутентично выглядящие пиксельные данные без раскрытия вашего реального GPU.
Это покрывает:
- Точность вывода фрагментных шейдеров
- Поведение сэмплирования текстур
- Данные readPixels() для любой отрисованной сцены
- Результаты getShaderPrecisionFormat()
- Операции смешивания фреймбуфера
Покрытие WebGL2
Те же элементы управления применяются к WebGL2. Параметры, расширения и поведение рендеринга - всё выводится из профиля. Нет разрыва между защитой WebGL1 и WebGL2.
Кросс-API согласованность
BotBrowser обеспечивает согласованность данных WebGL с другими сигналами профиля. GPU, о котором сообщает WebGL, совпадает с тем, что отображается в navigator.userAgentData, что производит рендеринг Canvas и что сообщает WebGPU (при включении). Эта кросс-API согласованность критична, поскольку системы отслеживания обычно перекрёстно проверяют сигналы, связанные с GPU, через несколько API.
Конфигурация и использование
Базовая защита 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-config-webgl=profile
# Использование реального системного GPU (без защиты WebGL)
chrome --bot-profile="/path/to/profile.enc" \
--bot-config-webgl=real
# Полное отключение WebGL
chrome --bot-profile="/path/to/profile.enc" \
--bot-config-webgl=disabled
Детерминированный рендеринг с seed-шума
Для воспроизводимых отпечатков WebGL:
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-config-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-config-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-config-noise-webgl-image=false
Верификация
Для проверки работоспособности защиты WebGL:
Проверка строки рендерера. Откройте консоль браузера и запросите UNMASKED_RENDERER_WEBGL. Значение должно соответствовать целевому GPU профиля, а не вашему реальному оборудованию.
Согласованность параметров. Проверьте несколько параметров WebGL (MAX_TEXTURE_SIZE, форматы точности, список расширений) и убедитесь, что они соответствуют ожидаемым значениям для GPU из профиля.
Стабильность между сессиями. Запустите одну и ту же процедуру фингерпринтинга WebGL в двух сессиях с одним профилем и seed-шума. Результаты должны быть идентичны.
Стабильность между машинами. Запустите тест на разном оборудовании с одним профилем и seed. Отпечаток WebGL должен совпадать.
Посетите BrowserLeaks, CreepJS или аналогичные сайты тестирования отпечатков для сравнения вашего вывода WebGL с ожидаемыми значениями профиля.
Матрица верификации ниже показывает, как выглядит успех на трёх хостах с одним и тем же профилем. Идентичные строки UNMASKED, идентичные хэши readPixels для WebGL1 и WebGL2, идентичный список расширений, независимо от оборудования хоста.
Лучшие практики
- Используйте
--bot-config-webgl=profile(по умолчанию). Это обеспечивает получение всех параметров WebGL из профиля. Переключайтесь наrealтолько если вам специально нужен доступ к нативному GPU. - Комбинируйте с
--bot-noise-seedдля детерминированного вывода. Без seed шум рендеринга WebGL варьируется между сессиями. Фиксированный seed обеспечивает воспроизводимость. - Согласовывайте настройки WebGL и WebGPU. Если ваш профиль содержит данные и WebGL, и WebGPU, держите оба в режиме
profileдля поддержания согласованности. Несоответствие между GPU, о котором сообщают WebGL и WebGPU, является обнаруживаемым несоответствием. - Не переопределяйте строки рендерера вручную. BotBrowser обрабатывает это через профиль. Ручная установка строк рендерера без согласования поведения рендеринга создаёт несоответствия.
- Тестируйте на сайтах проверки отпечатков. Проверьте, что ваш отпечаток WebGL соответствует ожиданиям, перед развёртыванием в продакшен.
FAQ
В: Работает ли фингерпринтинг WebGL без расширения WEBGL_debug_renderer_info? О: Частично. Без расширения строки рендерера и производителя недоступны, но вывод рендеринга, значения параметров и форматы точности по-прежнему варьируются в зависимости от GPU. Отпечатка на основе рендеринга часто достаточно для сужения популяции пользователей.
В: Можно ли использовать BotBrowser с WebGL-интенсивными приложениями вроде 3D-игр? О: Да. Контроль WebGL BotBrowser работает на уровне идентичности и отпечатка. Производительность рендеринга обеспечивается вашим реальным GPU. Игры и 3D-приложения работают нормально.
В: Влияет ли защита WebGL на фингерпринтинг Canvas? О: Canvas 2D и WebGL используют разные пути рендеринга, но BotBrowser контролирует оба через профиль. Они производят согласованные результаты, соответствующие одному профилированному устройству.
В: Что происходит, если сайт запрашивает расширения WebGL, отсутствующие в моём профиле? О: BotBrowser сообщает только расширения, указанные в профиле. Запросы неподдерживаемых расширений возвращают null, что согласовано с поведением GPU из профиля.
В: Защищается ли WebGL2 отдельно от WebGL1?
О: Оба контролируются одним профилем и конфигурацией. Флаг --bot-config-webgl применяется как к контекстам WebGL1, так и к WebGL2.
В: Как BotBrowser обрабатывает WebGL в Web Workers? О: Контексты WebGL OffscreenCanvas в workers подчиняются тем же элементам управления на уровне движка, что и контексты основного потока. Отпечаток согласован в обоих случаях.
Итоги
Фингерпринтинг WebGL объединяет строки идентичности GPU, параметры возможностей и попиксельный вывод рендеринга для создания мощного сигнала отслеживания. Поскольку он проникает на аппаратный уровень, защиты на основе JavaScript не могут полностью его адресовать. BotBrowser контролирует идентичность и рендеринг WebGL на уровне движка Chromium, обеспечивая, что каждая поверхность API возвращает значения, согласованные с загруженным профилем отпечатка. В сочетании с --bot-noise-seed для детерминированного вывода и --bot-config-webgl для явного контроля BotBrowser обеспечивает полную защиту отпечатка WebGL.
По связанным темам смотрите Что такое фингерпринтинг браузера, Защита отпечатка WebGPU, Фингерпринтинг Canvas и Защита аудио-отпечатка.
Похожие статьи
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.