Mejora la privacidad del usuario y la experiencia del desarrollador con Client Hints de usuario-agente

User-Agent Client Hints es una nueva expansión de la API de Client Hints, que permite a los desarrolladores acceder a información sobre el navegador de un usuario de una manera que preserva la privacidad y ergonómica.

Con Client Hints, los desarrolladores pueden solicitar información sobre el dispositivo o las condiciones del usuario de forma activa, en lugar de tener que analizarla fuera de la cadena de usuario-agente (UA). Proporcionar esta ruta alternativa es el primer paso para reducir, en algún momento, el nivel de detalle de la cadena de usuario-agente.

Obtén información sobre cómo actualizar la funcionalidad existente que se basa en el análisis de la string de usuario-agente para usar las sugerencias de clientes de usuario-agente en su lugar.

Información general

Cuando los navegadores web realizan solicitudes, incluyen información sobre el navegador y su entorno para que los servidores puedan habilitar las estadísticas y personalizar la respuesta. Esto se definió en 1996 (RFC 1945 para HTTP/1.0), en el que puedes encontrar la definición original de la string usuario-agente, que incluye un ejemplo:

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

Este encabezado tenía como objetivo especificar, en orden de importancia, el producto (p.ej., un navegador o una biblioteca) y un comentario (p.ej., la versión).

Estado de la string usuario-agente

Durante las décadas posteriores, esta string acumuló una variedad de detalles adicionales sobre el cliente que realiza la solicitud (además de información cruzada, debido a la retrocompatibilidad). Podemos ver que cuando observamos la cadena usuario-agente actual de Chrome, sucede lo siguiente:

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

La cadena anterior contiene información sobre el sistema operativo y la versión del usuario, el modelo del dispositivo, la marca y la versión completa del navegador, suficientes pistas para inferir que se trata de un navegador para dispositivos móviles, y sin mencionar varias referencias a otros navegadores por razones históricas.

La combinación de estos parámetros con la gran diversidad de valores posibles significa que la string de usuario-agente podría contener suficiente información para permitir que se identifiquen de forma única a los usuarios individuales. Si pruebas tu propio navegador en AmIUnique, puedes ver con qué nivel de detalle tu string de usuario-agente te identifica. Cuanto más baja sea la “Proporción de similitud” resultante, más únicas serán tus solicitudes, más fácil será para los servidores hacer un seguimiento encubierto de ti.

La cadena usuario-agente habilita muchos casos de uso legítimos y cumple un propósito importante para los desarrolladores y propietarios de sitios. Sin embargo, también es fundamental que la privacidad del usuario esté protegida contra métodos de seguimiento encubiertos, y el envío de información de UA de forma predeterminada va en contra de ese objetivo.

También es necesario mejorar la compatibilidad web en lo que respecta a la cadena usuario-agente. No está estructurado, por lo que su análisis genera una complejidad innecesaria, que suele ser la causa de errores y problemas de compatibilidad del sitio que perjudican a los usuarios. Estos problemas también perjudican desproporcionadamente a los usuarios de navegadores menos comunes, ya que es posible que los sitios no hayan podido realizar las pruebas de su configuración.

Presentación del nuevo User-Agent Client Hints

Las sugerencias de clientes de usuario-agente habilitan el acceso a la misma información, pero de una manera que preserva la privacidad, lo que, a su vez, permite que los navegadores reduzcan de forma eventual la configuración predeterminada de transmisión de todo la string de usuario-agente. Las sugerencias de cliente aplican un modelo en el que el servidor debe solicitar al navegador un conjunto de datos sobre el cliente (las sugerencias) y el navegador aplica sus propias políticas o configuración del usuario para determinar qué datos se muestran. Esto significa que, en lugar de exponer toda la información del usuario-agente de forma predeterminada, el acceso ahora se administra de manera explícita y auditable. Los desarrolladores también se benefician de una API más simple, ya no hay expresiones regulares.

El conjunto actual de Client Hints describe principalmente las capacidades de conexión y visualización del navegador. Puedes explorar los detalles en Cómo automatizar la selección de recursos con Client Hints, pero aquí hay un repaso rápido sobre el proceso.

El servidor solicita sugerencias de clientes específicas a través de un encabezado:

⚠️ Respuesta del servidor

Accept-CH: Viewport-Width, Width

