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

Client Hints Fingerprinting: как HTTP-заголовки раскрывают идентичность вашего браузера

Заголовки Client Hints, такие как sec-ch-ua, раскрывают бренд, версию, платформу и данные устройства с каждым HTTP-запросом. Узнайте, как несоответствия в этих заголовках создают отслеживаемые сигналы и как поддерживать согласованность.

Введение

Каждый HTTP-запрос, отправляемый вашим браузером, несет идентификационную информацию в виде заголовков Client Hints. До выполнения любого JavaScript, до загрузки любого содержимого страницы, заголовки Sec-CH-UA, Sec-CH-UA-Platform и Sec-CH-UA-Mobile уже передали серверу бренд браузера, версию и данные операционной системы в структурированном, машиночитаемом формате. Дополнительные значения высокой энтропии, охватывающие архитектуру процессора, версию ОС, модель устройства и полные строки версий, доступны по запросу сервера или при вызове JavaScript navigator.userAgentData.getHighEntropyValues().

Эти заголовки были разработаны как улучшение конфиденциальности по сравнению с монолитной строкой User-Agent, предоставляя структурированные данные через механизм opt-in. На практике заголовки по умолчанию, отправляемые с каждым запросом, уже вносят значимую энтропию в fingerprinting браузера. Более важно то, что внутренняя согласованность значений Client Hints между всеми типами запросов в рамках сессии, а также выравнивание между HTTP-заголовками и JavaScript API, стали критически важной поверхностью для конфиденциальности. Любое несоответствие между тем, что сообщает сетевой уровень, и тем, что раскрывает уровень JavaScript, создает отслеживаемый сигнал, тривиально наблюдаемый на стороне сервера.

BotBrowser решает эту задачу на уровне движка, обеспечивая, чтобы каждое значение Client Hints управлялось профилем, было согласованным между всеми типами запросов и контекстами выполнения, и выровненным между HTTP-заголовками и JavaScript API.

Решение BotBrowser

Client Hints, управляемые профилем

BotBrowser генерирует все значения Client Hints из профилей, захваченных на реальных экземплярах браузера. При загрузке профиля движок создает полную конфигурацию Client Hints из данных профиля, включая:

  • Полный список брендов Sec-CH-UA с правильным брендом GREASE для версии Chrome в профиле
  • Детерминистический порядок брендов, соответствующий реальному поведению Chrome
  • Значения платформы, версии платформы, архитектуры, разрядности и модели
  • Полный список версий со всеми записями брендов и их полными строками версий

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

Согласованность между запросами

Все типы запросов используют один и тот же список брендов. Навигационные запросы, запросы субресурсов (скрипты, таблицы стилей, изображения, fetch-вызовы), запросы воркеров, запросы предзагрузки и запросы service worker - все получают идентичные заголовки Sec-CH-UA, потому что все они берут конфигурацию из одного источника, производного от профиля. Одна загрузка страницы может сгенерировать десятки HTTP-запросов, и каждый из них несет одни и те же значения Client Hints.

Выравнивание JavaScript и HTTP

BotBrowser обеспечивает, чтобы navigator.userAgentData.brands в JavaScript возвращал те же бренды, что появляются в HTTP-заголовке Sec-CH-UA. Аналогично, navigator.userAgentData.getHighEntropyValues() возвращает значения, согласованные с заголовками Client Hints высокой энтропии. Это выравнивание распространяется на каждый контекст выполнения в браузере:

  • Основной поток (контекст window)
  • Выделенные web workers
  • Разделяемые workers
  • Service workers
  • Worklets

Каждый контекст сообщает одни и те же значения Client Hints, потому что все они происходят из одного профиля.

Стабильность между сессиями

При использовании одного профиля в нескольких сессиях браузера BotBrowser каждый раз воспроизводит одну и ту же конфигурацию Client Hints. Бренд GREASE, версия, порядок и все значения метаданных детерминистичны для данного профиля. Это важно для сценариев, где необходимо поддерживать постоянную идентичность браузера между перезапусками.

Замена бренда

Когда нужно представить другой бренд браузера (например, Edge вместо Chrome), BotBrowser автоматически настраивает все поверхности Client Hints:

chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-browser-brand=edge \
       --bot-config-brand-full-version=136.0.3240.76

