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 и бэкенда встречаются гораздо реже, чем принято считать.
Читается ли эта строка на самом деле сейчас, сильно зависит от браузера. В стандартной установке Chrome или Edge — да, по-прежнему. В Brave и Firefox — всё чаще нет; актуальную картину по браузерам см. ниже в разделе «Что теперь скрывают браузеры».
Поддерживаемые расширения
WebGL поставляется с базовым набором возможностей плюс десятками опциональных расширений. Список, возвращаемый getSupportedExtensions() — и его порядок — зависит от GPU, драйвера и версии браузера. Два устройства с одной и той же моделью GPU всё равно могут различаться здесь, если различаются их драйверы или сборки браузеров, что добавляет ещё один отличительный слой. Именно это делает список любимым инструментом хеш-фингерпринтинга: скрипту не нужно разбирать список, достаточно его хешировать — стабильный хеш работает как идентификатор ничуть не хуже самой строки, и именно это свойство теперь атакует Brave (см. раздел «Что теперь скрывают браузеры»).
Числовые параметры и точность шейдеров
WebGL раскрывает длинный список числовых ограничений, отражающих возможности оборудования: MAX_TEXTURE_SIZE, MAX_VIEWPORT_DIMS, MAX_RENDERBUFFER_SIZE, диапазоны ширины несглаженной (aliased) линии и размера точки, а также максимальное число векторов 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 + бэкенд рендеринга | Очень высокая в Chrome/Edge; в Brave 1.93+ обобщённая и неидентифицирующая | Легко переписать, но нарушает согласованность |
| Поддерживаемые расширения | Набор возможностей драйвера + браузера | Высокая; рандомизируется по сайтам в Brave 1.93+ | Умеренная — список должен оставаться внутренне согласованным |
| Числовые параметры | Ограничения возможностей оборудования | Очень высокая | Умеренная — значения взаимозависимы |
| Точность шейдеров | Поведение чисел с плавающей запятой | Высокая | Сложно — привязано к реальному кремнию |
| Хеш отрендеренных пикселей | Реальное поведение рендеринга GPU | Высокая | Очень сложно — нужно подделать реальный результат |
Поскольку метаданные и отрендеренный результат должны согласовываться друг с другом, наивная подделка нередко повышает уникальность: устройство, сообщающее строку рендерера Intel, но выдающее пиксели в стиле NVIDIA, выделяется сильнее, чем то, которое просто говорит правду.
Что теперь скрывают браузеры
Сигналы выше описывают стандартное поведение веб-платформы. Отдельные браузеры всё сильнее отклоняются от него, и по состоянию на август 2026 года разрыв между тем, «что WebGL теоретически способен прочитать», и тем, «что реально возвращает браузер конкретного посетителя», шире, чем когда-либо. Самый свежий и конкретный пример — обновление приватности Brave №38, которое включено по умолчанию в Brave 1.93 на двух платформах, которые перечисляет сама Brave, — на десктопе и в Android. Раскатка, по описанию Brave, постепенная и растянута на несколько дней, так что не все пользователи увидят её сразу. Оно меняет три сигнала из описанных выше:
- Строки производителя и рендерера деидентифицируются. Вместо того чтобы возвращать вашу настоящую модель GPU через
WEBGL_debug_renderer_info, Brave теперь заменяетUNMASKED_VENDOR_WEBGL/UNMASKED_RENDERER_WEBGLодной обобщённой строкой, одинаковой для всех пользователей Brave. Раздел выше по-прежнему верно описывает реальность для Chrome и Edge в стандартной конфигурации — но уже не описывает Brave. - Дескрипторы адаптера WebGPU обнуляются.
GPUAdapterInfo— аналог строки производителя/рендерера в мире WebGPU, раскрывающийvendor,architectureиdeviceкак полноценные свойства без каких-либо отладочных расширений — теперь обнуляется в Brave, вместо того чтобы позволить той же самой идентичности оборудования утекать через более новый API. Подробно эту поверхность мы разбираем в статье «WebGPU-фингерпринтинг: следующий GPU-идентификатор после WebGL»; коротко: Brave 1.93 закрывает её тем же способом, каким закрывает строку производителя WebGL. - Список расширений рандомизируется, а не просто скрывается. Brave вносит рандомизацию в
getSupportedExtensions(), так что хеш-фингерпринтер видит разное значение для каждой сессии браузера, каждого сайта (eTLD+1) и каждого хранилища. Это напрямую бьёт по технике хеширования, описанной выше: хеш работает как идентификатор, только если одни и те же входные данные дают одинаковый хеш на каждом сайте, который вы посещаете. Как только сам список расширений начинает меняться от сайта к сайту, вместе с ним меняется и хеш — значение, собранное трекером на сайте A, больше не совпадает со значением с сайта B, и оно полностью перестаёт работать как кросс-сайтовый идентификатор, даже если ваше оборудование никогда не менялось.
Здесь важна привязка к конкретному вендору, потому что эти защиты не универсальны. Brave по умолчанию деидентифицирует и рандомизирует данные начиная с версии 1.93. Firefox идёт другим путём: при включённом privacy.resistFingerprinting он полностью отключает WEBGL_debug_renderer_info, поэтому в этом режиме каждый пользователь Firefox получает одно и то же обобщённое значение VENDOR/RENDERER, а не рандомизированное. Chrome и Edge по умолчанию не предлагают ни деидентификации, ни рандомизации — немаскированные строки и реальный список расширений остаются читаемыми в точности так, как описано выше. Ничего из этого не означает, что фингерпринтинг «решён» хоть в одном браузере, а сама Brave прямо указывает, что раскатка функции ещё не завершена, — воспринимайте этот раздел как срез защит одного конкретного вендора, а не состояние веба в целом.
Стоит также понимать, почему настолько идентифицирующая строка вообще была читаема без какого-либо запроса разрешения. Ответ записан в самом названии расширения: WEBGL_debug_renderer_info создавалось для отладки. Ошибки рендеринга, привязанные к конкретному железу, вполне реальны, и у сайта с тяжёлой 3D-графикой есть законный повод логировать, какие сочетания GPU и драйвера дают битую картинку. Но как только расширение открывается веб-платформе в целом, вызвать его может любой сайт, а не только те, кому реально нужна диагностика, — это общая закономерность, стоящая за большинством фингерпринтинг-сигналов с высокой энтропией, которые не требуют разрешения.
Как сайты используют WebGL-фингерпринтинг
Легитимные применения распространены. Системы предотвращения мошенничества и защиты от ботов используют WebGL-отпечаток как один из многих сигналов, чтобы выявлять автоматизированный трафик, headless-браузеры и аккаунты, которые внезапно меняют оборудование. Команды аналитики и безопасности применяют его, чтобы помечать подозрительные сессии. Headless- и виртуализированные окружения нередко выдают характерные строки рендерера (например, программные растеризаторы вроде SwiftShader или llvmpipe), и именно поэтому детекторы ботов так сильно опираются на WebGL.
Та же логика согласованности распространяется не только на GPU, но и на сам браузер: строка рендерера должна соответствовать остальному окружению, включая движок рендеринга, который на самом деле отрисовал страницу. Вы можете проверить собственный движок и его версию — и заметить признаки подделки движка — с помощью проверки ядра браузера от BrowserInsight.
Та же возможность лежит в основе кросс-сайтовой рекламы и отслеживания, поскольку стабильный идентификатор, выведенный из оборудования, переживает очистку cookie и окна приватного просмотра. Эта двойственная природа и есть причина, по которой понимание WebGL-фингерпринтинга важно — будь ваш интерес в безопасности или в приватности.
Защита и её компромиссы
Идеальной защиты не существует — каждый вариант чем-то жертвует: функциональностью, производительностью или способностью «слиться с толпой». Основные подходы:
Tor Browser
Tor Browser выбирает путь стандартизации: он поставляется с единообразными настройками, чтобы все пользователи представляли один и тот же отпечаток, и запрашивает подтверждение, прежде чем вообще разрешить WebGL. Цель не в том, чтобы скрыть ваш GPU, а в том, чтобы каждый пользователь выглядел одинаково, — это самая сильная модель приватности, но ценой скорости и некоторого сломанного 3D-контента.
Brave и farbling
Brave добавляет крошечную детерминированную рандомизацию (называемую «farbling»), индивидуальную для каждой сессии и каждого сайта, к данным, поддающимся фингерпринтингу, включая считывания WebGL. Каждый сайт видит слегка отличающееся значение, и шум перетасовывается, так что построить стабильный кросс-сайтовый идентификатор трудно, при этом большинство страниц продолжают работать. Начиная с Brave 1.93 этот же подход распространился и на уровень метаданных — подробности о деидентификации строки производителя/рендерера и рандомизации списка расширений см. выше в разделе «Что теперь скрывают браузеры».
Отключение WebGL
Полное отключение WebGL (через флаги или webgl.disabled) полностью убирает эту поверхность. Это действенно, но грубо: само отсутствие WebGL отчасти необычно и может сломать карты, игры и инструменты визуализации.
Подделка значений — и почему она даёт обратный эффект
Расширения, которые переписывают строку рендерера или добавляют шум, могут помочь, но несут реальный риск. Если поддельные метаданные противоречат отрендеренным пикселям или числовым ограничениям, продвинутый детектор замечает несогласованность, и вы становитесь более идентифицируемыми, а не менее. Самая безопасная подделка — согласованная и общая для многих пользователей; стихийная индивидуальная рандомизация без координации часто достигает противоположного задуманному.
Прагматичный вывод: выбирайте защиту, которой пользуется много других людей (единообразие Tor, farbling в Brave), а не индивидуальную настройку, делающую вас уникальным. Чтобы узнать, как обстоят дела прямо сейчас, запустите инструмент обнаружения отпечатка от BrowserInsight и изучите свой рендерер WebGL, расширения и хеш.
WebGL — не последнее слово в GPU-фингерпринтинге. Более новый WebGPU API раскрывает производителя адаптера, архитектуру и строки устройства как первоклассные свойства — без каких-либо отладочных расширений. До недавнего времени это была более богатая поверхность, чем WebGL, которую почти не покрывали инструменты конфиденциальности; Brave 1.93 закрывает её, обнуляя эти дескрипторы адаптера, тогда как остальные браузеры пока раскрывают их как есть.
Рандомизация — это не анонимность
Ни одна из перечисленных защит не делает вас невидимым, и стоит явно объяснить почему. Защита, которая делает ваш браузер редким — необычное сочетание рандомизированных значений, которое больше ни у кого не встречается, — может идентифицировать вас не хуже сигнала, который она была призвана скрыть, по той же причине, по которой маскарадный костюм, который больше никто не носит, привлекает внимание. Этот компромисс и то, как его оценивать, мы разбираем в статье «Cover Your Tracks: что не доказывает оценка уникальности». Лежащее в основе понятие — сколько людей должны выглядеть точно так же, как вы, чтобы сигнал перестал годиться для повторной идентификации — объясняется в статье «Энтропия отпечатка браузера и множество анонимности». Единообразие (Tor, а теперь и деидентифицированная строка производителя у Brave) помогает именно потому, что удерживает вас внутри большой толпы; рандомизация для отдельного пользователя помогает, только если то же самое делает достаточно много других людей.
Часто задаваемые вопросы
Может ли сайт прочитать точную модель моего GPU?
Это зависит от вашего браузера. Расширение WEBGL_debug_renderer_info раскрывает немаскированную строку рендерера, которая часто называет модель вашего GPU и бэкенд рендеринга, и в стандартной конфигурации Chrome или Edge она по-прежнему читается без какого-либо запроса разрешения. Firefox отключает это расширение при включённом privacy.resistFingerprinting, а начиная с Brave 1.93 (август 2026) Brave заменяет её обобщённой строкой, одинаковой для всех пользователей Brave — актуальную картину по браузерам см. выше в разделе «Что теперь скрывают браузеры».
Работает ли WebGL-фингерпринтинг в приватном режиме / режиме инкогнито?
Да. Приватный просмотр очищает cookie и историю, но не меняет ваше оборудование. WebGL-сигналы — производитель, рендерер, расширения, числовые ограничения и отрендеренный хеш — остаются одинаковыми в обычных и приватных окнах, поэтому они могут повторно идентифицировать вас в обоих.
Достаточно ли отключить WebGL, чтобы остановить фингерпринтинг?
Это убирает поверхность WebGL, но не фингерпринтинг в целом. Canvas, аудио, шрифты, экран и другие сигналы по-прежнему действуют, а заметное отсутствие WebGL само по себе может быть отличительной чертой. Отключение — это один слой, а не полное решение.
Чем WebGL-фингерпринтинг отличается от фингерпринтинга canvas?
Фингерпринтинг canvas исследует путь 2D-рендеринга, тогда как WebGL исследует управляемый GPU 3D-путь и вдобавок раскрывает явные метаданные оборудования (производитель, рендерер, ограничения возможностей). Они коррелируют, но различны — именно поэтому трекеры собирают оба для большей уверенности.
Рекомендуем прочитать
- Обнаружение отпечатка Canvas: как сайты идентифицируют ваше устройство
- Браузерный фингерпринтинг простыми словами: как защитить свою приватность
- WebGPU-фингерпринтинг: следующий GPU-идентификатор после WebGL
- Cover Your Tracks: что не доказывает оценка уникальности
- Энтропия отпечатка браузера и множество анонимности


