Назад в Центр знаний
Отпечатки

performance.now: разрешение таймера и отпечаток браузера

Разрешение performance.now() и джиттер выдают огрубление таймера, дрейф часов и нагрузку. Измерьте их, прежде чем сравнивать две сборки браузера.

BotBrowser Team

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

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

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

performance.now() - та временная поверхность, к которой обзор приватности обращается первой: её не закрывает ни один запрос разрешения, а её разрешение вместе с мелкими неровностями описывает машину под ней. BotBrowser может сделать отдельные значения воспроизводимыми для разрешённых тестов, но не заменяет оборудование хоста и не обещает принятие результата каждым детектором.

TL;DR

  • Разрешение и джиттер performance.now() здесь главный сигнал; hardwareConcurrency и deviceMemory - два значения, которые обычно читают рядом с ним.
  • VPN, приватное окно и удаление cookie не меняют локальные аппаратные поверхности.
  • Параметры времени BotBrowser поддерживают воспроизводимую проверку, но не гарантируют анонимность или принятие детектором.

Contents

Что performance.now() говорит о часах

API времени создавались, чтобы разработчики могли измерять собственный код, но те же часы позволяют сайту узнать кое-что о машине, на которой этот код выполняется. performance.now() - поверхность, несущая больше всего сведений на байт, потому что два свойства отсчёта определяются вне страницы: насколько мелкие деления у часов и насколько сильно колеблются последовательные отсчёты.

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

У такого огрубления есть предыстория. Было показано, что часы высокого разрешения пригодны для атак по побочным каналам типа Spectre, поэтому разработчики браузеров снизили точность таймеров, добавили джиттер и связали более высокую точность с изоляцией перекрёстного происхождения. Эта мера создавалась для защиты содержимого памяти, а не для того, чтобы убрать облик оборудования из картины. Грубый таймер, который читают много раз, по-прежнему несёт сведения о том, сколько занимает задача на конкретной машине, и разброс между отсчётами говорит не меньше самих отсчётов.

Ещё два значения обычно стоят рядом с часами, и здесь они служат контекстом, а не темой. hardwareConcurrency сообщает число логических процессоров, доступных браузеру, и реальные устройства группируются вокруг значений вроде 4, 8, 12 и 16. deviceMemory возвращает приблизительный класс оперативной памяти в гигабайтах, округлённый до степени двойки и ограниченный сверху, а браузеры на основе Chromium отдают его только в защищённых контекстах. Руководство по планированию воркеров объясняет, как подобрать размер пула по этому числу ядер; здесь важно лишь то, что отсчёт времени заметнее, когда его сравнивают с ними.

Схема: часы performance.now, число логических ядер и класс памяти образуют единый профиль измерений, отражающий оборудование, который сравнивается с загруженным профилем

Ни одно из этих значений не требует запроса разрешения, ни одно не показывает видимого индикатора, и ни одно не стирается при удалении cookies. Поэтому они встречаются в исследованиях отпечатков, хотя каждое число по отдельности выглядит безобидно. Следующие разделы объясняют, как складываются эти отсчёты, какие распространённые меры приватности их не затрагивают и как вы можете настроить и проверить согласованное сообщаемое время с помощью BotBrowser.

Почему сочетание заметнее каждого сигнала

Взятый отдельно, каждый из этих сигналов несёт мало информации. Многие устройства имеют одинаковое число ядер, а у класса памяти лишь несколько возможных значений. Сочетание устроено иначе: сайт может прочитать все три значения за один проход и добавить короткий замер времени. Устройство, возвращающее определённый разброс дельт performance.now(), восемь ядер и класс памяти 8 ГБ, попадает в гораздо более узкую группу, чем устройство, описанное любым одним из этих фактов.

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

Представьте проверку тестового профиля, описывающего ноутбук среднего класса с восемью логическими ядрами и классом памяти 8 ГБ. На странице, которую вы контролируете, число ядер и класс памяти читаются как ожидается. Затем замер времени показывает, что цикл завершается намного быстрее, чем справился бы ноутбук такого класса, потому что реальный хост является серверной машиной высокого класса. Каждое значение оборудования согласуется с профилем, но время с ними не согласуется. На практике документированный диапазон масштаба, от 0.80 до 0.99, узок, поэтому он может смягчить умеренный перекос, но не превратит один класс оборудования в другой, а разрыв заметит только тот, кто читает поверхности вместе.

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

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

Три вопроса помогают структурировать проверку:

  • Описывают ли hardwareConcurrency и deviceMemory тот же класс машины, что и загруженный профиль?
  • Похожи ли повторные замеры времени на странице на тот же класс машины и остаются ли они близкими от запуска к запуску?
  • Согласуются ли записи Navigation Timing и Resource Timing с профилем, а не отражают реальное соединение хоста?

Что оставляют нетронутым VPN, приватные окна, расширения и шум

Сравнивайте performance.now(), navigator.hardwareConcurrency и navigator.deviceMemory в одном профиле; сетевые средства приватности не переписывают эти локальные значения.

VPN меняет сетевой путь и IP-адрес, который видит сервер. Он не меняет того, как быстро ваш процессор выполняет цикл, сколько логических ядер сообщает браузер и какой класс памяти он показывает. Все три значения читаются локально, поэтому две разные машины за одной точкой выхода VPN всё равно сообщают разный облик оборудования.

