Как формируется браузерный отпечаток: Canvas, WebGL и данные устройства
Опубликовано: Время чтения: ≈ 6 мин
Браузерный отпечаток (Фингерпринт) — это уникальный идентификатор вашего устройства. В отличие от привычных всем файлов cookie, этот отпечаток не хранится на клиентском устройстве. Сервер вычисляет его динамически при каждом вашем визите на конкретный ресурс. Вычисление происходит через сбор характеристик операционной системы устройства и аппаратного обеспечения.
Каждое устройство имеет разный набор данных, начиная аппаратными характеристиками, внутренним наполнением и заканчивая специфическими шрифтами, драйверами и даже версиями операционных систем. Собранные данные преобразуются в буквенно-цифровой хэш, который и принято называть фингерпринтом.
Как не бывает одинакового внутреннего содержимого женских сумочек, так и каждое устройство имеет свои отличия. Даже, незначительное изменение (например, версии драйвера) уже меняет конечный хэш и он получается другим.
Вот как выглядит хэш — d41d8cd98f00b204e9800998ecf8427e
Почему VPN и прокси не скрывают отпечаток?
Возникает закономерный вопрос, можно ли замаскировать свой отпечаток использованием VPN или прокси? Короткий ответ — нет, нельзя.
VPN и прокси работают на уровне изменения маршрутизации сетевого трафика и подменяют только IP-адрес источника, но это никак не влияет на исполнение клиентского кода.
Когда сервер присылает JavaScript-запрос — на отрисовку невидимой графики или проверку аудиодрайвера — ваш браузер выполняет его на реальном физическом оборудовании. Результат этого вычисления отправляется обратно на сервер, и нет никакой разницы, как именно сервер получит эти данные, напрямую с вашего реального IP либо через VPN-туннель (прокси), данные от этого не изменятся.
Как именно собираются аппаратные хэши — механика сбора
Процесс получения нужных антифрод-системе данных максимально прост, и нет необходимости в использовании уязвимостей системы или сложных хакерских методов. Для того, чтобы вытащить практический любой хэш достаточно базового интерфейса браузера. Так сложилось, что браузеры сильно «разговорчивы», при правильном подходе.
Существует несколько простых скриптов, с помощью которых сервер может вытащить требуемую ему информации о пользовательском устройстве.
Canvas Fingerprinting
Наиболее очевидная и самая информативная проверка, которая формирует в итоге общий хэш — Canvas-фингерпринт.
Скрипт сервера заставляет браузер в фоновом режиме отрисовать скрытое 2D-изображение. У каждого устройства результат этой отрисовки будет уникальным, не на уровне человеческого восприятия, а на машинном уровне. Так как даже микроскопическая разница в архитектуре видеокарт, алгоритмах сглаживания или банальных версиях драйверов, приводит к разному результату на уровне субпикселей — хэши тоже получаются разными.
Вот пример скрипта, который запрашивает отрисовку:
const canvas = document.createElement(‘canvas’);
const ctx = canvas.getContext(‘2d’);
ctx.textBaseline = «top»;
ctx.font = «14px ‘Arial'»;
ctx.fillText(«Fingerprint_Test_String», 2, 2);
const hash = canvas.toDataURL()

По хэшу, полученному в результате этой проверки антифрод может явно определить рассинхрон в цифровом отпечатке. Если, к примеру происходит подмена или внесение шума в итоговый хэш, антифрод системе будет достаточно сверить результат с имеющейся у нее накопленной базой устройств и принадлежащих им хэшей, чтобы увидеть рассинхрон.
Почему так? Каждое устройство имеет свой неповторимый отпечаток Canvas, характерный только ему и хороший антифрод это знает. Он может сопоставить хэш из базы с тем, что ему отдала система. И представьте ситуацию, браузер сообщил серверу, что пользователь зашел на сайт с дискретной видеокартой, а хэш отрисован топовой игровой. Вот и несовпадение, казалось бы мелочь, но на общий Trust Score такие рассинхроны сильно влияют.
WebGL Fingerprinting
Этот метод аналогичен Canvas, но работает с 3D-контекстом. Он позволяет напрямую запросить у браузера константы вашей видеокарты. Выполняется это простым скриптом:
const gl = document.createElement(‘canvas’).getContext(‘webgl’);
const debugInfo = gl.getExtension(‘WEBGL_debug_renderer_info’);
const vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);

