Фингерпринтинг Network Information API: проверка политики
Как значения navigator.connection добавляются к отпечатку браузера, почему выходной узел прокси может им противоречить и как проверить политику сетевой информации.
BotBrowser Team
Нужна структурированная документация по теме Отпечатки?
Эта статья относится к редакционной библиотеке. Для пошаговой настройки, справки и постоянных обновлений переходите сразу в соответствующий раздел docs.
Network Information API даёт странице несколько оценок соединения через navigator.connection. Он создавался, чтобы сайт мог выбирать более лёгкие ресурсы на медленном канале, но те же значения может прочитать любой скрипт на странице, поэтому они способны вносить вклад и в отпечаток браузера. Разделы ниже объясняют, что сообщает каждое свойство, почему выходной узел прокси может противоречить значениям, которые измеряет браузер, как выбрать между нативной политикой, политикой на основе профиля и политикой по полям и как проверить результат, не гадая. BotBrowser может сохранять согласованными значения сетевой информации одного профиля в контролируемом контексте, но не меняет реальное соединение и то, как сайт использует эти значения.
Кратко
navigator.connectionбез запроса разрешения отдаётeffectiveType,rttв миллисекундах,downlinkв мегабитах в секунду,typeиsaveData, поэтому любой скрипт на странице видит одни и те же пять полей.--bot-network-info-override=falseсохраняет измеренные значения хоста, флаг без значения илиprofileприменяет все значения из загруженного профиля, а JSON-политика задаёт только названные поля.- Некорректный JSON, неизвестное поле, недопустимое значение или селектор
profileдля поля, которого нет в профиле, отбрасывают всю политику, и измеренные нативные значения остаются. - Итоговая политика принадлежит одному контексту браузера и одновременно задаёт заголовки
RTT,Downlink,ECTиSave-Data, поэтому сравнивайте страницу с заголовками, которые получает ваш собственный сервер. - Выполняйте нативный запуск и запуск с переопределением подряд на одном хосте и одном маршруте, потому что прокси меняет путь, а не значения, которые читает страница.
Содержание
- Что раскрывает navigator.connection
- Как значения соединения добавляются к отпечатку
- Выбор политики сетевой информации
- Несоответствия, которые может заметить проверяющий
- Сравнение нативного запуска с запуском с переопределением
- Чем помогает BotBrowser
- Практический итог
Что раскрывает navigator.connection
Объект NetworkInformation сообщает приблизительные сведения о соединении, которое браузер использует в данный момент. Страницы применяют его, чтобы отложить необязательное видео, выбрать изображение меньшего размера или отложить предзагрузку. Он не требует запроса разрешения, поэтому его может прочитать любой скрипт, запущенный на странице, а событие change срабатывает, когда оценка браузера меняется.
effectiveTypeотносит наблюдаемые условия кslow-2g,2g,3gили4g. Он описывает качество, которое видел браузер, а не радиотехнологию.rttзадаёт оценку времени приёма-передачи в миллисекундах. Браузер округляет его, поэтому значение меняется ступенями.downlinkзадаёт оценку входящей пропускной способности в мегабитах в секунду, тоже округлённую.typeназывает технологию соединения, напримерwifi,cellular,ethernetилиunknown, если браузер её реализует.saveDataявляется булевым значением и сообщает, просил ли пользователь снизить расход данных.
Эти значения представляют собой оценки браузера, а не измерения, которым страница может доверять до последней цифры. Спецификация позволяет браузеру округлять их и группировать по диапазонам, и два чтения с интервалом в несколько секунд могут различаться. Поддержка также зависит от семейства браузеров. Браузеры на основе Chromium предоставляют объект, Firefox даёт ограниченный набор свойств, а Safari его не предоставляет, поэтому проверка должна начинаться с марки браузера, на которую рассчитано развёртывание. Отсутствие объекта у марки, которая обычно его предоставляет, само по себе является необычным наблюдением. О прикладной стороне этого же API, включая обработку отсутствующих или меняющихся подсказок, читайте в материале Network Information API для адаптивного контента. Спецификация описывает и downlinkMax, верхнюю границу для лежащей в основе технологии соединения, которую реализуют лишь некоторые браузеры, поэтому не считайте, что свойство, которое можно задать в политике, существует на каждой целевой платформе.
Как значения соединения добавляются к отпечатку
Ни одно свойство само по себе не идентифицирует человека. У effectiveType очень мало возможных значений, type часто равен unknown или отсутствует, а saveData у большинства посетителей выключен. Вклад здесь статистический. Конкретный effectiveType, округлённые rtt и downlink и настройка saveData вместе сужают набор браузеров, которые могли породить визит, и это сужение добавляется к остальным сигналам, которые собирает страница. Утверждение, что эти значения сами по себе идентифицируют пользователя или достигают фиксированной доли идентификации, выходит за рамки того, что поддерживают публичная спецификация и документация.
Значения несут и контекст о том, где находится браузер. Настольный компьютер на оптоволокне, телефон в мобильной сети и общий офисный канал обычно сообщают разные сочетания. saveData является пользовательской настройкой, поэтому посетитель, который её включил, выделяется сильнее того, кто оставил её выключенной. Поскольку объект читается без запроса разрешения, скрипт может записать значения при загрузке и сравнить их с более поздними чтениями в рамках того же визита.
Округление является собственной мерой приватности браузера и ограничивает то, что раскрывает одно чтение. Оставшийся сигнал касается главным образом стабильности и правдоподобия. Контекст, который всю сессию сообщает один класс соединения, а IP-адрес, часовой пояс и язык при этом ему соответствуют, выглядит как обычный визит. Контекст, у которого сетевые значения меняются так, как остальной визит не объясняет, или противоречат другим его сигналам, даёт скрипту материал для сравнения. Поэтому проверяющий смотрит на весь набор значений сразу, а не подгоняет одно число отдельно.
Самая практичная проблема возникает с прокси. Браузер, который отправляет трафик через выходной узел в другом регионе, по-прежнему измеряет тот путь, которым реально пользуется, поэтому rtt и downlink описывают этот реальный путь, а не соединение, типичное для региона выхода. Когда IP-адрес, часовой пояс и язык указывают на одно место, а оценки соединения описывают другой тип канала, сочетание выглядит необычно. Ни прокси, ни профиль не исправляют это в одиночку, потому что прокси меняет маршрут, а не значения, которые читает страница. Руководство по настройке прокси охватывает маршрутизацию, а политика сетевой информации охватывает значения, которые видит страница.
Второе место, где значения могут расходиться, это сам запрос. Те же оценки могут попадать к серверам, которые запрашивают их через Client Hints, в заголовках запроса RTT, Downlink, ECT и Save-Data. Если JavaScript сообщает один класс соединения, а заголовки другой, несоответствие заметнее, чем каждое значение по отдельности. Разумная политика рассматривает JavaScript API и сетевые Client Hints как одно решение. Руководство по фингерпринтингу через Client Hints объясняет более широкое семейство подсказок.
Выбор политики сетевой информации
Параметр --bot-network-info-override принимает одну политику, и полезных вариантов три. Выберите самый простой из тех, что отвечают на стоящий перед вами вопрос.
- Без переопределения, записывается как
false: страница видит нативные оценки браузера с обычным округлением. Это правильная база для любого сравнения. - База профиля, записывается как параметр без значения,
trueилиprofile: используются все сетевые значения, которые определяет загруженный профиль. Подходит для развёртывания, где профиль уже описывает нужный класс соединения. - JSON по полям: задаются только названные поля, а пропущенные остаются нативными. Политика, называющая только
rtt, оставляет все остальные поля с измеренными значениями.
Используйте нативную политику, когда нужно измерить, что сообщает соединение хоста, например при отладке или когда у развёртывания нет причин показывать что-то другое. Используйте базу профиля, когда профиль выбран так, чтобы описывать устройство и соединение, которое должна видеть страница, потому что тогда один параметр приносит все доступные сетевые значения и сохраняет их согласованными друг с другом. Используйте JSON по полям, когда сценарию нужны одно или два конкретных значения, например другой rtt для далёкого выходного узла, а остальные поля должны остаться как есть.
# Нативные значения
--bot-network-info-override=false
# Все доступные значения из загруженного профиля
--bot-network-info-override=profile
# Только выбранные поля; пропущенные остаются нативными
--bot-network-info-override='{"effectiveType":"3g","rtt":180,"downlink":1.8,"saveData":false}'
# Смешивание источников по полям
--bot-network-info-override='{"type":"profile","rtt":"host","downlink":2.5,"saveData":"profile"}'
JSON-политика принимает type, effectiveType, rtt, downlink, downlinkMax и saveData. Каждое поле принимает либо поддерживаемое значение, либо селектор источника, profile или host. Селектор profile берёт поле из загруженного профиля, а host сознательно сохраняет измеренное значение. Поддерживаемые значения следуют платформе: type равен одному из wifi, cellular, ethernet, bluetooth, wimax, other, none или unknown; effectiveType равен одному из slow-2g, 2g, 3g или 4g; rtt является неотрицательным целым числом в поддерживаемом диапазоне; downlink и downlinkMax являются неотрицательными числами в поддерживаемом диапазоне; saveData равен true или false. Пользовательская политика или политика с host может работать без профиля, тогда как селектору profile нужно, чтобы профиль определял это поле.
Относитесь к каждому значению как к базе, а не как к константе. Браузер по-прежнему применяет свои ограничения, округление и вариации по хостам, поэтому два источника могут получить немного разные числа из одной базы, а два запуска браузера не обязаны возвращать в точности один и тот же rtt. Ни одна политика не обещает одно фиксированное число для всех источников, а постоянное неокруглённое значение на каждом сайте само выглядело бы необычно.
Недопустимый ввод не приводит к сбою и не применяется частично. Некорректный JSON, неизвестное поле, недопустимое значение или селектор profile, указывающий на поле, которого нет в профиле, приводят к тому, что игнорируется вся политика, а измеренные нативные значения остаются. Остальные настройки профиля продолжают работать. Вывод для проверяющего прост: значения, похожие на нативные, не доказывают наличие пользовательского переопределения. Сначала проверьте текст политики, затем прочитайте значения заново.
Итоговая политика принадлежит контексту браузера. Страницы, воркеры, переходы и поддерживаемые запросы Client Hints внутри этого контекста используют один и тот же результат, а другой контекст может использовать иную политику. Задавайте политику до создания первой страницы в контексте. Политика, переданная в командной строке, имеет приоритет над настройкой networkInfoOverride в профиле, поэтому проверьте оба источника, когда результат не совпадает с тем, что предполагает профиль.
Несоответствия, которые может заметить проверяющий
Большинство проблем с сетевыми значениями это несоответствия между полями или между полем и остальным сценарием, а не одно неверное число. Эти случаи стоит проверить до запуска развёртывания.
Класс устройства, не соответствующий типу соединения. Профиль настольного браузера обычно сообщает ethernet, wifi или unknown, тогда как профиль телефона скорее сообщит cellular. Если вы задаёте type вручную, убедитесь, что он по-прежнему подходит устройству, которое описывает профиль.
Поля, не согласующиеся друг с другом. Спецификация определяет effectiveType через время приёма-передачи и downlink, поэтому написанный вручную 4g рядом с оценкой времени приёма-передачи в секундах описывает канал, который редко существует. Когда вы называете несколько полей, выбирайте значения, описывающие одно правдоподобное соединение, или позвольте профилю предоставить весь набор.
Флаг экономии данных, которого никто не хотел. Большинство посетителей оставляют saveData выключенным, поэтому значение true делает браузер более редким. Включайте его, только если сценарий действительно представляет пользователя, попросившего снизить расход данных, а в остальных случаях пусть решает профиль или нативное значение.
Селектор host в сценарии с прокси. Селектор host сохраняет измеренное значение, а значит, чтение снова отражает реальный путь, включая участок до прокси. Это правильный выбор, когда нужно измеренное поведение, и неправильный, когда вы ожидали, что страница будет выглядеть как соединение, типичное для региона выхода.
Воркер, который сообщает другое. Итоговая политика должна одинаково применяться к страницам и воркерам контекста. Если выделенный или общий воркер, который использует приложение, сообщает значения, отличные от значений страницы, считайте это находкой и записывайте, какая политика и какой контекст её дали.
Нативная база, снятая на другом соединении. Нативные значения зависят от соединения хоста в момент запуска, поэтому два нативных запуска в разных сетях или с разницей в несколько часов напрямую несопоставимы. Выполняйте нативный запуск и запуск с переопределением подряд, на одном хосте и по одному маршруту.
Контекст, изменённый слишком поздно. Поскольку итоговая политика фиксируется для контекста, значение, прочитанное на странице, существовавшей до применения политики, может отличаться от значения, прочитанного в новом контексте. Когда два чтения расходятся, сравнивайте их в отдельных контекстах, каждый из которых создан с одной и той же политикой.
Сравнение нативного запуска с запуском с переопределением
Проверка является сравнением, а не одиночным чтением. Запустите страницу один раз с нативной политикой и один раз с проверяемой политикой. Сохраняйте одинаковыми версию браузера, профиль, маршрут прокси, размер окна и состояние приложения и меняйте только значение политики. Используйте новый контекст для каждого запуска, чтобы новая политика не смешивалась со страницей, которая уже была создана.
- Запишите точный текст политики для каждого запуска, включая названия полей.
- Откройте небольшую диагностическую страницу, которая показывает
effectiveType,rtt,downlink,typeиsaveDataи больше ничего. - Прочитайте значения из консоли, как показано ниже, на странице и в воркере, если приложение его использует.
- Сравните сетевые Client Hints, которые доходят до вашего сервера, если этот сервер их запрашивает.
- Повторите чтение после перехода, чтобы убедиться, что контекст сохраняет один результат.
const c = navigator.connection;
console.log(c.effectiveType, c.rtt, c.downlink, c.type, c.saveData);
Представьте развёртывание, которое использует выходной узел прокси в другом регионе вместе с профилем широкополосного настольного компьютера. Нативный запуск показывает измеренные значения хоста. Запуск с профилем должен вместо этого показать класс соединения профиля с округлёнными значениями, стабильными внутри контекста. Запуск по полям, называющий только rtt, должен изменить именно это значение и оставить effectiveType, downlink и остальные поля такими, какими их сообщил нативный запуск. Если запуск по полям меняет больше полей, чем названо, или не меняет ничего, первым делом нужно перечитать текст политики.
Хороший результат выглядит так. Поля, названные в политике, меняются вместе, и на странице, и в заголовках запроса, а пропущенные поля сохраняют нативные значения. Значения могут округляться или немного отличаться между источниками, и это ожидаемо, а не сбой. Не менее важно то, что не меняется. Пропускная способность прокси, маршрутизация и любая задержка, которую сервер измеряет на собственных запросах, остаются прежними, поэтому сравнение, которое ожидает от сервера наблюдения другой скорости, проверяет не то.
Когда значение выглядит неверным, проверяйте в таком порядке: какой профиль был загружен, синтаксис JSON, названия полей, была ли политика задана до первой страницы контекста, какая из настроек командной строки и профиля победила, и маршрут прокси. Политика, проигнорированная из-за недопустимости, возвращает измеренные значения, поэтому страница без изменений не означает, что браузер перестал работать. Отдельный контекст это самый чистый способ проверить исправленную политику.
Ограничьте запись проверки конфигурацией и видимыми результатами: версия, имя профиля, текст политики, метка маршрута и прочитанные значения. Не включайте содержимое страниц, учётные данные и приватные данные запросов. Этого достаточно, чтобы кто-то другой повторил сравнение, и запись остаётся безопасной для передачи команде.
Повторяйте сравнение при каждой смене версии браузера, профиля или провайдера прокси, потому что правила округления, поддерживаемые свойства и сам маршрут могут меняться. Сохранённое сравнение с предыдущей версией служит хорошим ориентиром. Если названные поля по-прежнему меняются вместе, а пропущенные остаются нативными, политика всё ещё делает то, чего ожидает развёртывание. Если числа отличаются, но связи сохраняются, причиной обычно служат обычное округление и вариации по хостам, а не сломанная политика.
Чем помогает BotBrowser
BotBrowser поддерживает одну политику --bot-network-info-override, будь то база профиля, нативные значения или JSON по полям, которая задаёт свойства navigator.connection и соответствующие Client Hints для каждого контекста браузера, так что вы можете держать сетевые значения, которые видит страница, согласованными с выбранным вами профилем и сценарием прокси. Он не меняет реальную скорость или задержку прокси, измерения на стороне сервера и выводы сайта из других сетевых сигналов, а недопустимая политика игнорируется, и остаются измеренные нативные значения.
Сетевые значения служат лишь одним из многих входов, поэтому держите их согласованными с часовым поясом, локалью и языком, выбранными для того же маршрута, как описано в материале настройка часового пояса и локали. Поддержка браузеров и детали спецификации меняются, поэтому обращайтесь к источникам ниже, когда свойство или подсказка ведёт себя иначе в новой версии браузера.
Публичные источники
Практический итог
Проверка сетевой информации оставляет три артефакта: точный текст --bot-network-info-override, пять значений, прочитанных на странице и в воркере, и заголовки RTT, Downlink, ECT и Save-Data, полученные вашим сервером. Если запуск выглядит нативным, читайте текст политики раньше чисел, потому что отклонённый JSON-объект молча возвращает измеренные значения. Повторяйте пару запусков после выпуска браузера, смены профиля или провайдера прокси и сравнивайте две записи по полям, а не по одному числу.
Эта статья входит в руководство: Что такое отпечаток браузера?
Похожие статьи
Network Information API для адаптивного контента
ПлатформаNetwork Information API: приватность и резервный режим
ОтпечаткиФингерпринтинг Navigator: утечки браузера
ОтпечаткиКак hardwareConcurrency раскрывает реальные ядра вашего CPU
ОтпечаткиСнятие отпечатков WebGPU: следующее поколение отслеживания GPU
Отпечаткиwebgl_debug_renderer_info: что GPU раскрывает страницам
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.