Это обновляет бренды Sec-CH-UA, Sec-CH-UA-Full-Version-List, navigator.userAgentData.brands и строку User-Agent в одной согласованной операции. Все поверхности отражают одну и ту же идентичность бренда.

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

Базовое использование профиля

Для большинства случаев использования достаточно загрузить профиль:

chrome --bot-profile="/path/to/profile.enc"

Профиль содержит всю конфигурацию Client Hints. Для согласованного поведения Client Hints дополнительные флаги не нужны.

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

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

(async () => {
  const browser = await chromium.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/path/to/profile.enc',
    ],
    headless: true,
  });

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

  // Read low-entropy Client Hints from JavaScript
  const brands = await page.evaluate(() =>
    navigator.userAgentData.brands.map(b => `${b.brand};v="${b.version}"`)
  );
  console.log('Brands:', brands);

  // Read high-entropy Client Hints
  const hints = await page.evaluate(async () => {
    const data = await navigator.userAgentData.getHighEntropyValues([
      'platformVersion', 'architecture', 'bitness',
      'fullVersionList', 'model'
    ]);
    return {
      platform: data.platform,
      platformVersion: data.platformVersion,
      architecture: data.architecture,
      bitness: data.bitness,
      fullVersionList: data.fullVersionList,
      model: data.model,
    };
  });
  console.log('High-entropy hints:', hints);

  await browser.close();
})();

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

const puppeteer = require('puppeteer-core');

(async () => {
  const browser = await puppeteer.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/path/to/profile.enc',
    ],
    headless: true,
    defaultViewport: null,
  });

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

  // Verify Client Hints from the loaded profile
  const jsHints = await page.evaluate(() => ({
    brands: navigator.userAgentData.brands,
    mobile: navigator.userAgentData.mobile,
    platform: navigator.userAgentData.platform,
  }));
  console.log('Client Hints:', jsHints);

  await browser.close();
})();

Проверка

Проверка Client Hints через JavaScript

Откройте страницу и убедитесь, что navigator.userAgentData возвращает ожидаемые значения:

// In browser console or via automation
const brands = navigator.userAgentData.brands;
console.log('Brands:', JSON.stringify(brands, null, 2));
console.log('Platform:', navigator.userAgentData.platform);
console.log('Mobile:', navigator.userAgentData.mobile);

const high = await navigator.userAgentData.getHighEntropyValues([
  'platformVersion', 'architecture', 'bitness',
  'fullVersionList', 'model', 'wow64'
]);
console.log('High-entropy:', JSON.stringify(high, null, 2));

Использование онлайн-инструментов проверки

Посетите BrowserLeaks, CreepJS или Cover Your Tracks, чтобы просмотреть ваши значения Client Hints вместе с другими данными fingerprinting. Убедитесь, что отображаемые бренды, платформа и версия соответствуют ожидаемым значениям из вашего профиля. Также ознакомьтесь с руководством по проверке fingerprint BotBrowser для полного руководства по проверке.

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

Всегда используйте профили

Не создавайте значения Client Hints вручную. Связь между версией Chrome, брендом GREASE и порядком брендов зависит от версии и меняется с каждым выпуском. Профили захватывают эти связи из реальных экземпляров браузера и точно воспроизводят их.

Сопоставляйте Client Hints с User-Agent

Если вы переопределяете строку User-Agent с помощью --user-agent, убедитесь, что флаги --bot-config-browser-brand и --bot-config-ua-full-version согласованы. BotBrowser автоматически сгенерирует соответствующие Client Hints, но переопределение строки User-Agent применяется отдельно и должно быть согласованным.

Поддерживайте профили в актуальном состоянии

Client Hints меняются с каждой версией Chrome. Вводятся новые бренды GREASE, увеличиваются номера версий. Использование устаревшего профиля со старыми номерами версий само по себе может стать различительным сигналом. Регулярно обновляйте свои профили из репозитория профилей BotBrowser, чтобы соответствовать текущим версиям браузера.

Не смешивайте источники Client Hints

Избегайте комбинирования Client Hints на основе профилей BotBrowser с переопределениями CDP или изменениями User-Agent на уровне фреймворка. Каждый из них работает на разном уровне, и их комбинирование создает несогласованности. Позвольте BotBrowser управлять всеми сигналами идентичности через свою систему профилей.

Отслеживайте запрашиваемые сервером Hints

