Назад к блогу
Отпечатки

Режим детерминированного поведения браузера в BotBrowser

Как BotBrowser обеспечивает воспроизводимое поведение между сессиями с помощью --bot-noise-seed для детерминированных fingerprint и согласованных результатов.

Введение

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

Детерминированный режим BotBrowser, включаемый флагом --bot-noise-seed, даёт полный контроль над всеми источниками вариации фингерпринта. Одна и та же пара профиль + seed всегда даёт одинаковый фингерпринт — между сессиями, машинами и ОС.

Влияние на приватность

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

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

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

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

Технический фон

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

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

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

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

Как работают шумовые seed

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

Seed BotBrowser (через --bot-noise-seed) контролирует:

  • Canvas 2D image noise
  • WebGL image noise
  • WebGPU rendering noise
  • Variation in audio context processing
  • Text metric variation

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

Детерминированность тайминга

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

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

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

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

  • Нет шума: детерминированно, но без преимуществ вариации.
  • Случайный шум без seed: вариативно, но нерепродуцируемо.
  • Шум на уровне сессии: ручное управление seed — громоздко.
  • Шум через расширение: обычно на JS-уровне без seed — непредсказуемо.

BotBrowser устраняет сложность, принимая seed как CLI-флаг.

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

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

Одна seed — полный охват

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

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

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

Поскольку шум выводится из seed и применяется на уровне движка, одна и та же комбинация профиль + seed даёт одинаковый фингерпринт независимо от железа или ОС.

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

Практически каждая seed определяет уникальную под-идентичность внутри профиля. Профиль определяет класс устройства, а seed — индивидуальность внутри класса.

Детерминированность тайминга

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

<svg viewBox="0 0 600 300" xmlns="http://www.w3.org/2000/svg" style="font-family: system-ui, sans-serif; max-width: 600px;">
  <rect width="600" height="300" fill="#f8f9fa" rx="8"/>

  <text x="300" y="30" text-anchor="middle" font-size="16" font-weight="bold" fill="#1a1a2e">Deterministic Mode: Seed Controls All Noise Sources</text>

  <!-- Seed box -->
  <rect x="230" y="50" width="140" height="40" fill="#2563eb" rx="6"/>
  <text x="300" y="75" text-anchor="middle" fill="white" font-size="13" font-weight="bold">--bot-noise-seed=42</text>

  <!-- Arrow down -->
  <line x1="300" y1="90" x2="300" y2="120" stroke="#2563eb" stroke-width="2" marker-end="url(#arrowBlue)"/>

  <!-- PRNG box -->
  <rect x="220" y="120" width="160" height="30" fill="#e0e7ff" rx="4" stroke="#2563eb"/>
  <text x="300" y="140" text-anchor="middle" font-size="12" fill="#1e40af">Deterministic PRNG</text>

  <!-- Arrows to each output -->
  <line x1="220" y1="150" x2="100" y2="190" stroke="#6b7280" stroke-width="1.5"/>
  <line x1="270" y1="150" x2="220" y2="190" stroke="#6b7280" stroke-width="1.5"/>
  <line x1="330" y1="150" x2="380" y2="190" stroke="#6b7280" stroke-width="1.5"/>
  <line x1="380" y1="150" x2="500" y2="190" stroke="#6b7280" stroke-width="1.5"/>

  <!-- Output boxes -->
  <rect x="40" y="190" width="120" height="35" fill="#dbeafe" rx="4" stroke="#93c5fd"/>
  <text x="100" y="212" text-anchor="middle" font-size="11" fill="#1e40af">Canvas Noise</text>

  <rect x="170" y="190" width="120" height="35" fill="#dbeafe" rx="4" stroke="#93c5fd"/>
  <text x="230" y="212" text-anchor="middle" font-size="11" fill="#1e40af">WebGL Noise</text>

  <rect x="310" y="190" width="120" height="35" fill="#dbeafe" rx="4" stroke="#93c5fd"/>
  <text x="370" y="212" text-anchor="middle" font-size="11" fill="#1e40af">Audio Noise</text>

  <rect x="440" y="190" width="120" height="35" fill="#dbeafe" rx="4" stroke="#93c5fd"/>
  <text x="500" y="212" text-anchor="middle" font-size="11" fill="#1e40af">Text Metrics</text>

  <!-- Result -->
  <rect x="150" y="250" width="300" height="35" fill="#dcfce7" rx="4" stroke="#86efac"/>
  <text x="300" y="272" text-anchor="middle" font-size="12" font-weight="bold" fill="#166534">Same seed = Same fingerprint every time</text>

  <defs>
    <marker id="arrowBlue" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
      <polygon points="0 0, 10 3.5, 0 7" fill="#2563eb"/>
    </marker>
  </defs>