O una metaetiqueta:

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

Luego, el navegador puede optar por enviar los siguientes encabezados de vuelta en solicitudes posteriores:

⬆️ Solicitud posterior

Viewport-Width: 460
Width: 230

El servidor puede optar por variar sus respuestas; por ejemplo, entregando imágenes en una resolución adecuada.

User-Agent Client Hints amplía el rango de propiedades con el prefijo Sec-CH-UA que se puede especificar a través del encabezado de respuesta del servidor Accept-CH. Para conocer todos los detalles, comienza con la explicación y, luego, explora la propuesta completa.

User-Agent Client Hints de Chromium 89

User-Agent Client Hints está habilitado de forma predeterminada en Chrome desde la versión 89.

De forma predeterminada, el navegador muestra la marca del navegador, la versión significativa o principal, la plataforma y un indicador si el cliente es un dispositivo móvil:

⬆️ Todas las solicitudes

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"

Encabezados de la solicitud y la respuesta de usuario-agente

⬇️ Respuesta Accept-CH
⬆️ Encabezado de la solicitud
⬆️ Solicitud
Valor de ejemplo
Descripción
Sec-CH-UA "Chromium";v="84",
"Google Chrome";v="84"
Lista de marcas de navegador y su versión significativa.
Sec-CH-UA-Mobile ?1 Es un valor booleano que indica si el navegador está en un dispositivo móvil (?1 para verdadero) o no (?0 para falso).
Sec-CH-UA-Full-Version "84.0.4143.2" [Obsoleta]La versión completa para el navegador.
Sec-CH-UA-Full-Version-List "Chromium";v="84.0.4143.2",
"Google Chrome";v="84.0.4143.2"
Lista de marcas de navegador y su versión completa.
Sec-CH-UA-Platform "Android" Es la plataforma del dispositivo, generalmente el sistema operativo (SO).
Sec-CH-UA-Platform-Version "10" Es la versión para la plataforma o el SO.
Sec-CH-UA-Arch "arm" La arquitectura subyacente del dispositivo. Aunque esto no sea relevante para mostrar la página, es posible que el sitio ofrezca una descarga que tenga el formato correcto de forma predeterminada.
Sec-CH-UA-Model "Pixel 3" El modelo del dispositivo
Sec-CH-UA-Bitness "64" El valor de bits de la arquitectura subyacente (es decir, el tamaño en bits de un número entero o una dirección de memoria)

Intercambio de ejemplo

Un intercambio de ejemplo se vería de la siguiente manera:

⬆️ Solicitud inicial del navegador
El navegador solicita la página /downloads del sitio y envía su usuario-agente básico predeterminado.

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"

⬇️ Respuesta del servidor
El servidor devuelve la página y, además, solicita la versión completa del navegador y la plataforma.

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

⬆️ Solicitudes posteriores
El navegador le otorga al servidor acceso a la información adicional y envía las sugerencias adicionales de vuelta en todas las solicitudes posteriores.

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"

API de JavaScript

Además de los encabezados, también se puede acceder al usuario-agente en JavaScript a través de navigator.userAgentData. Se puede acceder a la información predeterminada de los encabezados Sec-CH-UA, Sec-CH-UA-Mobile y Sec-CH-UA-Platform a través de las propiedades brands y mobile, respectivamente:

// 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";

Se accede a los valores adicionales a través de la llamada getHighEntropyValues(). El término de "entropía alta" hace referencia a la entropía de la información; en otras palabras, es la cantidad de información que estos valores revelan sobre el navegador del usuario. Al igual que con la solicitud de encabezados adicionales, depende del navegador qué valores se muestran, si los hay.

// 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"
}

Demostración

Puedes probar los encabezados y la API de JavaScript en tu propio dispositivo en user-agent-client-hints.glitch.me.

Duración de la sugerencia y restablecimiento

Las sugerencias que se especifiquen en el encabezado Accept-CH se enviarán durante la sesión del navegador o hasta que se especifique un conjunto diferente de sugerencias.

Esto significa que, si el servidor envía lo siguiente:

⬇️ Respuesta

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

Luego, el navegador enviará el encabezado Sec-CH-UA-Full-Version-List en todas las solicitudes de ese sitio hasta que se cierre.

⬆️ Solicitudes posteriores

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"