Некоторые серверы запрашивают дополнительные hints высокой энтропии через Accept-CH. BotBrowser отвечает на эти запросы значениями из профиля. Если вы тестируете против конкретного сервиса, проверьте, какие hints он запрашивает, и убедитесь, что ответы BotBrowser полные и согласованные.

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

В чем разница между User-Agent и Client Hints?

Заголовок User-Agent - это единая строка, содержащая информацию о браузере, версии и ОС в свободном формате. Client Hints (заголовки Sec-CH-UA-*) предоставляют ту же информацию в виде структурированных пар ключ-значение. Современные браузеры на Chromium отправляют оба, и серверы сравнивают их на согласованность. См. Пользовательский User Agent для подробного сравнения.

Можно ли настроить Client Hints вручную с помощью Playwright или Puppeteer?

Playwright и Puppeteer позволяют переопределять строку User-Agent и, через CDP, некоторые метаданные Client Hints. Однако эти переопределения не охватывают все поверхности (workers, service workers, значения высокой энтропии) и требуют ручного управления брендами GREASE. Подход BotBrowser на основе профилей охватывает каждую поверхность и устраняет риск того, что частичные переопределения создадут несогласованности.

Работают ли Client Hints в headless-режиме?

Да. BotBrowser отправляет идентичные Client Hints как в headless, так и в обычном режиме. Заголовки Sec-CH-UA и значения navigator.userAgentData одинаковы независимо от режима отображения.

Как Client Hints связаны со свойствами navigator?

navigator.userAgentData - это JavaScript-интерфейс для Client Hints. Бренды, платформа и флаг mobile, раскрываемые через navigator.userAgentData, напрямую соответствуют HTTP-заголовкам Sec-CH-UA, Sec-CH-UA-Platform и Sec-CH-UA-Mobile. BotBrowser гарантирует их постоянное выравнивание. Подробнее о свойствах navigator см. Fingerprinting свойств Navigator.

Что происходит, если сервер не запрашивает hints высокой энтропии?

BotBrowser отправляет заголовки Client Hints высокой энтропии только когда сервер запрашивает их через Accept-CH, следуя стандартному поведению Chromium. Однако JavaScript API getHighEntropyValues() всегда доступен. BotBrowser гарантирует, что и HTTP-заголовки (когда они отправляются), и JavaScript API возвращают согласованные значения из профиля.

Можно ли использовать заголовки Client Hints для отслеживания без JavaScript?

Да. Заголовки по умолчанию Sec-CH-UA, Sec-CH-UA-Mobile и Sec-CH-UA-Platform отправляются с каждым HTTP-запросом, даже когда JavaScript отключен. Именно поэтому защита BotBrowser работает на уровне движка, а не полагается на вмешательства на уровне JavaScript.

Как часто нужно обновлять профили для точности Client Hints?

Каждый выпуск Chrome может вносить изменения в значения Client Hints. Рекомендуется обновлять профили с каждым основным выпуском Chrome (примерно каждые четыре недели), чтобы значения соответствовали текущим версиям браузера.

Поддерживает ли BotBrowser замену бренда для Edge, Brave и Opera?

Да. Флаг --bot-config-browser-brand поддерживает chrome, edge, brave, opera и webview. При указании бренда BotBrowser обновляет все заголовки Client Hints, JavaScript API и строку User-Agent для согласованного отражения выбранного бренда.

Итоги

Заголовки Client Hints несут идентификационную информацию браузера в каждом HTTP-запросе, создавая значимую для конфиденциальности поверхность, которая работает до загрузки любого содержимого страницы. Согласованность этих значений между типами запросов, контекстами выполнения, а также между HTTP-заголовками и JavaScript API критически важна для защиты конфиденциальности.

BotBrowser решает это на уровне движка. Профили, захваченные из реальных экземпляров браузера, определяют все значения Client Hints. Эти значения генерируются один раз из профиля и единообразно применяются к каждому типу запроса, каждому контексту выполнения и каждой поверхности API. Результатом является поведение Client Hints, соответствующее реальному выводу браузера, поскольку оно производится тем же движком Chromium с конфигурацией, управляемой профилем.

Для получения дополнительной информации о связанных темах см.:

#client hints#sec-ch-ua#fingerprinting#GREASE#user agent#privacy#browser identity#HTTP headers

Готовы защитить отпечаток браузера?

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