Отпечатки

Детерминированный режим: воспроизводимые отпечатки

Как создавать идентичные отпечатки браузера между сессиями с помощью контроля сида шума для согласованного вывода Canvas, WebGL и Audio.

Документация

Нужна структурированная документация по теме Отпечатки?

Эта статья относится к редакционной библиотеке. Для пошаговой настройки, справки и постоянных обновлений переходите сразу в соответствующий раздел docs.

Введение

Фингерпринтинг браузера опирается на сигналы, стабильные в рамках сессии, но различающиеся между устройствами. Обратная сторона этой проблемы - воспроизводимость: когда вам нужно, чтобы несколько браузерных сессий представляли одну и ту же идентичность, или когда нужно проверить правильность работы защиты конфиденциальности, необходимо детерминированное поведение. Браузер, дающий слегка различающиеся canvas-хеши, аудио-отпечатки или WebGL-вывод при каждом запуске, делает невозможным поддержание стабильной идентичности или надёжное тестирование конфигурации. Детерминированный режим BotBrowser, включаемый через флаг --bot-noise-seed, даёт полный контроль над всеми источниками вариации отпечатка. Одна и та же комбинация профиля и сида всегда даёт один и тот же отпечаток - между сессиями, между машинами и между операционными системами.

Влияние на конфиденциальность

Потребность в детерминированном поведении браузера возникает из фундаментального противоречия в защите отпечатков. Шум важен для конфиденциальности. Добавление контролируемой вариации к canvas-выводу, обработке аудио и рендерингу WebGL предотвращает тривиальную привязку отпечатков к одному профилю. Но неконтролируемый шум, при котором каждая сессия даёт другой отпечаток, создаёт иную проблему: каждая сессия выглядит как уникальный пользователь, что является противоположностью «растворения в толпе».

Исследование команды по конфиденциальности INRIA показало, что нестабильность отпечатка (изменение отпечатков между сессиями) сама по себе является сигналом отслеживания. Если отпечаток меняется при каждом визите, но другие сигналы (IP, состояние входа, поведенческие паттерны) остаются стабильными, меняющийся отпечаток становится маркером, а не щитом.

Детерминированный режим решает это, давая вам явный контроль. Вы выбираете, когда отпечатки должны оставаться одинаковыми (одинаковый сид) и когда они должны отличаться (разный сид). Это особенно важно для:

  • Непрерывности сессий. Возврат на сайт через несколько сессий с одним и тем же отпечатком.
  • Координации нескольких экземпляров. Запуск нескольких экземпляров браузера, которым нужны разные, но стабильные идентичности.
  • Тестирования и верификации. Подтверждение того, что защита отпечатков даёт ожидаемые результаты.
  • Воспроизводимости исследований. Проведение контролируемых экспериментов, где вариация отпечатков должна быть исключена как переменная.

Техническая справка

Источники вариации отпечатков

Современная защита отпечатков включает добавление контролируемого шума к нескольким конвейерам рендеринга и обработки:

  • Canvas 2D. Рендеринг текста, рисование фигур и манипуляции с изображениями дают специфичный для устройства пиксельный вывод. Шум добавляет субпиксельную вариацию для предотвращения точного сопоставления.
  • WebGL/WebGPU. Выполнение шейдеров, сэмплирование текстур и чтение фреймбуфера дают специфичный для GPU вывод. Шум модифицирует пиксельные значения в отрисованном выводе.
  • Аудио. Рендеринг OfflineAudioContext и частотные данные AnalyserNode дают специфичные для платформы значения с плавающей точкой. Шум варьирует вывод обработки.
  • Метрики текста. measureText(), getBoundingClientRect() и getClientRects() возвращают размеры, зависящие от рендеринга шрифтов. Шум добавляет субпиксельную вариацию к измерениям.

Без сида каждый из этих источников шума генерирует новую случайную вариацию при каждом запуске браузера. С сидом генератор случайных чисел инициализируется в известное состояние, создавая идентичные паттерны вариации каждый раз.

Как работают сиды шума

Сид шума - это одно целое число, инициализирующее детерминированный генератор псевдослучайных чисел (PRNG). PRNG создаёт последовательность значений, которая выглядит случайной, но полностью определяется сидом. Две сессии с одинаковым сидом дают одинаковую последовательность и, следовательно, одинаковый шум, применяемый к каждой поверхности отпечатка.

Сид шума BotBrowser (задаваемый через --bot-noise-seed) контролирует:

  • Шум изображений Canvas 2D
  • Шум изображений WebGL
  • Шум рендеринга WebGPU
  • Вариацию обработки аудио-контекста
  • Вариацию метрик текста (client rects, text rects)
  • Вариацию раскладки текста

Сид не влияет на свойства, не связанные с шумом, такие как navigator.hardwareConcurrency, screen.width или строки user agent. Они берутся непосредственно из профиля и всегда детерминированы.

Детерминизм тайминга

