WebGL нужен не только для красивых веб-эффектов — с его помощью отслеживают пользователей. Как работает WebGL-фингерпринтинг и как от него защититься.
WebGL-фингерпринтинг идентифицирует ваше устройство, запрашивая данные у графического оборудования и наблюдая за тем, как именно оно рендерит трёхмерные сцены. Поскольку каждая комбинация модели GPU, версии драйвера и операционной системы даёт чуть отличающийся результат и сообщает чуть отличающиеся возможности, сайт может прочитать строки производителя и рендерера вашего GPU, перечислить поддерживаемые расширения и числовые ограничения, а также хешировать отрендеренное изображение в стабильный идентификатор — и всё это без разрешения, cookie или хранилища. Именно это делает WebGL одним из сигналов с наибольшей энтропией в современном браузерном фингерпринтинге.
Что такое WebGL и почему он раскрывает идентичность оборудования
WebGL — это JavaScript API, который даёт веб-страницам низкоуровневый доступ к GPU для аппаратно-ускоренной 2D- и 3D-графики. По сути это привязка браузера к OpenGL ES, а значит, вызывая WebGL, вы спускаетесь сквозь браузер и графический драйвер к физическому графическому процессору внутри вашей машины.
Именно этот глубокий доступ и превращает WebGL в золотую жилу для фингерпринтинга. Чтобы рисовать эффективно, WebGL вынужден раскрывать, на что способно ваше оборудование: какой максимальный размер текстуры оно поддерживает, какие опциональные возможности доступны, как его шейдеры округляют числа с плавающей запятой. Кроме того, он выдаёт результат, зависящий от оборудования: одни и те же инструкции рисования дают слегка разные пиксели на карте NVIDIA, на GPU Apple и на встроенном чипе Intel, потому что каждое устройство по-своему реализует растеризацию, сглаживание и арифметику с плавающей запятой.
Существуют два больших семейства WebGL-сигналов: объявленные метаданные (строки и числа, которые GPU сообщает о самом себе) и отрендеренный результат (реальные пиксели, получаемые при отрисовке сцены). Вместе они дополняют фингерпринтинг Canvas, который исследует путь 2D-рендеринга, и оба вписываются в более широкую картину, описанную в нашем руководстве по браузерному фингерпринтингу.
Точки данных с высокой информативностью
Строки производителя и рендерера GPU
Самый идентифицирующий WebGL-сигнал — это немаскированные строки производителя и рендерера. По умолчанию стандартные параметры VENDOR и RENDERER возвращают обобщённые значения, но расширение WEBGL_debug_renderer_info раскрывает настоящую идентичность оборудования — строки вроде Google Inc. (NVIDIA) и ANGLE (NVIDIA, NVIDIA GeForce RTX 3070 Direct3D11 vs_5_0 ps_5_0, D3D11).
Эта строка часто раскрывает модель вашего GPU, бэкенд рендеринга (Direct3D, Metal, OpenGL через ANGLE), а иногда и драйвер. Сама по себе она способна сузить круг до небольшой доли пользователей, потому что точные сочетания GPU и бэкенда встречаются гораздо реже, чем принято считать.
Поддерживаемые расширения
WebGL поставляется с базовым набором возможностей плюс десятками опциональных расширений. Список, возвращаемый getSupportedExtensions() — и его порядок — зависит от GPU, драйвера и версии браузера. Два устройства с одним и тем же флагманским GPU всё равно могут различаться здесь, если различаются их драйверы или сборки браузеров, что добавляет ещё один отличительный слой.
Числовые параметры и точность шейдеров
WebGL раскрывает длинный список числовых ограничений, отражающих возможности оборудования: MAX_TEXTURE_SIZE, MAX_VIEWPORT_DIMS, MAX_RENDERBUFFER_SIZE, диапазоны ширины сглаженной линии и размера точки, а также максимальное число векторов uniform для вершинного и фрагментного шейдеров. Точность шейдеров — запрашиваемая через getShaderPrecisionFormat() для форматов high/medium/low float и int — добавляет ещё больше детализации, поскольку поведение точности привязано к самому кремнию.
Хеширование на основе рендеринга
Самая мощная техника повторяет фингерпринтинг canvas, но проводит его через GPU. Скрипт рендерит намеренно непростую сцену — градиенты, освещение, прозрачность, изогнутую геометрию, — считывает пиксели обратно с помощью readPixels() и хеширует их. Различия в округлении чисел с плавающей запятой, сглаживании и фильтрации текстур между разными GPU и драйверами дают стабильный хеш, который отличается у разных семейств оборудования. Поскольку он фиксирует поведение, а не только объявленные значения, его гораздо труднее убедительно подделать, чем строку метаданных.
Практический взгляд на код
Фрагмент ниже собирает основные WebGL-сигналы, которые собрал бы фингерпринтинг-скрипт. Эквивалентные живые результаты для вашего собственного браузера можно увидеть с помощью инструмента обнаружения отпечатка от BrowserInsight.
function getWebGLFingerprint() {
const canvas = document.createElement('canvas');
const gl =
canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) return { supported: false };
// 1. Немаскированные производитель + рендерер GPU через debug-расширение
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
const vendor = debugInfo
? gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL)
: gl.getParameter(gl.VENDOR);
const renderer = debugInfo
? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)
: gl.getParameter(gl.RENDERER);
// 2. Числовые ограничения возможностей
const params = {
maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE),
maxViewportDims: gl.getParameter(gl.MAX_VIEWPORT_DIMS),
maxRenderbufferSize: gl.getParameter(gl.MAX_RENDERBUFFER_SIZE),
aliasedLineWidth: gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE),
};
// 3. Точность шейдера для формата high-float фрагментного шейдера
const precision = gl.getShaderPrecisionFormat(
gl.FRAGMENT_SHADER,
gl.HIGH_FLOAT
);
// 4. Поддерживаемые расширения (важны и наличие, и порядок)
const extensions = gl.getSupportedExtensions();
return {
supported: true,
vendor,
renderer,
params,
precision: { rangeMin: precision.rangeMin, prec: precision.precision },
extensions,
};
}
Хеш на основе рендеринга идёт ещё дальше: он компилирует шейдер, рисует фигуру с градиентным освещением, вызывает gl.readPixels() в типизированный массив и пропускает этот массив через хеш-функцию. Полученное значение остаётся постоянным для вашего устройства, но различается между разными типами оборудования.
Сколько энтропии добавляет WebGL
Энтропия измеряет, насколько сильно сигнал сужает круг того, кто вы есть. WebGL ценен для трекеров именно потому, что несёт её много и остаётся стабильным: ваш GPU не меняется между загрузками страниц, а большинство пользователей никогда не меняет драйвер. Строка производителя/рендерера, список расширений, числовые ограничения и отрендеренный хеш частично коррелируют — все они происходят от одного и того же оборудования, — но каждый улавливает то, что упускают другие.
На практике WebGL редко используется в одиночку. Его комбинируют с canvas, аудио, шрифтами, метриками экрана и десятками других атрибутов. Таблица ниже сопоставляет основные типы WebGL-сигналов и то, насколько легко каждый из них подделать.
| Сигнал WebGL | Что раскрывает | Стабильность | Сложность подделки |
|---|---|---|---|
| Строка производителя / рендерера | Модель GPU + бэкенд рендеринга | Очень высокая | Легко переписать, но нарушает согласованность |
| Поддерживаемые расширения | Набор возможностей драйвера + браузера | Высокая | Умеренная — список должен оставаться внутренне согласованным |
| Числовые параметры | Ограничения возможностей оборудования | Очень высокая | Умеренная — значения взаимозависимы |
| Точность шейдеров | Поведение чисел с плавающей запятой | Высокая | Сложно — привязано к реальному кремнию |
| Хеш отрендеренных пикселей | Реальное поведение рендеринга GPU | Высокая | Очень сложно — нужно подделать реальный результат |
Поскольку метаданные и отрендеренный результат должны согласовываться друг с другом, наивная подделка нередко повышает уникальность: устройство, сообщающее строку рендерера Intel, но выдающее пиксели в стиле NVIDIA, выделяется сильнее, чем то, которое просто говорит правду.
Как сайты используют WebGL-фингерпринтинг
Легитимные применения распространены. Системы предотвращения мошенничества и защиты от ботов используют WebGL-отпечаток как один из многих сигналов, чтобы выявлять автоматизированный трафик, headless-браузеры и аккаунты, которые внезапно меняют оборудование. Команды аналитики и безопасности применяют его, чтобы помечать подозрительные сессии. Headless- и виртуализированные окружения нередко выдают характерные строки рендерера (например, программные растеризаторы вроде SwiftShader или llvmpipe), и именно поэтому детекторы ботов так сильно опираются на WebGL.
Та же возможность лежит в основе кросс-сайтовой рекламы и отслеживания, поскольку стабильный идентификатор, выведенный из оборудования, переживает очистку cookie и окна приватного просмотра. Эта двойственная природа и есть причина, по которой понимание WebGL-фингерпринтинга важно — будь ваш интерес в безопасности или в приватности.
Защита и её компромиссы
Идеальной защиты не существует — каждый вариант чем-то жертвует: функциональностью, производительностью или способностью «слиться с толпой». Основные подходы:
Tor Browser
Tor Browser выбирает путь стандартизации: он поставляется с единообразными настройками, чтобы все пользователи представляли один и тот же отпечаток, и запрашивает подтверждение, прежде чем вообще разрешить WebGL. Цель не в том, чтобы скрыть ваш GPU, а в том, чтобы каждый пользователь выглядел одинаково, — это самая сильная модель приватности, но ценой скорости и некоторого сломанного 3D-контента.
Brave и farbling
Brave добавляет крошечную детерминированную рандомизацию (называемую «farbling»), индивидуальную для каждой сессии и каждого сайта, к данным, поддающимся фингерпринтингу, включая считывания WebGL. Каждый сайт видит слегка отличающееся значение, и шум перетасовывается, так что построить стабильный кросс-сайтовый идентификатор трудно, при этом большинство страниц продолжают работать.
Отключение WebGL
Полное отключение WebGL (через флаги или webgl.disabled) полностью убирает эту поверхность. Это действенно, но грубо: само отсутствие WebGL отчасти необычно и может сломать карты, игры и инструменты визуализации.
Подделка значений — и почему она даёт обратный эффект
Расширения, которые переписывают строку рендерера или добавляют шум, могут помочь, но несут реальный риск. Если поддельные метаданные противоречат отрендеренным пикселям или числовым ограничениям, продвинутый детектор замечает несогласованность, и вы становитесь более идентифицируемыми, а не менее. Самая безопасная подделка — согласованная и общая для многих пользователей; стихийная индивидуальная рандомизация без координации часто достигает противоположного задуманному.
Прагматичный вывод: выбирайте защиту, которой пользуется много других людей (единообразие Tor, farbling в Brave), а не индивидуальную настройку, делающую вас уникальным. Чтобы узнать, как обстоят дела прямо сейчас, запустите инструмент обнаружения отпечатка от BrowserInsight и изучите свой рендерер WebGL, расширения и хеш.
WebGL — не последнее слово в GPU-фингерпринтинге. Более новый WebGPU API раскрывает производителя адаптера, архитектуру и строки устройства как первоклассные свойства — без каких-либо отладочных расширений — образуя ещё более богатую поверхность, которую большинство инструментов конфиденциальности пока не покрывает.
Часто задаваемые вопросы
Может ли сайт прочитать точную модель моего GPU?
В большинстве браузеров — да. Расширение WEBGL_debug_renderer_info раскрывает немаскированную строку рендерера, которая часто называет модель вашего GPU и бэкенд рендеринга. Некоторые приватные браузеры ограничивают или рандомизируют это, но в стандартной конфигурации Chrome или Edge оно читается без какого-либо запроса разрешения.
Работает ли WebGL-фингерпринтинг в приватном режиме / режиме инкогнито?
Да. Приватный просмотр очищает cookie и историю, но не меняет ваше оборудование. WebGL-сигналы — производитель, рендерер, расширения, числовые ограничения и отрендеренный хеш — остаются одинаковыми в обычных и приватных окнах, поэтому они могут повторно идентифицировать вас в обоих.
Достаточно ли отключить WebGL, чтобы остановить фингерпринтинг?
Это убирает поверхность WebGL, но не фингерпринтинг в целом. Canvas, аудио, шрифты, экран и другие сигналы по-прежнему действуют, а заметное отсутствие WebGL само по себе может быть отличительной чертой. Отключение — это один слой, а не полное решение.
Чем WebGL-фингерпринтинг отличается от фингерпринтинга canvas?
Фингерпринтинг canvas исследует путь 2D-рендеринга, тогда как WebGL исследует управляемый GPU 3D-путь и вдобавок раскрывает явные метаданные оборудования (производитель, рендерер, ограничения возможностей). Они коррелируют, но различны — именно поэтому трекеры собирают оба для большей уверенности.