Sin embargo, si se recibe otro encabezado Accept-CH, reemplazará por completo las sugerencias actuales que envía el navegador.

⬇️ Respuesta

Accept-CH: Sec-CH-UA-Bitness

⬆️ Solicitudes posteriores

Sec-CH-UA-Platform: "64"

No se enviará el Sec-CH-UA-Full-Version-List solicitado previamente.

Se recomienda considerar que el encabezado Accept-CH especifica el conjunto completo de sugerencias deseadas para esa página, lo que significa que el navegador envía las sugerencias especificadas para todos los subrecursos de esa página. Si bien se mantendrán las sugerencias durante la siguiente navegación, el sitio no debe confiar ni suponer que se publicarán.

También puedes usarlo para borrar de manera efectiva todas las sugerencias que envía el navegador. Para ello, envía un Accept-CH en blanco en la respuesta. Considera agregar este archivo en cualquier lugar en el que el usuario restablezca las preferencias o salga de tu sitio.

Este patrón también coincide con el funcionamiento de las sugerencias mediante la etiqueta <meta http-equiv="Accept-CH" …>. Las sugerencias solicitadas solo se enviarán en las solicitudes que inicie la página y no en las navegaciones posteriores.

Alcance de las sugerencias y solicitudes de origen cruzado

De forma predeterminada, Client Hints solo se enviará en solicitudes del mismo origen. Es decir, si solicitas sugerencias específicas en https://example.com, pero los recursos que deseas optimizar están en https://downloads.example.com, no recibirán ninguna sugerencia.

Para permitir sugerencias en solicitudes de origen cruzado, cada sugerencia y origen se deben especificar con un encabezado Permissions-Policy. Para aplicar esto a una sugerencia de cliente de usuario-agente, debes escribir en minúscula la sugerencia y quitar el prefijo sec-. Por ejemplo:

⬇️ La respuesta de 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");

⬆️ Solicitud a downloads.example.com

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

⬆️ Solicitudes para cdn.provider o img.example.com

DPR: 2

¿Dónde se debe usar User-Agent Client Hints?

La respuesta rápida es que debes refactorizar cualquier instancia en la que analices el encabezado de usuario-agente o hagas uso de cualquiera de las llamadas de JavaScript que acceden a la misma información (es decir, navigator.userAgent, navigator.appVersion o navigator.platform) para usar en su lugar las sugerencias de clientes de usuario-agente.

Para seguir avanzando, debes volver a examinar el uso de la información del usuario-agente y reemplazarla con otros métodos siempre que sea posible. A menudo, puedes lograr el mismo objetivo mediante la mejora progresiva, la detección de funciones o el diseño responsivo. El problema básico de depender de los datos del usuario-agente es que siempre debes mantener una asignación entre la propiedad que inspeccionas y el comportamiento que habilita. Es una sobrecarga de mantenimiento para garantizar que la detección sea integral y se mantenga actualizada.

Con estas advertencias en mente, el repositorio de User-Agent Client Hints enumera algunos casos de uso válidos para los sitios.

¿Qué sucede con la cadena usuario-agente?

El plan es minimizar la capacidad de seguimiento encubierto en la Web mediante la reducción de la cantidad de información de identificación que expone la string de usuario-agente existente y sin causar interrupciones injustificadas en los sitios existentes. Ahora, la presentación de User-Agent Client Hints te brinda la oportunidad de comprender la nueva función y experimentar con ella, antes de que se realicen cambios en las strings de usuario-agente.

Con el tiempo, la información en la string de usuario-agente se reducirá para que mantenga el formato heredado y, al mismo tiempo, solo proporcione el mismo navegador de alto nivel y la misma información de versión significativa según las sugerencias predeterminadas. En Chromium, este cambio se postergó hasta al menos 2022 para brindar tiempo adicional para que el ecosistema evalúe las nuevas capacidades de User-Agent Client Hints.

Puedes probar una versión de esto habilitando la marca about://flags/#reduce-user-agent de Chrome 93 (Nota: Esta marca se llamaba about://flags/#freeze-user-agent en las versiones de Chrome 84 a 92). Se mostrará una string con las entradas históricas por motivos de compatibilidad, pero con información específica depurada. Por ejemplo:

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

Miniatura de Sergey Zolkin en Unsplash