Fingerprinting через измерение текста: субпиксельные метрики шрифтов как сигнал отслеживания
Canvas measureText() возвращает значения ширины текста с субпиксельной точностью, которые различаются между ОС из-за различий в движках рендеринга шрифтов. Узнайте, как эти крошечные числовые различия становятся надежным сигналом идентификации платформы.
Введение
Когда веб-сайт измеряет ширину текстовой строки с помощью метода measureText() API Canvas, результатом является значение с плавающей точкой субпиксельной точности. Эти значения различаются между операционными системами, поскольку каждая платформа использует свой встроенный движок рендеринга с собственной внутренней арифметической моделью. Различия крошечные, невидимые для человеческого глаза, но они стабильные, воспроизводимые и измеримые через JavaScript.
Эта субпиксельная точность превращает measureText() в один из самых надежных сигналов идентификации платформы, доступных скриптам отслеживания. В отличие от fingerprinting изображений Canvas, который требует рендеринга пикселей и хеширования результата, fingerprinting через измерение текста быстрый, легковесный и дает прямое числовое значение, которое можно сравнить мгновенно. Один вызов занимает микросекунды и возвращает значение, идентифицирующее вашу операционную систему. Когда скрипт отслеживания измеряет несколько строк при нескольких размерах шрифта, объединенный результат становится мощным сигналом fingerprint.
Это делает измерение текста вектором отслеживания, активно используемым коммерческими системами fingerprinting на сайтах социальных сетей, банков, платежных систем и электронной коммерции. Оно не требует специальных разрешений, не создает видимого пользователю поведения и дает стабильные результаты между сессиями браузера. По мере улучшения браузерами защиты от других векторов fingerprinting, измерение текста получает все больше внимания, поскольку его трудно защитить на уровне API без ухудшения работы веб-приложений.
Подход BotBrowser на уровне движка
BotBrowser решает проблему fingerprinting через измерение текста на уровне движка браузера, а не через перехват API или постобработку. Это фундаментальное архитектурное отличие, которое обеспечивает защиту без обнаружения и без нарушения веб-функциональности.
Унифицированный путь рендеринга шрифтов
BotBrowser модифицирует конвейер рендеринга шрифтов внутри Chromium, чтобы обеспечить использование согласованной арифметики при вычислении метрик шрифтов на всех платформах. Независимо от того, работает ли BotBrowser на macOS, Windows или Linux, математика масштабирования шрифтов для данного профиля дает идентичные результаты.
Это означает, что когда профиль fingerprint указывает конкретную конфигурацию устройства, результаты measureText() точно соответствуют этой конфигурации, вплоть до последней значащей цифры. Шрифтовый движок не просто возвращает нативные значения хост-системы. Вместо этого он вычисляет метрики, используя модель рендеринга, определенную профилем.
Согласованность на основе профиля
Каждый профиль fingerprint BotBrowser кодирует характеристики текстовых метрик профилируемого устройства. При загрузке профиля движок рендеринга шрифтов выдает измерения, соответствующие оригинальному устройству:
- Одна и та же текстовая строка при одном и том же размере шрифта возвращает одинаковое значение ширины, независимо от хост-ОС.
- Один и тот же профиль, загруженный на macOS, Windows и Linux, дает побитово идентичные результаты
measureText(). - Результаты внутренне согласованы с другими сигналами, связанными со шрифтами (список шрифтов, рендеринг текста Canvas, метрики CSS-макета).
Эта согласованность распространяется на все свойства объекта TextMetrics, а не только на width. Значения actualBoundingBoxAscent, actualBoundingBoxDescent, fontBoundingBoxAscent, fontBoundingBoxDescent и bounding box left/right - все соответствуют профилю.
Побитово идентичные результаты на разных платформах
Ключевое техническое достижение - побитово идентичные результаты. Это означает, что представление с плавающей точкой результата measureText() идентично побайтово на разных платформах. Нет порога "достаточно близко". Значения математически идентичны.
Такой уровень согласованности возможен только при контроле на уровне движка. Любой подход, работающий выше движка рендеринга, такой как расширения, прокси API или обертки JavaScript, не может достичь побитово идентичных результатов, поскольку не может контролировать фактическую арифметику, выполняемую шрифтовым движком.
BotBrowser достигает этого, обеспечивая использование одной и той же модели точности в математике масштабирования шрифтов, независимо от хост-платформы. Профиль определяет ожидаемое поведение, и движок производит именно это поведение. Нативные предпочтения рендеринга шрифтов хост-системы не влияют на вывод.
Отсутствие обнаруживаемых артефактов
Поскольку защита работает внутри самого движка рендеринга:
measureText()возвращает нативные значения JavaScriptNumberс полной точностью двойной точности с плавающей точкой, точно так же, как немодифицированный браузер.- Нет модификаций прототипов, нет оберток функций, нет перехвата на уровне JavaScript.
- Значения согласованы с рендерингом пикселей Canvas. Текст, нарисованный на Canvas и затем измеренный попиксельно, соответствует ширине, сообщаемой
measureText(). - Нет статистических аномалий в распределении значений при разных размерах шрифтов и текстовых строках.
Внутренняя согласованность с другими сигналами
Защита текстовых метрик не работает изолированно. Профиль гарантирует, что значения measureText() согласованы со всеми другими наблюдаемыми сигналами шрифтов и рендеринга. Если скрипт отслеживания перекрестно проверяет текстовые метрики с выводом пикселей Canvas, результатами перечисления шрифтов или измерениями CSS-макета, все сигналы соответствуют одной и той же идентичности устройства. Эта внутренняя согласованность критически важна, поскольку системы fingerprinting все чаще ищут несоответствия между различными типами сигналов как индикатор вмешательства.
Конфигурация и использование
Использование CLI
Запустите BotBrowser с профилем fingerprint для активации защиты измерения текста:
chrome --bot-profile="/path/to/profile.enc" \
--user-data-dir="$(mktemp -d)"
Для детерминированных результатов между запусками добавьте seed шума:
chrome --bot-profile="/path/to/profile.enc" \
--bot-noise-seed=12345 \
--user-data-dir="$(mktemp -d)"
Объедините с настройками часового пояса, локали и прокси для полной согласованности идентичности:
chrome --bot-profile="/path/to/profile.enc" \
--bot-noise-seed=12345 \
--proxy-server="socks5://user:pass@proxy:1080" \
--bot-config-timezone="America/New_York" \
--bot-config-locale="en-US" \
--bot-config-languages="en-US,en"
Интеграция с Playwright
const { chromium } = require('playwright-core');
(async () => {
const browser = await chromium.launch({
executablePath: '/path/to/botbrowser/chrome',
args: [
'--bot-profile=/path/to/profile.enc',
'--bot-noise-seed=42',
],
headless: true,
});
const context = await browser.newContext({ viewport: null });
const page = await context.newPage();
await page.goto('https://example.com');
// measureText() results will be consistent with the loaded profile
const metrics = await page.evaluate(() => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.font = '16px Arial';
const measurement = ctx.measureText('Sample text for measurement');
return {
width: measurement.width,
actualBoundingBoxAscent: measurement.actualBoundingBoxAscent,
actualBoundingBoxDescent: measurement.actualBoundingBoxDescent,
};
});
console.log('Text metrics:', metrics);
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',
'--bot-noise-seed=42',
],
headless: true,
defaultViewport: null,
});
const page = await browser.newPage();
await page.goto('https://example.com');
// Verify text measurement from the loaded profile
const metrics = await page.evaluate(() => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.font = '16px Arial';
const m = ctx.measureText('Sample text for measurement');
return { width: m.width };
});
console.log('Text width:', metrics.width);
await browser.close();
})();
Проверка
После запуска BotBrowser с профилем убедитесь, что защита измерения текста активна:
const width = await page.evaluate(() => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.font = '16px Arial';
return ctx.measureText('Verification string').width;
});
console.log('Text width:', width);
Что проверять:
- Значение ширины является числом с плавающей точкой полной точности, соответствующим тому, что вернуло бы реальное устройство с целевой платформой профиля.
- Перезагрузка страницы и повторение измерения дает то же значение.
- Перезапуск браузера с тем же профилем и seed шума дает то же значение.
- Посетите сайты тестирования fingerprint, такие как BrowserLeaks или CreepJS, и убедитесь, что никакие межсигнальные несоответствия не отмечены.
Лучшие практики
Всегда используйте полный профиль
Защита измерения текста работает как часть полного профиля fingerprint BotBrowser. Профиль гарантирует, что текстовые метрики согласованы со всеми другими сигналами браузера: рендеринг Canvas, списки шрифтов, параметры WebGL и системная информация. Загрузка профиля необходима для активации защиты измерения текста.
Сочетайте с сетевой идентичностью
Текстовые метрики идентифицируют платформу. Сетевые сигналы идентифицируют местоположение. Для согласованной идентичности объедините профиль fingerprint с соответствующими настройками прокси и локали:
chrome --bot-profile="/path/to/profile.enc" \
--proxy-server="socks5://user:pass@proxy:1080" \
--bot-config-timezone="Europe/London" \
--bot-config-locale="en-GB" \
--bot-config-languages="en-GB,en"
Используйте детерминированный режим для тестирования
При запуске автоматизированных тестов или исследовательских экспериментов используйте --bot-noise-seed для обеспечения воспроизводимых результатов. Это позволяет проверить, что текстовые метрики остаются стабильными между запусками тестов и обнаружить любые регрессии в согласованности метрик.
Тестируйте с различными конфигурациями шрифтов
При проверке защиты тестируйте с различными семействами шрифтов и размерами. Включите в набор тестов как распространенные веб-шрифты, так и системные значения по умолчанию. Это обеспечивает всестороннее покрытие согласованности текстовых метрик вашего профиля в диапазоне шрифтов, которые обычно зондируют скрипты отслеживания.
Поддерживайте профили и BotBrowser в актуальном состоянии
Fingerprinting через измерение текста продолжает развиваться. В последних версиях браузеров добавлены новые свойства TextMetrics, и скрипты отслеживания обновляют свой сбор для включения этих новых сигналов. Поддерживайте установку BotBrowser и профили в актуальном состоянии для покрытия новых эксплуатируемых свойств.
FAQ
Что такое fingerprinting через измерение текста?
Fingerprinting через измерение текста использует API Canvas measureText() для определения, на какой платформе работает браузер. API возвращает значения ширины текста с субпиксельной точностью, и эти значения различаются между операционными системами, поскольку каждая ОС использует свой встроенный движок рендеринга с собственной внутренней арифметической моделью. Измеряя определенные текстовые строки при определенных размерах, скрипт отслеживания может идентифицировать операционную систему и различать отдельные устройства.
Чем это отличается от Canvas fingerprinting?
Canvas fingerprinting рендерит визуальный контент (текст, фигуры, градиенты) на элемент Canvas и хеширует полученные пиксельные данные. Fingerprinting через измерение текста использует measureText() для получения числовых значений ширины без рендеринга чего-либо видимого. Измерение текста быстрее, дает прямой числовой результат и предоставляет другой тип сигнала. Обе техники основаны на платформо-специфичных различиях рендеринга, но работают с разными выходами API Canvas. Подробнее о Canvas fingerprinting читайте в нашем руководстве Canvas Fingerprinting.
BotBrowser выдает одинаковые значения на всех платформах?
Да. При загрузке одного и того же профиля fingerprint BotBrowser выдает побитово идентичные результаты measureText() на macOS, Windows и Linux. Это достигается за счет контроля на уровне движка над математикой рендеринга шрифтов, гарантируя, что один и тот же профиль всегда дает одинаковые числовые результаты независимо от хост-ОС.
Защита измерения текста ломает сайты?
Нет. BotBrowser не блокирует и не модифицирует API measureText(). API работает нормально, возвращая точные значения ширины текста, которые веб-приложения могут использовать для верстки, обрезки текста, рендеринга графиков и всех других законных целей. Значения просто согласованы с загруженным профилем, а не с нативным рендерингом хост-системы.
Как это связано с fingerprinting шрифтов?
Fingerprinting через измерение текста тесно связан с fingerprinting шрифтов, но нацелен на другой сигнал. Fingerprinting шрифтов определяет, какие шрифты установлены, проверяя доступность конкретных семейств шрифтов. Fingerprinting через измерение текста определяет, как движок рендеринга обрабатывает эти шрифты, исследуя субпиксельные значения метрик. Оба сигнала происходят из стека рендеринга шрифтов, и оба покрываются защитой BotBrowser на уровне движка. Для более широкого обзора см. нашу статью о fingerprinting браузера.
Могу ли я использовать защиту измерения текста BotBrowser с существующими фреймворками автоматизации?
Да. BotBrowser интегрируется с Playwright, Puppeteer, Selenium и другими фреймворками автоматизации. Защита измерения текста автоматически активна при загрузке профиля fingerprint. Никаких дополнительных настроек или изменений кода не требуется, кроме передачи флага --bot-profile. Инструкции по настройке см. в руководстве по началу работы с Playwright и руководстве по началу работы с Puppeteer.
Покрывает ли эта защита все свойства TextMetrics?
Да. Защита BotBrowser покрывает полный набор свойств TextMetrics, включая width, actualBoundingBoxLeft, actualBoundingBoxRight, actualBoundingBoxAscent, actualBoundingBoxDescent, fontBoundingBoxAscent и fontBoundingBoxDescent. Все значения согласованы с загруженным профилем на всех платформах.
Итоги
Fingerprinting через измерение текста использует субпиксельную точность API Canvas measureText() для идентификации браузеров по их движку рендеринга. Поскольку каждая операционная система использует свой встроенный движок рендеринга с собственной внутренней арифметической моделью, один и тот же текст при одном и том же размере шрифта дает измеримо различные значения ширины на каждой платформе. Эти различия стабильные, воспроизводимые и активно собираются коммерческими системами отслеживания.
BotBrowser решает проблему fingerprinting через измерение текста на уровне движка браузера, контролируя математику рендеринга шрифтов внутри Chromium. При загрузке профиля fingerprint вычисления масштабирования шрифтов дают побитово идентичные результаты на macOS, Windows и Linux. Нет хуков на уровне API, нет модификаций прототипов и нет статистических аномалий. Значения внутренне согласованы со всеми другими сигналами шрифтов и Canvas в профиле, гарантируя, что перекрестные проверки скриптов fingerprinting не обнаружат несоответствий.
В сочетании с защитой BotBrowser для рендеринга Canvas, перечисления шрифтов и кроссплатформенной согласованности профилей, защита измерения текста закрывает один из самых точных векторов fingerprinting, доступных системам отслеживания сегодня.
Похожие статьи
Готовы защитить отпечаток браузера?
BotBrowser обеспечивает контроль отпечатков на уровне движка с реальными профилями устройств. Начните бесплатно или изучите все возможности.