Режим детерминированного поведения браузера в 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/');
// Запишите все хеши отпечатков, затем перезапустите с теми же флагами.
// Хеши должны совпадать точно.
Начало работы
- Скачайте BotBrowser с GitHub
- Выберите профиль из репозитория профилей
- Настройте
--bot-noise-seed,--bot-time-scaleи--bot-stack-seedдля полного детерминизма - Проверьте инструментами тестирования отпечатков согласованность между сессиями