Отпечатки

Фингерпринтинг шрифтов: контроль списков и метрик

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

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

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

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

Введение

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

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

Фингерпринтинг шрифтов был надёжным вектором отслеживания более десяти лет. Исследование EFF Panopticlick обнаружило, что набор установленных шрифтов был одним из атрибутов браузера с наивысшей энтропией, способным уникально идентифицировать более 80% браузеров в их наборе данных. Исследование 2016 года из Университета Аделаиды подтвердило, что списки шрифтов дают в среднем от 8 до 10 бит идентифицирующей информации, а для пользователей со специализированным ПО (дизайнеров, разработчиков, пользователей с языковыми пакетами CJK) значительно больше.

Проблема усилилась по мере диверсификации операционных систем. Windows, macOS и Linux поставляются с разными наборами шрифтов по умолчанию, и каждая версия ОС изменяет эти наборы. Windows 11 включает шрифты, которых нет в Windows 10. macOS Sonoma отличается от macOS Ventura. Эти различия означают, что фингерпринтинг шрифтов часто может определить точную версию вашей операционной системы, сужая популяцию ещё до рассмотрения любого другого сигнала.

Корпоративные среды добавляют ещё одно измерение. Корпоративные лицензии на шрифты (Helvetica Neue, Futura, проприетарные брендовые шрифты) создают характерные отпечатки, привязанные к конкретным организациям. Креативные специалисты с установленными Adobe Fonts или Google Fonts имеют уникально большие наборы шрифтов.

Техническая основа

Фингерпринтинг шрифтов опирается на две основные техники.

Перечисление шрифтов через измерение

Браузеры не предоставляют прямого API для получения списка установленных шрифтов (устаревший подход document.fonts.check() имеет ограниченное покрытие). Вместо этого скрипты отслеживания используют технику на основе измерений:

  1. Создать скрытый HTML-элемент с известным запасным шрифтом (monospace, serif или sans-serif).
  2. Измерить его отрисованную ширину и высоту.
  3. Изменить font-family на шрифт-кандидат плюс запасной.
  4. Измерить снова. Если размеры изменились, шрифт-кандидат установлен.

Тестируя сотни названий шрифтов, скрипт может построить бинарный вектор установленных/неустановленных шрифтов. Этот вектор и является шрифтовым отпечатком.

Фингерпринтинг метрик текста

Помимо списка шрифтов, точные измерения рендеринга текста варьируются в зависимости от платформы. Они включают:

  • Метрики текста Canvas. Использование measureText() на контексте Canvas 2D возвращает свойства вроде width, actualBoundingBoxAscent, actualBoundingBoxDescent, fontBoundingBoxAscent и fontBoundingBoxDescent. Эти значения зависят от движка рендеринга шрифтов (DirectWrite на Windows, CoreText на macOS, FreeType на Linux), настроек хинтинга и конфигурации субпиксельного рендеринга.
  • Ограничивающие прямоугольники элементов. getBoundingClientRect() и getClientRects() возвращают размеры, которые варьируются в зависимости от формирования шрифтов, таблиц кернинга и поведения движка компоновки.
  • Рендеринг текста OffscreenCanvas. Текст, нарисованный на OffscreenCanvas, производит пиксельные данные, которые варьируются в зависимости от платформы, предоставляя ещё один вектор измерения.

Комбинация списка шрифтов и метрик текста создаёт составной отпечаток с очень высокой энтропией.

Почему вывод различается

Рендеринг шрифтов - сложный процесс, включающий несколько уровней:

  • Формат файла шрифта. Шрифты TrueType и OpenType содержат различные инструкции хинтинга, которые влияют на рендеринг при малых размерах.
  • Движок рендеринга. DirectWrite (Windows), CoreText (macOS) и FreeType (Linux) по-разному реализуют формирование текста, хинтинг и растеризацию.
  • Субпиксельный рендеринг. ClearType (Windows), субпиксельное сглаживание (macOS) и различные конфигурации FreeType производят визуально различный вывод на субпиксельном уровне.
  • DPI и масштабирование. Дисплеи с высоким DPI влияют на метрики текста через масштабирование соотношения пикселей устройства.

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

Блокировка перечисления шрифтов непрактична, поскольку техника использует стандартные CSS и DOM-API для измерений. Вы не можете заблокировать getBoundingClientRect(), не нарушив веб-вёрстку.

Установка большего количества шрифтов для слияния с толпой на самом деле имеет обратный эффект. Система с 500 шрифтами более уникальна, чем система со стандартными шрифтами ОС. Шрифтовой отпечаток становится более характерным, а не менее.

Расширения браузера, которые заявляют о защите шрифтовых отпечатков, обычно работают через инъекцию CSS-переопределений или перехват API измерений. Эти подходы хрупки. Расширение может переопределить measureText(), но пропустить getClientRects(). Или оно может сообщать общий список шрифтов, пока фактический рендеринг использует реальные шрифты, создавая обнаруживаемое несоответствие.

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

Использование минимального набора шрифтов (как делает Tor Browser) уменьшает уникальность, но создаёт собственный характерный профиль. Браузер с набором шрифтов, точно соответствующим Tor Browser, идентифицируется как вероятно являющийся Tor.

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

BotBrowser контролирует фингерпринтинг шрифтов на уровне движка Chromium через два механизма: управление списком шрифтов и контроль рендеринга текста.

Контролируемые списки шрифтов

При загрузке профиля отпечатка BotBrowser настраивает подсистему шрифтов так, чтобы она сообщала именно те шрифты, которые были бы у профилированного устройства. Это не CSS-переопределение и не JavaScript-перехват. Внутреннее перечисление шрифтов браузера возвращает список шрифтов профиля. Когда веб-сайт проверяет наличие конкретного шрифта, ответ (установлен или не установлен) соответствует профилированной системе.

