Huella digital

Fingerprinting de fuentes: listas y metricas

Cómo la enumeración de fuentes y la medición de métricas de texto crean huellas de navegador únicas, y técnicas para controlar la identidad de fuentes a nivel del motor.

Documentación

Prefieres la documentación del producto mantenida?

Este artículo tiene una página equivalente en el centro de documentación. Usa los docs para el flujo canónico, las flags actuales y la referencia duradera.

Introducción

Cada sistema operativo viene con un conjunto diferente de fuentes. Los usuarios instalan fuentes adicionales para trabajo, diseño o preferencia personal. Esta combinación de fuentes instaladas crea un identificador sorprendentemente único. Los sitios web pueden sondear qué fuentes están disponibles midiendo cómo se renderiza el texto a tamaños específicos, y la lista resultante de fuentes detectadas forma una huella de fuentes. Más allá de la lista de fuentes en sí, las métricas de texto como anchos de glifos, alturas y cuadros delimitadores varían entre plataformas y motores de renderizado de fuentes. Juntas, la enumeración de fuentes y las métricas de texto dan a los sistemas de rastreo una señal estable y de alta entropía que persiste entre sesiones. Este artículo explica cómo funciona la huella de fuentes y cómo BotBrowser controla la identidad de fuentes a nivel del motor.

Impacto en la privacidad

La huella de fuentes ha sido un vector de rastreo fiable durante más de una década. El estudio Panopticlick de la EFF encontró que el conjunto de fuentes instaladas era uno de los atributos del navegador con mayor entropía, capaz de identificar de forma única más del 80% de los navegadores en su conjunto de datos. Un estudio de 2016 de la University of Adelaide confirmó que las listas de fuentes proporcionan de 8 a 10 bits de información identificativa en promedio, y significativamente más para usuarios con software especializado (diseñadores, desarrolladores, usuarios con paquetes de idiomas CJK).

El problema ha crecido a medida que los sistemas operativos se han diversificado. Windows, macOS y Linux vienen cada uno con conjuntos de fuentes predeterminados diferentes, y cada versión del SO cambia los valores predeterminados. Windows 11 incluye fuentes que Windows 10 no tiene. macOS Sonoma difiere de macOS Ventura. Estas diferencias significan que la huella de fuentes frecuentemente puede identificar tu versión exacta del sistema operativo, reduciendo la población antes de considerar cualquier otra señal.

Los entornos corporativos añaden otra dimensión. Las licencias de fuentes empresariales (Helvetica Neue, Futura, fuentes corporativas propietarias) crean huellas distintivas ligadas a organizaciones específicas. Los profesionales creativos con Adobe Fonts o Google Fonts instalados tienen conjuntos de fuentes excepcionalmente grandes.

Trasfondo técnico

La huella de fuentes se basa en dos técnicas principales.

Enumeración de fuentes vía medición

Los navegadores no exponen una API directa para listar fuentes instaladas (el enfoque obsoleto document.fonts.check() tiene cobertura limitada). En su lugar, los scripts de rastreo usan una técnica basada en medición:

  1. Crear un elemento HTML oculto con una fuente de fallback conocida (monospace, serif o sans-serif).
  2. Medir su ancho y alto renderizados.
  3. Cambiar el font-family a una fuente candidata más el fallback.
  4. Medir de nuevo. Si las dimensiones cambian, la fuente candidata está instalada.

Probando cientos de nombres de fuentes, un script puede construir un vector binario de fuentes instaladas/no instaladas. Este vector es la huella de fuentes.

Huella de métricas de texto

Más allá de la lista de fuentes, las mediciones precisas del renderizado de texto varían por plataforma. Estas incluyen:

  • Métricas de texto Canvas. Usando measureText() en un contexto Canvas 2D se obtienen propiedades como width, actualBoundingBoxAscent, actualBoundingBoxDescent, fontBoundingBoxAscent y fontBoundingBoxDescent. Estos valores dependen del motor de renderizado de fuentes (DirectWrite en Windows, CoreText en macOS, FreeType en Linux), configuraciones de hinting y configuración de renderizado subpíxel.
  • Cajas delimitadoras de elementos. getBoundingClientRect() y getClientRects() devuelven dimensiones que varían según el modelado de fuentes, tablas de kerning y comportamiento del motor de layout.
  • Renderizado de texto en OffscreenCanvas. El texto dibujado en un OffscreenCanvas produce datos de píxeles que varían por plataforma, proporcionando otro vector de medición.

La combinación de lista de fuentes y métricas de texto crea una huella compuesta con entropía muy alta.

Por qué varía la salida