При использовании этого метода WebGL выдает реальное название графического чипа, и это обесценивает любые попытки примитивной подмены User-Agent с помощью обычных расширений.
Сопоставление имеющихся данных и полученного хэша актуально и для этого параметра.
Аппаратный параллелизм (Hardware Concurrency)
Помимо генерации хэшей, антифрод сверяет много других параметров, которые косвенно могут указывать на то, что сессия управляется ботом или скриптом.
Возьмем к примеру данные о многозадачности процессора (аппаратный параллелизм). С помощью JavaScript сервер запрашивает количество логических ядер процессора, доступных для выполнения потоков напрямую.
const cores = navigator.hardwareConcurrency;
console.log(`Доступно ядер: ${cores}`);

Результаты этого параметра при сопоставлении с другими данными, которые браузер передает антифроду, эффективно отсекает ботов и попытки запуска ресурсоемких задач на слабых виртуальных машинах. Сервер, запрашивая эти данные, увидит несоответствие, если заявленный User-Agent принадлежит, например Mac, а системе выделено всего 2 ядра.
Правильная подмена
В каком может произойти рассинхрон между подменяемыми параметрами и реальными? Когда пользователь при использовании антидетект-браузера выполняет автоматическую генерацию фингерпринта.
Как работает классическая генерация, которая используется у подавляющего большинства антидетектов:
- Пользователь не хочет собирать отпечаток браузера руками и использует кнопку — сгенерить фингерпринт.
- Алгоритм подбирает реалистичный отпечаток устройства (любого рандомного устройства) и совсем не обязательно, что это устройство, похожее на то, где запущен клиент.
И в этой схеме нет ничего критичного, кроме одной части — когда антифрод начинает сверять переданный ему отпечаток со своей базой скорее всего он получит рассинхрон, как раз по степени совпадения отпечатков.
Но рынок не стоит на месте и начали появляться более умные алгоритмы генерации фингерпринтов, яркий пример — ИИ-фингерпринт от антидетект-браузера Aurorium.
Тут схема уже работает иначе стандартной генерации. Перед тем как создать отпечаток ИИ анализирует клиентское ПО (его технические характеристики) и подбирает такой фингерпринт, который максимально похож на клиентский. Чувствуете разницу? Антифрод не найдет рассинхрона в похожих отпечатках.
Практические ошибки: как пользователи выдают себя
Непонимание работы браузерных API приводит к типичным ошибкам при попытках автоматизации или при ручной настройке приватности.
- Сценарий 1: Утечка через UDP и WebRTC Пользователь настраивает HTTP/SOCKS прокси для скрытия IP-адреса. Однако протокол WebRTC, который используется для peer-to-peer соединений, работает поверх UDP. Если прокси не поддерживает UDP (или браузер не настроен на принудительную маршрутизацию WebRTC через TCP), протокол отправляет STUN-запрос напрямую, минуя туннель. В результате сервер получает реальный локальный и внешний IP-адреса сетевого интерфейса.
- Сценарий 2: Маркеры headless-браузеров При запуске Puppeteer или Selenium без глубокой кастомизации, ядро Chromium отдает специфические маркеры. Так, переменная navigator.webdriver по умолчанию возвращает true. Антифрод-системе даже не нужно ничего делать, тем более собирать Canvas — одной этой переменной достаточно для блокировки сессии по причине использования фреймворка автоматизации.
- Сценарий 3: Парадокс подмены Пользователь отключает выполнение JavaScript или ставит блокировщик Canvas. Что видит антифрод? Максимально нетипичный профиль, у которого метод toDataURL() возвращает пустую строку или ошибку. Топорная блокировка делает пользователя наоборот более уникальным и подозрительным, чем наличие стандартного отпечатка.
Как работает реальная защита
Логика работы профессиональных антидетект-решений строится не на блокировке скриптов, а на статистическом слиянии.
Задача такого ПО — перехватить вызовы функций вроде getContext или getParameter на уровне ядра браузера (еще до того, как их получит JS-скрипт сайта) и внедрить в них консистентный шум.
В результате сайт успешно собирает данные и формирует отпечаток, но антифрод классифицирует его как стандартный профиль обычного пользователя, не вызывая никаких подозрений.
Часто задаваемые вопросы
Здесь мы ответили на самые часто задаваемые вопросы. Все равно не можешь найти ответа?
Можно ли скрыть браузерный фингерпринт с помощью прокси или VPN?
Нет. Прокси и VPN меняют IP-адрес и маршрут трафика, но не характеристики устройства и браузера, из которых формируется цифровой отпечаток.
Какие данные используются для создания фингерпринта?
Почему простая блокировка Canvas или JavaScript не всегда помогает?
Полное отключение отдельных браузерных функций само по себе может сделать профиль необычным. Антифрод-системы оценивают не только отдельные параметры, но и их согласованность между собой.