Помимо шума отпечатков, BotBrowser предлагает дополнительный контроль тайминга:

  • --bot-time-seed - контролирует разнообразие тайминга выполнения по 27 операциям браузера. Каждый сид создаёт уникальный, стабильный профиль производительности. Это покрывает интервалы performance.now(), performance.getEntries(), тайминг навигации и многое другое.
  • --bot-time-scale - масштабирует интервалы performance.now() для нормализации различий тайминга, вызванных разной серверной нагрузкой.

Вместе сиды шума и тайминга обеспечивают комплексный детерминированный контроль над всеми переменными выходами браузера.

Распространённые подходы защиты и их ограничения

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

Случайный шум без сида обеспечивает вариацию, но за счёт воспроизводимости. Каждая сессия имеет уникальный отпечаток. Вы не можете поддерживать стабильную идентичность, не можете надёжно проверить конфигурацию и не можете координировать несколько экземпляров.

Сессионный шум (генерация случайного сида для каждой сессии и его сохранение) - ручной обходной путь, добавляющий сложность. Вам нужно управлять значениями сидов, связывать их с сессиями и обеспечивать их согласованное применение. BotBrowser устраняет эти накладные расходы, принимая сид как CLI-флаг.

Шум на основе расширений обычно применяет случайный шум на уровне JavaScript без какого-либо механизма сидов. Каждая загрузка страницы даёт разные результаты. Шум недетерминирован, неконтролируем и несогласован между API-поверхностями.

Подход BotBrowser на уровне движка

Детерминированный режим BotBrowser работает на уровне движка рендеринга, обеспечивая согласованное применение шума по всем API-поверхностям из единого значения сида.

Один сид - полное покрытие

Флаг --bot-noise-seed принимает целое число от 1 до 4294967295 (UINT32_MAX). Это единственное значение контролирует все источники шума одновременно:

  • toDataURL(), toBlob() и getImageData() в Canvas 2D дают идентичный вывод для одного и того же сида.
  • readPixels() в WebGL возвращает те же данные фреймбуфера для одной и той же отрисованной сцены и сида.
  • OfflineAudioContext рендерит тот же буфер для одного и того же аудио-графа и сида.
  • measureText() и getClientRects() возвращают те же измерения для одного и того же содержимого и сида.

Воспроизводимость между машинами

Поскольку шум выводится из сида и применяется на уровне движка, одна и та же комбинация профиля и сида даёт один и тот же отпечаток независимо от аппаратного обеспечения, операционной системы или GPU. Сессия на Linux-сервере с GPU NVIDIA и сессия на Mac-ноутбуке с Apple Silicon дают идентичные отпечатки при использовании одного профиля и сида.

Сид как идентичность

На практике каждый сид можно рассматривать как определение уникальной суб-идентичности в рамках профиля. Профиль A с сидом 42 - это стабильная, воспроизводимая идентичность. Профиль A с сидом 43 - другая стабильная, воспроизводимая идентичность. Профиль определяет класс устройства (ОС, браузер, оборудование), а сид определяет индивида внутри этого класса.

Эта модель естественно отображается на мультиаккаунтные или мультисессионные рабочие процессы:

  • Сессия 1: профиль A, сид 100
  • Сессия 2: профиль A, сид 200
  • Сессия 3: профиль B, сид 100

Сессии 1 и 2 выглядят как разные пользователи с похожим оборудованием. Сессия 3 выглядит как другой пользователь на другом оборудовании.

Детерминизм тайминга

С --bot-time-seed тайминг выполнения тоже становится воспроизводимым. Измерения производительности, тайминг навигации и тайминг ресурсов следуют детерминированному паттерну для заданного сида. В сочетании с --bot-noise-seed это обеспечивает полный контроль над всеми переменными выходами браузера.

Deterministic Mode: Seed Controls All Noise Sources --bot-noise-seed=42 Deterministic PRNG Canvas Noise WebGL Noise Audio Noise Text Metrics Same seed = Same fingerprint every time

Настройка и использование

Базовый детерминированный режим

chrome --bot-profile="/path/to/profile.enc" \
       --bot-noise-seed=42 \
       --user-data-dir="$(mktemp -d)"

Полный детерминированный контроль

chrome --bot-profile="/path/to/profile.enc" \
       --bot-noise-seed=42 \
       --bot-time-seed=42 \
       --bot-stack-seed=profile \
       --user-data-dir="$(mktemp -d)"

Несколько экземпляров с разными сидами

# Instance 1 - stable identity A
chrome --bot-profile="/path/to/profile.enc" \
       --bot-noise-seed=1001 \
       --user-data-dir="/tmp/session-a" &

# Instance 2 - stable identity B
chrome --bot-profile="/path/to/profile.enc" \
       --bot-noise-seed=1002 \
       --user-data-dir="/tmp/session-b" &

Интеграция с Playwright

const { chromium } = require('playwright');

const browser = await chromium.launch({
  executablePath: '/path/to/botbrowser/chrome',
  args: [
    '--bot-profile=/path/to/profile.enc',
    '--bot-noise-seed=42',
    '--bot-time-seed=42'
  ]
});

const page = await browser.newPage();
await page.goto('https://example.com');