Это покрывает:

  • Результаты перечисления системных шрифтов
  • Порядок разрешения CSS font-family
  • Ответы API document.fonts
  • Поведение цепочки запасных шрифтов

Согласованность метрик текста

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

  • measureText() возвращает метрики, соответствующие формированию текста и хинтингу профилированной платформы.
  • getBoundingClientRect() и getClientRects() возвращают размеры, согласованные с профилированным движком рендеринга.
  • Рендеринг текста Canvas производит пиксельный вывод, соответствующий профилированной платформе.
  • Шум клиентских прямоугольников (контролируется через --bot-config-noise-client-rects и --bot-config-noise-text-rects) добавляет детерминированную вариацию при включении.

Кросс-платформенная эмуляция шрифтов

Ключевое преимущество подхода BotBrowser - кросс-платформенная эмуляция шрифтов. Работая на Linux, вы можете загрузить профиль Windows и получить типичные для Windows списки шрифтов и метрики текста. Шрифтовой отпечаток соответствует реальной системе Windows, а не системе Linux, притворяющейся имеющей шрифты Windows.

Это возможно потому, что BotBrowser контролирует рендеринг шрифтов на уровне движка, а не через установку файлов шрифтов. Вам не нужно устанавливать шрифты Windows на вашу Linux-систему.

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

Базовая защита шрифтов

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

Параметры конфигурации шрифтов

# Использование настроек шрифтов профиля (по умолчанию, рекомендуется)
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-fonts=profile

# Шрифты профиля плюс системные запасные шрифты
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-fonts=expand

# Использование реальных системных шрифтов (без защиты шрифтов)
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-fonts=real

Контроль шума метрик текста

# Включение шума клиентских прямоугольников для вариации измерений
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-noise-client-rects=true \
       --bot-config-noise-text-rects=true \
       --bot-noise-seed=42

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

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

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

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

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

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

Верификация

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

Проверка метрик текста. Измерьте стандартную строку (например, "Hello World" шрифтом Arial 16px) через measureText() и сравните результаты между сессиями и машинами. При одном профиле и seed-шума значения должны быть идентичны.

Проверка платформенной согласованности. Если вы загружаете профиль Windows на Linux, убедитесь, что обнаруженные шрифты типичны для Windows (Segoe UI, Calibri, Consolas), а не для Linux (Liberation Sans, DejaVu Sans).

Кросс-API проверка. Сравните результаты обнаружения шрифтов через CSS-измерение, Canvas measureText() и getClientRects(). Все должны быть согласованы с одним и тем же набором шрифтов.

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

  • Используйте --bot-config-fonts=profile (по умолчанию). Это обеспечивает наиболее полную защиту шрифтов. Опция expand добавляет системные шрифты как запасные, что может внести локальную вариацию.
  • Комбинируйте защиту шрифтов с шумом Canvas. Метрики текста и рендеринг Canvas тесно связаны. Включайте оба для комплексной защиты.
  • Используйте профили, соответствующие вашему целевому региону. Наборы CJK-шрифтов, RTL-шрифты и специфичные для локали умолчания значительно различаются. Используйте профиль, соответствующий вашей ожидаемой локали.
  • Тестируйте с несколькими списками проверки шрифтов. Разные системы отслеживания проверяют разные списки шрифтов. Проверяйте вашу защиту на нескольких инструментах тестирования.
  • Избегайте установки необычных шрифтов. При использовании --bot-config-fonts=expand или real необычные шрифты в вашей системе будут обнаруживаемы.

FAQ

В: Сколько шрифтов обычно проверяют скрипты отслеживания? О: Распространённые библиотеки фингерпринтинга тестируют от 50 до 500 названий шрифтов. Некоторые комплексные скрипты проверяют более 1000 шрифтов, нацеливаясь на конкретные платформы и программные установки.

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

В: Может ли фингерпринтинг шрифтов определить мою конкретную версию ОС? О: Да. Наборы шрифтов по умолчанию меняются между версиями ОС. Windows 11, Windows 10, macOS Sonoma и macOS Ventura имеют разные шрифты по умолчанию. Системы отслеживания поддерживают базы данных, сопоставляющие наборы шрифтов с версиями ОС.

В: Для чего нужен режим expand шрифтов? О: Режим expand использует список шрифтов профиля как основной набор и добавляет системные шрифты как запасные. Это полезно, если вашему приложению нужны конкретные системные шрифты для рендеринга, но вы всё же хотите перечисление шрифтов на основе профиля.

В: Влияет ли защита шрифтов на загрузку веб-шрифтов? О: Нет. Веб-шрифты, загружаемые с серверов (через @font-face), не затрагиваются защитой шрифтового отпечатка. Контролируется только обнаружение локальных/системных шрифтов.

В: Согласованы ли метрики текста между headless и headed режимами? О: Да. BotBrowser контролирует метрики текста на уровне движка независимо от режима отображения.

Итоги

Фингерпринтинг шрифтов объединяет перечисление шрифтов и измерение метрик текста для создания высокоэнтропийного сигнала отслеживания, который варьируется между операционными системами, версиями и индивидуальными установками. BotBrowser контролирует как сообщаемый список шрифтов, так и метрики рендеринга текста на уровне движка, производя результаты, согласованные с загруженным профилем, независимо от ваших реальных системных шрифтов. С помощью --bot-config-fonts=profile и --bot-noise-seed шрифтовые отпечатки стабильны, согласованы и аутентичны.

По связанным темам смотрите Что такое фингерпринтинг браузера, Согласованность CSS-сигналов, Фингерпринтинг Canvas и Защита экрана и окна.

#Fonts#fingerprinting#Text-Metrics#Privacy

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

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