Улучшение конфиденциальности пользователей и удобства разработки с помощью подсказок клиента User-Agent.

Клиентские подсказки User-Agent — это новое расширение API Client Hints, которое позволяет разработчикам получать доступ к информации о браузере пользователя эргономичным и сохраняющим конфиденциальность способом.

Клиентские подсказки позволяют разработчикам активно запрашивать информацию об устройстве или условиях пользователя вместо необходимости анализировать ее из строки User-Agent (UA). Предоставление этого альтернативного маршрута является первым шагом к постепенному снижению детализации строк User-Agent.

Узнайте, как обновить существующие функции, основанные на анализе строки User-Agent, чтобы вместо этого использовать клиентские подсказки User-Agent.

Фон

Когда веб-браузеры отправляют запросы, они включают информацию о браузере и его среде, чтобы серверы могли включить аналитику и настроить ответ. Это было определено еще в 1996 году (RFC 1945 для HTTP/1.0), где вы можете найти исходное определение строки User-Agent , которое включает пример:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

Этот заголовок предназначен для указания в порядке значимости продукта (например, браузера или библиотеки) и комментария (например, версии).

Состояние строки User-Agent

За прошедшие десятилетия эта строка накопила множество дополнительных сведений о клиенте, делающем запрос (а также бесполезную информацию из-за обратной совместимости). Мы можем видеть это, глядя на текущую строку User-Agent Chrome:

Mozilla/5.0 (Linux; Android 10; Pixel 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4076.0 Mobile Safari/537.36

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

Сочетание этих параметров с огромным разнообразием возможных значений означает, что строка User-Agent может содержать достаточно информации, позволяющей однозначно идентифицировать отдельных пользователей.

Строка User-Agent допускает множество законных вариантов использования и служит важной цели для разработчиков и владельцев сайтов. Однако также важно, чтобы конфиденциальность пользователей была защищена от скрытых методов отслеживания, а отправка информации UA по умолчанию противоречит этой цели.

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

Представляем новые клиентские подсказки User-Agent

Подсказки клиента User-Agent обеспечивают доступ к той же информации, но более конфиденциальным способом, что, в свою очередь, позволяет браузерам в конечном итоге уменьшить значение по умолчанию в строке User-Agent, транслирующее все. Клиентские подсказки реализуют модель, в которой сервер должен запрашивать у браузера набор данных о клиенте (подсказки), а браузер применяет свои собственные политики или пользовательскую конфигурацию, чтобы определить, какие данные возвращаются. Это означает, что вместо раскрытия всей информации об агенте пользователя по умолчанию доступ теперь управляется явным и проверяемым способом. Разработчики также получают выгоду от более простого API — больше никаких регулярных выражений!

Текущий набор клиентских подсказок в первую очередь описывает возможности отображения и подключения браузера. Подробности можно узнать в разделе «Автоматизация выбора ресурсов с помощью подсказок клиента» , а здесь мы кратко освежим этот процесс.

Сервер запрашивает определенные клиентские подсказки через заголовок:

⬇️ Ответ с сервера

Accept-CH: Viewport-Width, Width

Или метатег:

<meta http-equiv="Accept-CH" content="Viewport-Width, Width" />

Затем браузер может выбрать отправку следующих заголовков обратно в последующих запросах:

⬆️ Последующий запрос

Viewport-Width: 460
Width: 230

Сервер может изменить свои ответы, например, предоставляя изображения с соответствующим разрешением.

Подсказки клиента User-Agent расширяют диапазон свойств с помощью префикса Sec-CH-UA , который можно указать через заголовок ответа сервера Accept-CH . Чтобы узнать все подробности, начните с пояснения , а затем углубитесь в полное предложение .

Подсказки для клиента User-Agent из Chromium 89

Подсказки клиента User-Agent включены в Chrome по умолчанию, начиная с версии 89.

По умолчанию браузер возвращает марку браузера, основную/основную версию, платформу и индикатор, является ли клиент мобильным устройством:

⬆️ Все запросы

Sec-CH-UA: "Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "macOS"

Заголовки ответа и запроса пользовательского агента

⬇️ Ответ Accept-CH
⬆️ Заголовок запроса
⬆️ Запрос
Пример значения
Описание
Sec-CH-UA "Chromium";v="84",
"Google Chrome";v="84"
Список брендов браузеров и их основные версии.
Sec-CH-UA-Mobile ?1 Логическое значение, указывающее, находится ли браузер на мобильном устройстве ( ?1 для true) или нет ( ?0 для false).
Sec-CH-UA-Full-Version "84.0.4143.2" [ Устарело ]Полная версия для браузера.
Sec-CH-UA-Full-Version-List "Chromium";v="84.0.4143.2",
"Google Chrome";v="84.0.4143.2"
Список брендов браузеров и их полные версии.
Sec-CH-UA-Platform "Android" Платформа устройства, обычно операционная система (ОС).
Sec-CH-UA-Platform-Version "10" Версия для платформы или ОС.
Sec-CH-UA-Arch "arm" Базовая архитектура устройства. Хотя это может не иметь отношения к отображению страницы, сайт может предложить загрузку, которая по умолчанию имеет правильный формат.
Sec-CH-UA-Model "Pixel 3" Модель устройства.
Sec-CH-UA-Bitness "64" Разрядность базовой архитектуры (т. е. размер в битах целого числа или адреса памяти)

Пример обмена

Пример обмена будет выглядеть так:

⬆️ Первоначальный запрос из браузера
Браузер запрашивает страницу /downloads с сайта и отправляет свой базовый пользовательский агент по умолчанию.

GET /downloads HTTP/1.1
Host: example.site

Sec-CH-UA: "Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"
Sec-CH-UA-Mobile: ?1
Sec-CH-UA-Platform: "Android"

⬇️ Ответ с сервера
Сервер отправляет страницу обратно и дополнительно запрашивает полную версию браузера и платформу.

HTTP/1.1 200 OK
Accept-CH: Sec-CH-UA-Full-Version-List

⬆️ Последующие запросы
Браузер предоставляет серверу доступ к дополнительной информации и отправляет дополнительные подсказки во всех последующих запросах.

GET /downloads/app1 HTTP/1.1
Host: example.site

Sec-CH-UA: " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"
Sec-CH-UA-Mobile: ?1
Sec-CH-UA-Full-Version-List: " Not A;Brand";v="99.0.0.0", "Chromium";v="98.0.4738.0", "Google Chrome";v="98.0.4738.0"
Sec-CH-UA-Platform: "Android"

JavaScript API

Помимо заголовков, доступ к User-Agent также можно получить в JavaScript через navigator.userAgentData . Доступ к информации заголовков Sec-CH-UA , Sec-CH-UA-Mobile и Sec-CH-UA-Platform по умолчанию можно получить через brands и mobile свойства соответственно:

// Log the brand data
console.log(navigator.userAgentData.brands);

// output
[
  {
    brand: 'Chromium',
    version: '93',
  },
  {
    brand: 'Google Chrome',
    version: '93',
  },
  {
    brand: ' Not;A Brand',
    version: '99',
  },
];

// Log the mobile indicator
console.log(navigator.userAgentData.mobile);

// output
false;

// Log the platform value
console.log(navigator.userAgentData.platform);

// output
"macOS";

Доступ к дополнительным значениям осуществляется через вызов getHighEntropyValues() . Термин «высокая энтропия» относится к информационной энтропии , другими словами — к количеству информации, которую эти значения раскрывают о браузере пользователя. Как и в случае с запросом дополнительных заголовков, браузер сам решает, какие значения будут возвращены.

// Log the full user-agent data
navigator
  .userAgentData.getHighEntropyValues(
    ["architecture", "model", "bitness", "platformVersion",
     "fullVersionList"])
  .then(ua => { console.log(ua) });

// output
{
   "architecture":"x86",
   "bitness":"64",
   "brands":[
      {
         "brand":" Not A;Brand",
         "version":"99"
      },
      {
         "brand":"Chromium",
         "version":"98"
      },
      {
         "brand":"Google Chrome",
         "version":"98"
      }
   ],
   "fullVersionList":[
      {
         "brand":" Not A;Brand",
         "version":"99.0.0.0"
      },
      {
         "brand":"Chromium",
         "version":"98.0.4738.0"
      },
      {
         "brand":"Google Chrome",
         "version":"98.0.4738.0"
      }
   ],
   "mobile":false,
   "model":"",
   "platformVersion":"12.0.1"
}

Демо

Вы можете опробовать заголовки и API JavaScript на своем устройстве по адресу user-agent-client-hints.glitch.me .

Подсказка о времени жизни и сбросе

Подсказки, указанные в заголовке Accept-CH будут отправляться в течение сеанса браузера или до тех пор, пока не будет указан другой набор подсказок.

Это означает, что если сервер отправляет:

⬇️ Ответ

Accept-CH: Sec-CH-UA-Full-Version-List

Затем браузер будет отправлять заголовок Sec-CH-UA-Full-Version-List на все запросы к этому сайту, пока браузер не будет закрыт.

⬆️ Последующие запросы

Sec-CH-UA-Full-Version-List: " Not A;Brand";v="99.0.0.0", "Chromium";v="98.0.4738.0", "Google Chrome";v="98.0.4738.0"

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

⬇️ Ответ

Accept-CH: Sec-CH-UA-Bitness

⬆️ Последующие запросы

Sec-CH-UA-Platform: "64"

Ранее запрошенный Sec-CH-UA-Full-Version-List не будет отправлен .

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

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

Этот шаблон также соответствует тому, как работают подсказки через тег <meta http-equiv="Accept-CH" …> . Запрошенные подсказки будут отправляться только по запросам, инициированным страницей, а не при любой последующей навигации.

Область подсказок и запросы между источниками

По умолчанию подсказки клиента будут отправляться только по запросам того же источника. Это означает, что если вы запросите конкретные подсказки на https://example.com , но ресурсы, которые вы хотите оптимизировать, находятся на https://downloads.example.com они не получат никаких подсказок.

Чтобы разрешить подсказки для запросов из разных источников, каждая подсказка и источник должны быть указаны в заголовке Permissions-Policy . Чтобы применить это к подсказке клиента User-Agent, вам нужно перевести подсказку в нижний регистр и удалить префикс sec- . Например:

⬇️ Ответ сайта example.com

Accept-CH: Sec-CH-UA-Platform-Version, DPR
Permissions-Policy: ch-ua-platform-version=(self "downloads.example.com"),
                    ch-dpr=(self "cdn.provider" "img.example.com");

⬆️ Запрос на downloads.example.com

Sec-CH-UA-Platform-Version: "10"

⬆️ Запросы к cdn.provider или img.example.com

DPR: 2

Где использовать клиентские подсказки User-Agent?

Быстрый ответ: вам следует провести рефакторинг всех случаев, когда вы анализируете заголовок User-Agent или используете любые вызовы JavaScript, которые обращаются к одной и той же информации (например, navigator.userAgent , navigator.appVersion или navigator.platform ), чтобы вместо этого используйте подсказки клиента User-Agent.

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

Учитывая эти предостережения, в репозитории User-Agent Client Hints перечислены некоторые допустимые варианты использования сайтов.

Что происходит со строкой User-Agent?

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

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

Вы можете протестировать эту версию, включив флаг about://flags/#reduce-user-agent из Chrome 93 (Примечание: этот флаг назывался about://flags/#freeze-user-agent в версиях Chrome 84 — 92). Это вернет строку с историческими записями по соображениям совместимости, но с очищенными особенностями. Например, что-то вроде:

Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Mobile Safari/537.36

Миниатюра Сергея Золкина на Unsplash