El renderizado de fuentes es un proceso complejo que involucra múltiples capas:

  • Formato de archivo de fuente. Las fuentes TrueType y OpenType contienen diferentes instrucciones de hinting que afectan el renderizado a tamaños pequeños.
  • Motor de renderizado. DirectWrite (Windows), CoreText (macOS) y FreeType (Linux) implementan el modelado de texto, hinting y rasterización de manera diferente.
  • Renderizado subpíxel. ClearType (Windows), anti-aliasing subpíxel (macOS) y varias configuraciones de FreeType producen salida visiblemente diferente a nivel subpíxel.
  • DPI y escalado. Las pantallas de alto DPI afectan las métricas de texto a través del escalado de relación de píxeles del dispositivo.

Enfoques comunes de protección y sus limitaciones

Bloquear la enumeración de fuentes es impráctico porque la técnica usa APIs estándar de CSS y medición del DOM. No puedes bloquear getBoundingClientRect() sin romper el layout web.

Instalar más fuentes para mezclarse realmente resulta contraproducente. Un sistema con 500 fuentes es más único que uno con los valores predeterminados del SO. La huella de fuentes se vuelve más distintiva, no menos.

Extensiones del navegador que afirman proteger las huellas de fuentes típicamente funcionan inyectando sobrescrituras CSS o interceptando APIs de medición. Estos enfoques son frágiles. Una extensión podría sobrescribir measureText() pero no getClientRects(). O podría reportar una lista de fuentes genérica mientras el renderizado real usa las fuentes verdaderas, creando una inconsistencia detectable.

Aleatorizar métricas de texto rompe aplicaciones web. Muchos sitios dependen de mediciones de texto precisas para cálculos de layout, editores de texto y diseño responsivo. Los valores aleatorios causan fallos visuales y layouts rotos.

Usar un conjunto mínimo de fuentes (como hace el navegador Tor) reduce la unicidad pero crea un perfil distintivo propio. Un navegador con exactamente el conjunto de fuentes del navegador Tor es identificable como probablemente Tor.

Enfoque de BotBrowser a nivel de motor

BotBrowser controla la huella de fuentes a nivel del motor de Chromium a través de dos mecanismos: gestión de lista de fuentes y control de renderizado de texto.

Listas de fuentes controladas

Cuando se carga un perfil de huella digital, BotBrowser configura el subsistema de fuentes para reportar exactamente las fuentes que el dispositivo perfilado tendría. Esto no es una sobrescritura CSS o interceptación JavaScript. La enumeración interna de fuentes del navegador devuelve la lista de fuentes del perfil. Cuando un sitio web sondea una fuente específica, la respuesta (instalada o no instalada) coincide con el sistema perfilado.

Esto cubre:

  • Resultados de enumeración de fuentes del sistema
  • Orden de resolución CSS font-family
  • Respuestas de la API document.fonts
  • Comportamiento de cadena de fallback de fuentes

Consistencia de métricas de texto

El sistema de perfiles de BotBrowser incluye datos de métricas de texto para la plataforma objetivo. Cuando el texto se mide a través de cualquier API, los resultados son consistentes con el motor de renderizado de fuentes del dispositivo perfilado:

  • measureText() devuelve métricas que coinciden con el modelado y hinting de texto de la plataforma perfilada.
  • getBoundingClientRect() y getClientRects() devuelven dimensiones consistentes con el motor de renderizado perfilado.
  • El renderizado de texto Canvas produce salida de píxeles que coincide con la plataforma perfilada.
  • El ruido de client rect (controlado vía --bot-config-noise-client-rects y --bot-config-noise-text-rects) añade variación determinista cuando está habilitado.

Emulación de fuentes multiplataforma

Una fortaleza clave del enfoque de BotBrowser es la emulación de fuentes multiplataforma. Ejecutándose en Linux, puedes cargar un perfil de Windows y obtener listas de fuentes y métricas de texto típicas de Windows. La huella de fuentes coincide con un sistema Windows real, no con un sistema Linux pretendiendo tener fuentes de Windows.

Esto es posible porque BotBrowser controla el renderizado de fuentes a nivel del motor, no a través de instalación de archivos de fuentes. No necesitas instalar fuentes de Windows en tu sistema Linux.

Configuración y uso

Protección básica de fuentes

chrome --bot-profile="/path/to/profile.enc" \
       --user-data-dir="$(mktemp -d)"

Opciones de configuración de fuentes

# Use profile's font settings (default, recommended)
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-fonts=profile

# Profile fonts plus system fallback fonts
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-fonts=expand

# Use real system fonts (no font protection)
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-fonts=real

Control de ruido de métricas de texto

# Enable client rect noise for measurement variation
chrome --bot-profile="/path/to/profile.enc" \
       --bot-config-noise-client-rects=true \
       --bot-config-noise-text-rects=true \
       --bot-noise-seed=42

Integración con Playwright

const { chromium } = require('playwright');

const browser = await chromium.launch({
  executablePath: '/path/to/botbrowser/chrome',
  args: [
    '--bot-profile=/path/to/profile.enc',
    '--bot-config-fonts=profile',
    '--bot-noise-seed=42'
  ]
});

