вернуться к обзору Больше статей

Отпечаток WebGL: что ваша видеокарта рассказывает каждому сайту

Считываем ваш GPU через WebGL...

Любая веб-страница может спросить у браузера, какая у вас видеокарта. Без запроса разрешений, без баннера про cookie — несколько строк JavaScript. На типичном Windows-ноутбуке ответ выглядит примерно так: ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 (0x00002503) Direct3D11 vs_5_0 ps_5_0, D3D11), а виджет на этой странице покажет, что говорит ваш.

Это и есть WebGL fingerprinting — снятие отпечатка через WebGL. Именно из-за него чекеры отпечатков выдают строки вроде «WebGL fingerprinting is present» или, что звучит куда тревожнее, «WebGL renderer info is spoofed». Первое верно почти для любого браузера на планете. Второе означает, что ваш браузер поймали на противоречии самому себе — обычно из-за расширения, которое вы же и установили.

Если коротко: WebGL выдаёт ваш GPU дважды: один раз по имени (немаскированная строка рендерера) и один раз через пиксели (то, как ваш GPU рисует тестовую сцену). «WebGL fingerprinting is present» означает лишь, что WebGL включён, — это нормально. «Spoofed» значит, что эти две версии противоречат друг другу или остальному браузеру, а неумело спрятанное имя выдаёт вас сильнее, чем честное.

Что тест отпечатка WebGL считывает в вашем браузере

WebGL — это браузерный API для отрисовки 3D-графики силами вашего GPU. На нём работают Google Maps, браузерные игры и 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 device ID: различает варианты чипа, которые продаются под одним и тем же названием
  • Direct3D: существует только в Windows
Вот что Chrome возвращает на запрос UNMASKED_RENDERER_WEBGL — не спрашивая никаких разрешений. Графический API обычно и сам выдаёт операционную систему.

Direct3D существует только в Windows, а Metal — только на железе Apple, поэтому на большинстве машин строка GPU сама по себе закрывает вопрос об операционной системе, что бы там ни утверждал ваш User-Agent. Это та же перекрёстная проверка, которую мы разбирали в статье Один браузер, пять версий ОС.

Насколько уникален отпечаток WebGL?

Сам по себе — меньше, чем можно опасаться. RTX 3060 стоит у миллионов людей, а каждый MacBook на M2 сообщает одну и ту же строку. WebGL сужает круг до «корзины» железа, а отпечаток складывается как раз из наложения таких корзин. RTX 3060 — дело обычное. RTX 3060 с экраном 1440p, в часовом поясе Амстердама, с нидерландским и английским в языковых настройках — это уже небольшая толпа.

Ценность для трекеров — в постоянстве: можно сменить браузер и стереть все cookie, а GPU останется прежним. Исследователи пошли ещё дальше. В работе DrawnApart 2022 года замеряли время выполнения крошечных задач на исполнительных блоках 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 и renderer расходятся. Поле производителя (vendor) по-прежнему говорит NVIDIA, потому что подмена переписала только renderer.
  • Функции WebGL пропатчены. Чтобы изменить то, что возвращает getParameter, расширению приходится его подменить, а наивно подменённая встроенная функция перестаёт сообщать [native code]. Для патчей, спрятанных получше, нужны проверки потоньше. В ту же ловушку попадают инструменты автоматизации в нашем тесте на обнаружение ботов.
  • Пиксели меняются между чтениями. На практике настоящий GPU, дважды нарисовав одну и ту же сцену, возвращает одинаковые пиксели. Некоторые расширения против фингерпринтинга подмешивают свежий случайный шум при каждом чтении, так что два рендера дают два хеша. Такая нестабильность встречается реже, чем любой GPU на рынке.
  • Имя не совпадает с пикселями. Антифрод-системы могут сравнить результат вашего рендеринга с тем, что выдают известные устройства. Заявите RTX 3060, а рисуйте как встроенная графика Intel — и хеш рендера вас выдаст. Отдельный браузер такую проверку провести не может, поэтому виджет её пропускает.

Переключайте варианты и смотрите, на каких приметах попадается каждый:

Что видит чекер подмены
Заявленный рендерер ANGLE (Apple, ANGLE Metal Renderer: Apple M2, Unspecified Version)
  • отмечено
    Графический API подходит к ОС
    Metal при User-Agent от Windows
  • отмечено
    Vendor совпадает с renderer
    vendor всё ещё говорит NVIDIA
  • отмечено
    Функции WebGL нативные
    getParameter подменён
  • пройдено
    Тот же рисунок — те же пиксели
    два рендера, один хеш
Замена имени проваливает сразу три проверки: новое имя принадлежит другой ОС, поле vendor забыли поправить, а сама замена — это пропатченная функция.

В обоих вариантах с подменой с самим GPU всё в порядке — каждый флаг вызван подменой. Если вы получили предупреждение «spoofed», даже не пытаясь ничего подделывать, проверьте список расширений на WebGL- или canvas-«защитника». Обычно виноват именно он, а средство диагностики Cloudflare прямо называет одного из них по имени — WebGL Fingerprint Defender.

Когда предупреждение — ложная тревога

Не каждый флаг означает, что в ваш браузер кто-то влез. Несколько вполне обычных конфигураций тоже цепляют чекеры:

  • Удалённый рабочий стол и виртуальные машины. Когда настоящего GPU нет, браузер откатывается на программный рендерер вроде llvmpipe или Microsoft Basic Render Driver — либо остаётся без WebGL совсем. Серверы, на которых крутятся боты, выглядят точно так же, поэтому чекеры относятся к этому с подозрением.
  • Ноутбуки с двумя видеокартами. Ноутбук со встроенной и дискретной графикой может сообщать разные GPU в зависимости от настроек питания или от того, какую карту выделили браузеру.
  • Браузеры, которые защищают вас намеренно. Safari сообщает любому сайту обезличенное «Apple GPU». Firefox огрубляет имя рендерера до широкого семейства. Brave выдаёт всем пользователям одно и то же обобщённое имя GPU, а к остальным выходным данным WebGL добавляет небольшие вариации, свои для каждого сайта, — в Brave это называют farbling. Хорошие чекеры держат такие браузеры в белом списке. Ленивые помечают всё равно.

Разница между ними и подменой — в согласованности. Safari, говорящий «Apple GPU» на устройстве Apple, даёт честный ответ, общий для множества людей. Браузер под Windows, заявляющий GPU от Apple, — это противоречие.

Как изменить или заблокировать отпечаток WebGL

  1. Оставьте WebGL включённым. Отключение делает вас более редким, а не более защищённым, и ломает настоящие сайты.
  2. Удалите расширения для подмены WebGL. Подменщики имени и расширения, подмешивающие шум WebGL, создают ровно те противоречия, которые ищут чекеры. Если виджет выше отмечает пропатченные функции или нестабильные пиксели, первый подозреваемый — расширение.
  3. Если нужна другая личность, меняйте её целиком. Когда вы ведёте несколько аккаунтов для проверки рекламы, e-commerce или соцсетей, каждому профилю нужен GPU, подходящий к его операционной системе, vendor, подходящий к renderer, и пиксели, подходящие к GPU. Подделать всё это на JavaScript трудно, поэтому антидетект-браузеры делают это внутри движка. Incogniton даёт каждому профилю согласованный отпечаток WebGL на уровне самого браузера — без пропатченных функций, которые мог бы найти чекер.

А затем запустите полное сканирование браузера и посмотрите, как ваш GPU сочетается со всем остальным, что сообщает браузер, — от часового пояса до шрифтов.

Логотип Incogniton

Повысьте уровень своей приватности

Стрелка