Окна приватного просмотра удаляют cookies, историю и данные сайтов при закрытии. Они не меняют ни число ядер, ни класс памяти, ни скорость лежащего в основе оборудования, поэтому значения времени и оборудования в приватном окне совпадают со значениями в обычном окне на той же машине.

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

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

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

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

Всё это не делает такие инструменты бесполезными. VPN защищает сетевой уровень, приватные окна защищают локальную историю, а расширения могут блокировать многие трекеры до их загрузки. Они закрывают разные поверхности. Облик времени и оборудования лежит в области, для которой они не создавались, поэтому при проверке его нужно рассматривать отдельно и проверять напрямую.

Настройка сообщаемого времени с профилем BotBrowser

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

chromium-browser \
  --bot-profile="path/to/profile.enc" \
  --bot-time-scale=0.92 \
  --bot-time-seed=42

--bot-time-scale сжимает сообщаемые интервалы времени высокого разрешения. Документированный диапазон составляет от 0.80 до 0.99, и значение ближе к 0.80 сжимает интервалы сильнее, чем значение ближе к 0.99. Документация описывает эффект как имитацию более низкой нагрузки на систему и уменьшение сигналов перекоса времени. Это параметр уровня ENT Tier2.

--bot-time-seed принимает целое число от 1 до 4294967295, а 0 его отключает. Каждое зерно даёт стабильный профиль времени, распределяющий детерминированное разнообразие по операциям браузера и записям navigation timing, поэтому то же зерно с тем же профилем даёт то же поведение при следующем запуске. Это тоже параметр уровня ENT Tier2.

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

--bot-performance-timing это отдельный параметр для видимых браузеру записей времени, например этапов соединения в Navigation Timing и Resource Timing. Он принимает basic и advanced, требует ENT Tier3 и работает только тогда, когда активный пакет профиля включает Performance Timing Protection. Его нужно задать до запуска первой страницы или первого воркера, и он разрешается для каждого контекста браузера отдельно. Опустите его или передайте false, чтобы оставить политику отключённой.

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

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

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

const { hardwareConcurrency, deviceMemory } = navigator;
const samples = [];
for (let run = 0; run < 5; run += 1) {
  const start = performance.now();
  for (let i = 0; i < 100000; i += 1) Math.sqrt(i);
  samples.push(performance.now() - start);
}
console.log({ hardwareConcurrency, deviceMemory, samples });

Фрагмент читает два значения оборудования и собирает пять коротких замеров времени. Относитесь к результату как к проверке согласованности, а не как к тесту производительности: абсолютные числа зависят от хоста, а вы ищете совпадение сообщаемых значений с профилем.

Что проверять:

  1. hardwareConcurrency совпадает с числом ядер, которое описывает профиль.
  2. deviceMemory совпадает с классом памяти, который описывает профиль.
  3. Пять замеров близки друг к другу, а второй запуск с тем же профилем, масштабом и зерном даёт согласованную картину.
  4. Изменение только зерна меняет картину, что подтверждает применение зерна.
  5. Чтение тех же значений в выделенном воркере и во фрейме iframe даёт те же значения оборудования, что и на главной странице.

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

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

Если результат не совпадает, меняйте одну настройку за раз и повторяйте запуск: именно такой подход рекомендует документация по производительности для устранения проблем. Обычные причины: отсутствующее или неверное зерно, профиль без этой функции или уровень ENT, который не покрывает параметр.

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

Что делает BotBrowser и где он останавливается

BotBrowser документирует --bot-time-scale и --bot-time-seed (ENT Tier2), которые сжимают интервалы времени высокого разрешения, сообщаемые содержимому страницы, и дают каждому экземпляру стабильный профиль времени, воспроизводимый по зерну, рядом со значениями оборудования, заданными профилем, чтобы вы могли повторять согласованное время между тестовыми сеансами. BotBrowser не может изменить, насколько быстро хост на самом деле выполняет JavaScript, не заменяет физическое оборудование и не гарантирует, что каждая поверхность времени или каждый сторонний детектор примет результат; параметры меняют только значения, сообщаемые содержимому страницы, и зависят от уровня ENT и поддержки в профиле, а для --bot-performance-timing дополнительно нужны ENT Tier3 и профиль, который его включает.

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

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

Запись проверки полезнее всего, когда в ней перечислены:

  • Файл профиля и использованная версия BotBrowser.
  • Точные параметры, включая масштаб и зерно.
  • Уровень ENT, доступный для запуска.
  • Прочитанные значения оборудования и замеры времени.
  • Дата и страница, использованная для проверки.

Смежные поверхности разбирают другие материалы. Общий обзор отпечатков браузера объясняет, как сигналы складываются, hardwareConcurrency и планирование воркеров подробнее рассматривает число ядер, а управление частотой кадров описывает параметр времени отображения.

Открытые источники

Практический итог

Используйте значения времени и оборудования как свидетельство согласованности, а не как обещание, что браузер станет неотличимым от другой машины. Начните с базового запуска только с профилем, меняйте по одному поддерживаемому параметру, записывайте точную команду и уровень ENT, а затем повторяйте разрешённые проверки в странице, worker и iframe. При расхождении зафиксируйте его и исследуйте профиль или хост, вместо того чтобы добавлять необъяснимый шум.

#производительность#Timing#fingerprinting#приватность#Cpu#Hardware#Time-Seed

Эта статья входит в руководство: Что такое отпечаток браузера?

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

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