// This canvas fingerprint will be identical on every run
const hash = await page.evaluate(() => {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  ctx.fillText('deterministic test', 10, 10);
  return canvas.toDataURL();
});
console.log(hash);

Интеграция с 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-noise-seed=42',
    '--bot-time-seed=42'
  ]
});

const page = await browser.newPage();
await page.goto('https://example.com');

Отключение отдельных каналов шума

Если нужен детерминированный вывод для одних сигналов, но нативный для других:

chrome --bot-profile="/path/to/profile.enc" \
       --bot-noise-seed=42 \
       --bot-config-noise-canvas=false \
       --bot-config-noise-audio-context=false

Проверка

Воспроизводимость между сессиями. Запустите один и тот же тест фингерпринтинга в двух отдельных сессиях с одним профилем и сидом. Сравните canvas-хеши, аудио-отпечатки, WebGL-вывод и метрики текста. Все значения должны быть идентичны.

Воспроизводимость между машинами. Запустите тот же тест на другой машине с тем же профилем и сидом. Отпечаток должен совпадать точно.

Вариация сида. Измените сид и запустите тест снова. Отпечаток должен быть другим, подтверждая, что сид действительно влияет на вывод.

Поведение сида 0. Использование --bot-noise-seed=0 сохраняет шум активным с настройками профиля по умолчанию, но без детерминированного сидирования. Убедитесь, что это даёт разный вывод между сессиями.

Лучшие практики

  • Используйте уникальный сид для каждой идентичности. Каждый сид определяет стабильную суб-идентичность. Не используйте один и тот же сид для сессий, которые должны выглядеть как разные пользователи.
  • Сохраняйте значения сидов. Если вам нужно вернуться к сессии, необходим тот же профиль и сид. Сохраняйте связь между идентичностью сессии и значением сида.
  • Сочетайте --bot-noise-seed с --bot-time-seed. Сид шума контролирует вывод рендеринга. Сид тайминга контролирует тайминг производительности. Оба вносят вклад в полный отпечаток. Используйте оба для полного детерминизма.
  • Избегайте значения сида 0. Ноль сохраняет шум активным с недетерминированной вариацией. Используйте любое положительное целое число для детерминированного поведения.
  • Тестируйте назначения сидов. Перед развёртыванием убедитесь, что разные сиды дают разные отпечатки и что один и тот же сид даёт идентичные отпечатки.

Часто задаваемые вопросы

В: Каков допустимый диапазон для --bot-noise-seed? О: Любое целое число от 1 до 4294967295 (UINT32_MAX). Значение 0 сохраняет шум активным, но недетерминированным.

В: Влияет ли сид шума на производительность браузера? О: Нет. Операции шума крайне легковесны. Вычисление PRNG добавляет пренебрежимо малые накладные расходы.

В: Могут ли два разных профиля с одним сидом дать одинаковый отпечаток? О: Нет. Профиль определяет базовый отпечаток (GPU, экран, navigator и т.д.), а сид определяет вариацию шума. Разные профили с одним сидом дают разные отпечатки, потому что базовые значения различаются.

В: Что происходит, если не задать --bot-noise-seed? О: Шум применяется со случайным сидом при каждом запуске. Каждая сессия имеет свой отпечаток. Базовые свойства профиля (navigator, screen и т.д.) остаются одинаковыми.

В: Влияет ли детерминированный режим на cookies или локальное хранилище? О: Нет. Детерминированный режим контролирует вывод рендеринга, релевантный для отпечатков. Хранилище, cookies и состояние сессии управляются через --user-data-dir и --bot-cookies.

В: Можно ли использовать один сид с разными версиями BotBrowser? О: Алгоритм шума может меняться между основными версиями. Для точной воспроизводимости используйте одну и ту же версию BotBrowser. В рамках одной версии поведение сида гарантированно стабильно.

В: Чем --bot-time-seed отличается от --bot-noise-seed? О: --bot-noise-seed контролирует шум рендеринга (canvas, WebGL, аудио, метрики текста). --bot-time-seed контролирует разнообразие тайминга выполнения (паттерны performance.now(), тайминг навигации). Они независимы и могут быть заданы с разными значениями.

Итоги

Детерминированное поведение браузера необходимо для поддержания стабильных идентичностей отпечатков, координации мультисессионных рабочих процессов и верификации защиты конфиденциальности. Флаг --bot-noise-seed в BotBrowser обеспечивает полный контроль над всеми источниками вариации отпечатков, создавая идентичный вывод для одной и той же комбинации профиля и сида независимо от аппаратного обеспечения. В сочетании с --bot-time-seed для детерминизма тайминга и --bot-stack-seed для контроля глубины стека, BotBrowser предлагает комплексный детерминированный режим, покрывающий каждый переменный выход браузера.

По связанным темам смотрите Что такое фингерпринтинг браузера, Защита аудио-отпечатка, Canvas-фингерпринтинг и Воспроизводимость сида шума.

#Deterministic#Noise-Seed#Reproducibility#fingerprinting#Privacy

Переведите BotBrowser из исследований в продакшн

Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.