const page = await browser.newPage();
await page.goto('https://example.com');

Integración con Puppeteer

const puppeteer = require('puppeteer');

const browser = await puppeteer.launch({
  executablePath: '/path/to/botbrowser/chrome',
  defaultViewport: null,
  args: [
    '--bot-profile=/path/to/profile.enc',
    '--bot-config-fonts=profile',
    '--bot-noise-seed=42'
  ]
});

const page = await browser.newPage();
await page.goto('https://example.com');

Verificación

Verificación de lista de fuentes. Usa un sitio de prueba de huellas digitales para ver qué fuentes se detectan. La lista debería coincidir con el SO y configuración objetivo del perfil, no con tu sistema real.

Verificación de métricas de texto. Mide una cadena estándar (ej. "Hello World" en 16px Arial) usando measureText() y compara los resultados entre sesiones y máquinas. Con el mismo perfil y semilla de ruido, los valores deberían ser idénticos.

Verificación de consistencia de plataforma. Si estás cargando un perfil de Windows en Linux, verifica que las fuentes detectadas son típicas de Windows (Segoe UI, Calibri, Consolas) en lugar de típicas de Linux (Liberation Sans, DejaVu Sans).

Verificación entre APIs. Compara los resultados de detección de fuentes de la medición CSS, measureText() de Canvas y getClientRects(). Todos deberían ser consistentes con el mismo conjunto de fuentes.

Mejores prácticas

  • Usa --bot-config-fonts=profile (predeterminado). Esto proporciona la protección de fuentes más completa. La opción expand añade fuentes del sistema como fallbacks, lo que puede introducir variación local.
  • Combina protección de fuentes con ruido de canvas. Las métricas de texto y el renderizado de canvas están estrechamente relacionados. Habilita ambos para protección integral.
  • Usa perfiles que coincidan con tu región objetivo. Los conjuntos de fuentes CJK, fuentes RTL y valores predeterminados específicos de locale varían significativamente. Usa un perfil que coincida con el locale esperado.
  • Prueba con múltiples listas de sondeo de fuentes. Diferentes sistemas de rastreo sondean diferentes listas de fuentes. Verifica tu protección contra varias herramientas de prueba.
  • Evita instalar fuentes distintivas. Si usas --bot-config-fonts=expand o real, las fuentes inusuales en tu sistema serán detectables.

Preguntas frecuentes

P: ¿Cuántas fuentes sondean típicamente los scripts de rastreo? R: Las bibliotecas de fingerprinting comunes prueban entre 50 y 500 nombres de fuentes. Algunos scripts exhaustivos sondean más de 1,000 fuentes dirigidas a plataformas e instalaciones de software específicas.

P: ¿BotBrowser incrusta archivos de fuentes reales en el perfil? R: Los perfiles de BotBrowser contienen la información necesaria para controlar la enumeración de fuentes y el comportamiento de métricas de texto. El motor produce mediciones consistentes con la plataforma perfilada sin requerir instalación real de archivos de fuentes.

P: ¿La huella de fuentes puede identificar mi versión específica del SO? R: Sí. Los conjuntos de fuentes predeterminados cambian entre versiones del SO. Windows 11, Windows 10, macOS Sonoma y macOS Ventura tienen cada uno fuentes predeterminadas diferentes. Los sistemas de rastreo mantienen bases de datos que mapean conjuntos de fuentes a versiones del SO.

P: ¿Para qué es el modo de fuentes expand? R: El modo expand usa la lista de fuentes del perfil como conjunto primario y añade fuentes del sistema como fallbacks. Es útil si tu aplicación requiere fuentes del sistema específicas para renderizado pero aún quieres enumeración de fuentes basada en perfil.

P: ¿La protección de fuentes afecta la carga de web fonts? R: No. Las web fonts descargadas de servidores (vía @font-face) no se ven afectadas por la protección de huella de fuentes. Solo se controla la detección de fuentes locales/del sistema.

P: ¿Las métricas de texto son consistentes entre modo headless y con interfaz? R: Sí. BotBrowser controla las métricas de texto a nivel del motor independientemente del modo de visualización.

Resumen

La huella de fuentes combina enumeración de fuentes y mediciones de métricas de texto para crear una señal de rastreo de alta entropía que varía entre sistemas operativos, versiones e instalaciones individuales. BotBrowser controla tanto la lista de fuentes reportada como las métricas de renderizado de texto a nivel del motor, produciendo resultados consistentes con el perfil cargado independientemente de las fuentes reales de tu sistema. Con --bot-config-fonts=profile y --bot-noise-seed, las huellas de fuentes son estables, consistentes y auténticas.

Para temas relacionados, consulta Qué es la huella digital del navegador, Consistencia de señales CSS, Huella digital de Canvas, y Protección de pantalla y ventana.

#Fonts#fingerprinting#Text-Metrics#Privacy

Lleva BotBrowser de la investigación a producción

Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.