</svg>

Конфигурация и использование

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

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)"

Мульти-инстансы с разными seed

# 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" &

Проверка

Проверьте воспроизводимость между сессиями и машинами, изменения при смене seed и поведение seed=0.

Рекомендации

  • Используйте уникальную seed для каждой идентичности.
  • Храните значения seed.
  • Комбинируйте --bot-noise-seed и --bot-time-seed.
  • Избегайте seed 0.

FAQ

(要点)

Резюме

Детерминированное поведение необходимо для стабильных идентичностей и тестирования. --bot-noise-seed предоставляет полный контроль над источниками вариации.

title: "Детерминированный режим поведения браузера в BotBrowser" description: "Как BotBrowser обеспечивает согласованное, воспроизводимое поведение браузера между сессиями с помощью конфигурации на основе профилей и флагов запуска." date: "2025-06-10" locale: ru category: fingerprint tags: ["deterministic", "consistent", "fingerprinting", "reproducibility", "privacy"] published: true

Почему детерминизм важен

Каждая сессия браузера вносит небольшие вариации в рендеринг, тайминг и генерацию случайных чисел. По-настоящему согласованная идентичность браузера требует контроля над всеми источниками случайности.

Как BotBrowser достигает детерминизма

BotBrowser контролирует недетерминированность через конфигурацию профилей и флаги запуска на уровне движка браузера.

Аппаратная идентичность на основе профилей

Флаг --bot-profile загружает полный отпечаток устройства:

chrome --bot-profile="/profiles/windows-chrome-122.enc" \
       --user-data-dir="$(mktemp -d)"

Seed шума для согласованности рендеринга

Флаг --bot-noise-seed контролирует весь шум рендеринга через детерминированный генератор случайных чисел:

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

Контроль тайминга и стека

Дополнительные флаги контролируют другие источники вариаций:

chrome --bot-profile="/profiles/windows-chrome-122.enc" \
       --bot-noise-seed=42 \
       --bot-time-scale=1.0 \
       --bot-stack-seed=profile \
       --user-data-dir="$(mktemp -d)"

Полная детерминированная конфигурация

chrome --bot-profile="/profiles/windows-chrome-122.enc" \
       --bot-noise-seed=42 \
       --bot-time-scale=1.0 \
       --bot-stack-seed=profile \
       --bot-config-noise-canvas=true \
       --user-data-dir="/data/session-identity-a"

Каждый запуск с этой конфигурацией дает идентичные выходные данные отпечатка.

Проверка

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

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

const page = await (await browser.newContext()).newPage();
await page.goto('https://abrahamjuliot.github.io/creepjs/');
// Запишите все хеши отпечатков, затем перезапустите с теми же флагами.
// Хеши должны совпадать точно.

Начало работы

  1. Скачайте BotBrowser с GitHub
  2. Выберите профиль из репозитория профилей
  3. Настройте --bot-noise-seed, --bot-time-scale и --bot-stack-seed для полного детерминизма
  4. Проверьте инструментами тестирования отпечатков согласованность между сессиями
#deterministic#noise-seed#reproducibility#fingerprinting#privacy