1 puntos por GN⁺ 2026-04-23 | 1 comentarios | Compartir por WhatsApp
  • Solo con el orden de retorno de indexedDB.databases() es posible generar un identificador estable que se mantiene durante la vida del proceso en navegadores basados en Firefox
  • Este identificador se comparte más allá del alcance del origin, por lo que incluso sitios no relacionados pueden observar el mismo valor dentro del mismo tiempo de ejecución del navegador y usarlo para rastreo cross-origin
  • En Private Browsing de Firefox, el identificador se mantiene aunque se cierren todas las ventanas privadas si el proceso sigue vivo, y también persiste después de New Identity en Tor Browser
  • La causa está en que la implementación de IndexedDB de Gecko asigna los nombres de bases de datos privadas a nombres de archivo basados en UUID y expone ese resultado sin ordenarlo
  • Mozilla publicó la corrección en Firefox 150 y ESR 140.10.0; diseñar el sistema para no exponer hacia afuera el orden del almacenamiento interno es importante para proteger la privacidad

Resumen de la vulnerabilidad

  • En todos los navegadores basados en Firefox, es posible extraer un identificador que perdura durante la vida del proceso a partir del orden de los elementos devueltos por indexedDB.databases()
    • Si un sitio web crea varias bases de datos de IndexedDB y luego revisa el orden de retorno, puede generar un identificador único y determinista del proceso del navegador en ejecución
    • Este comportamiento no aparece a nivel de origin sino a nivel de proceso, por lo que sitios no relacionados pueden observar el mismo identificador dentro del mismo tiempo de ejecución del navegador
  • En Private Browsing de Firefox, el identificador se conserva aunque se cierren todas las ventanas privadas, siempre que el proceso de Firefox siga en ejecución
    • En Tor Browser, el identificador estable permanece incluso después de New Identity, que borra cookies e historial y usa un nuevo circuito de Tor
    • Esto entra en conflicto con la expectativa de que la actividad posterior no debería poder vincularse con la anterior, debilitando la garantía de desvinculación en la que confía el usuario
  • Se realizó una divulgación responsable a Mozilla y al Tor Project
    • Mozilla distribuyó la corrección en Firefox 150 y ESR 140.10.0
    • El parche se sigue en Mozilla Bug 2024220, y la causa está en la implementación de IndexedDB de Gecko, por lo que también afecta a Tor Browser y a otros navegadores basados en Firefox
  • El principio de la corrección es simple
    • El navegador no debería exponer hacia afuera el orden del almacenamiento interno con alcance de proceso
    • Si los resultados se normalizan o se devuelven ordenados, se puede eliminar la entropía y bloquear el abuso de este identificador estable

Por qué importa

  • El modo de navegación privada y los navegadores centrados en la privacidad buscan dificultar la identificación del usuario entre distintos contextos
    • Expectativa general 1: salvo que exista almacenamiento compartido o un mecanismo de identidad explícito, sitios no relacionados no deberían poder saber si están interactuando con la misma instancia del navegador
    • Expectativa general 2: cuando termina una sesión privada, también debería desaparecer la información asociada con esa sesión
  • Este comportamiento rompe ambas expectativas
    • Un sitio puede derivar un identificador a partir del comportamiento interno del almacenamiento del navegador sin cookies, localStorage ni canales explícitos entre sitios
    • El orden de los nombres de bases de datos devuelto por la API puede ofrecer una señal de identificación de alta capacidad
  • Hay una lección importante desde la perspectiva de desarrollo
    • Las vulnerabilidades de privacidad no surgen solo por el acceso directo a datos identificatorios
    • También puede haber filtraciones cuando detalles internos de implementación quedan expuestos de forma determinista
  • Punto clave desde seguridad y producto
    • Incluso una API aparentemente inocua puede convertirse en un vector de rastreo entre sitios si filtra un estado estable a nivel de proceso

IndexedDB y indexedDB.databases()

  • IndexedDB es una API del navegador para almacenamiento estructurado de datos del lado del cliente
    • Las aplicaciones web la usan para soporte offline, caché, estado de sesión y otros fines de almacenamiento local
    • Cada origin puede crear una o más bases de datos con nombre y almacenar object store y grandes volúmenes de datos
  • indexedDB.databases() devuelve metadatos de las bases de datos visibles para el origin actual
    • Los desarrolladores pueden usarla para revisar bases de datos existentes, depurar uso de almacenamiento y administrar el estado de la aplicación
  • Bajo una expectativa normal de privacidad, el orden de retorno de esta API no debería contener información identificatoria
    • Se necesita una representación neutral o normalizada de los metadatos de las bases de datos
    • El problema real fue que, en los navegadores basados en Firefox, ese orden de retorno no era neutral en absoluto

Cómo indexedDB.databases() se convirtió en un identificador estable

  • En Firefox Private Browsing, indexedDB.databases() devuelve los metadatos no en orden de creación de la base de datos, sino en un orden derivado de la estructura de almacenamiento interna
    • La implementación relevante está en dom/indexedDB/ActorsParent.cpp
  • En Private Browsing, los nombres de las bases de datos no se usan directamente como identificadores en disco
    • En su lugar, se asignan a una base de nombre de archivo basada en UUID mediante la tabla hash global StorageDatabaseNameHashtable = nsTHashMap<nsString, nsString>
    • Esa asignación se realiza en GetDatabaseFilenameBase() dentro de OpenDatabaseOp::DoDatabaseWork()
  • Cuando aIsPrivate es true, el nombre de la base de datos proporcionado por el sitio se reemplaza por un UUID generado y se guarda en StorageDatabaseNameHashtable
    • La clave usa únicamente la cadena del nombre de la base de datos
    • Persiste durante la vida del QuotaClient de IndexedDB
    • Se comparte entre todos los origins
    • Solo se reinicia al cerrar por completo Firefox
  • Más tarde, cuando se llama a indexedDB.databases(), Firefox recopila los nombres de archivo de las bases de datos mediante QuotaClient::GetDatabaseFilenames(...) en GetDatabasesOp::DoDatabaseWork()
    • Los nombres base de las bases de datos se insertan en un nsTHashSet
    • No se realiza ninguna ordenación antes de iterar
  • El orden final de resultados queda determinado por el recorrido de la distribución interna de buckets del conjunto hash
    • Como la asignación UUID se mantiene estable durante la vida del proceso de Firefox, el orden de retorno también permanece como una función determinista de los valores UUID generados, del comportamiento de la función hash, de la capacidad de la tabla hash y del historial de inserciones
    • Ese orden se mantiene entre pestañas y ventanas privadas, y solo se reinicia con un reinicio completo de Firefox
    • Tanto la asignación UUID como la iteración del conjunto hash tienen alcance de proceso, no de origin

Cómo reproducirlo

  • Se puede demostrar el comportamiento con un PoC simple
    • Dos origins distintos alojan el mismo script
    • Cada script crea bases de datos con un conjunto fijo de nombres, llama a indexedDB.databases(), extrae el orden devuelto y lo muestra
  • En versiones afectadas de Firefox Private Browsing y Tor Browser, ambos origins observan la misma permutación durante la vida del mismo proceso del navegador
    • Al reiniciar el navegador, la permutación cambia
  • Se muestra un ejemplo conceptual de salida
    • Orden de creación: a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p
    • Orden de retorno: g,c,p,a,l,f,n,d,j,b,o,h,e,m,i,k
  • Lo importante no es el orden exacto en sí
    • Es distinto del orden original de creación
    • El mismo orden aparece en origins no relacionados
    • Se mantiene tras recargar, abrir una nueva ventana privada o incluso cerrar todas las ventanas privadas
    • Solo se genera un nuevo orden al reiniciar por completo el navegador
    • Esto permite verificar directamente una propiedad no deseada desde el punto de vista de la privacidad

Impacto en la privacidad

  • Esta vulnerabilidad permite tanto rastreo cross-origin como same-origin dentro de un mismo tiempo de ejecución del navegador
  • Impacto cross-origin

    • Sitios web no relacionados pueden derivar de forma independiente el mismo identificador e inferir que están interactuando con el mismo proceso en ejecución de Firefox o Tor Browser
    • Eso permite vincular actividad entre dominios incluso sin cookies ni otro almacenamiento compartido
  • Impacto same-origin

    • En Firefox Private Browsing, el identificador persiste aunque se cierren todas las ventanas privadas, siempre que el proceso de Firefox siga en ejecución
    • Un sitio puede volver a reconocer visitas posteriores que aparentan ser una nueva sesión privada
    • En Tor Browser, el identificador estable prácticamente anula el aislamiento de New Identity dentro del proceso del navegador en ejecución
    • Esto permite vincular sesiones que deberían estar completamente separadas
  • Por qué es especialmente grave en Tor Browser

    • Tor Browser está diseñado para reducir la posibilidad de vinculación entre sitios y minimizar la identificación a nivel de instancia del navegador
    • Un identificador estable que dura toda la vida del proceso choca directamente con ese objetivo de diseño
    • Aunque solo sobreviva hasta un reinicio completo del proceso, eso basta para debilitar la desvinculación durante el uso activo

Entropía y capacidad de fingerprinting

  • Esta señal no solo es estable, también tiene alta capacidad
    • Si un sitio controla N nombres de bases de datos, la cantidad de permutaciones observables es N!
    • La entropía teórica es log2(N!)
  • Con 16 nombres controlables, el espacio teórico es de aproximadamente 44 bits
    • Eso alcanza para distinguir instancias concurrentes del navegador en entornos reales
  • Debido al comportamiento de la tabla hash interna, la cantidad real de permutaciones alcanzables podría ser algo menor
    • Sin embargo, eso no cambia el punto central desde el punto de vista de seguridad
    • El orden expuesto sigue aportando suficiente entropía para funcionar como un identificador fuerte

Cómo se corrigió

  • La corrección adecuada consiste en dejar de exponer la entropía derivada de la distribución del almacenamiento interno
    • La mitigación más limpia es devolver los resultados en un orden canónico, como orden lexicográfico
    • Así se conserva la utilidad de la API para los desarrolladores y se elimina la señal de fingerprinting
  • Aleatorizar la salida en cada llamada también podría ocultar el orden estable
    • Pero ordenar es una opción más simple, predecible y fácil de entender para los desarrolladores
  • Se describen las condiciones ideales de la corrección desde la ingeniería de seguridad
    • Baja complejidad conceptual
    • Riesgo mínimo de compatibilidad
    • Eliminación directa de la filtración de privacidad

Divulgación responsable

  • Se realizó una divulgación responsable a Mozilla y al Tor Project
    • Mozilla distribuyó la corrección en Firefox 150 y ESR 140.10.0
    • El parche se sigue en Mozilla Bug 2024220
  • El origen del comportamiento está en la implementación de IndexedDB de Gecko
    • Los navegadores derivados de Gecko, incluido Tor Browser, también quedan dentro del alcance si no aplican mitigaciones propias

Diseño centrado en la privacidad

  • Incluso pequeños detalles de implementación pueden convertirse en problemas de privacidad significativos
    • Sitios no relacionados pueden vincular actividad más allá del origin durante el mismo tiempo de ejecución del navegador
    • El identificador sobrevive más de lo que espera el usuario y debilita los límites de las sesiones privadas
  • Lo positivo es que la corrección es simple y efectiva
    • Normalizar la salida antes de devolverla elimina esta fuente de entropía
    • Eso permite restaurar los límites de privacidad esperados
  • Es un tipo de vulnerabilidad fácil de pasar por alto pero con gran impacto, y vale la pena tenerla muy presente al crear funciones sensibles a la privacidad

1 comentarios

 
GN⁺ 2026-04-23
Comentarios de Hacker News
  • Sentí que esta investigación fue realmente impresionante y que el texto también estuvo muy bien escrito
    Hasta me sorprendió que al final no apareciera publicidad del producto
    Aun así, si el producto de esta empresa hace fingerprinting, me pregunto por qué reportaron esta vulnerabilidad a Mozilla
    Incluso si fuera poco ético, para diferenciarse de la competencia parecería mejor para el negocio guardársela en privado
    Casi nunca he visto a actores de amenazas quemar sus propios zero-day con una divulgación responsable

    • Yo no uso vulnerabilidades en nuestro producto
    • Creo que en primer lugar no dependían de esa vulnerabilidad, y que lo importante es que al publicarla tampoco podrán usarla los demás
  • Como dice el artículo, el identificador puede mantenerse mientras el proceso de Firefox siga vivo, así que en Tor Browser hay que cerrarlo completamente al terminar la sesión
    También es importante no mezclar distintos usos dentro de una misma sesión

  • El enlace que puso OP me dio timeout en mi entorno de Tor, pero la versión en Wayback abrió sin problema
    Y también me pregunto si hay investigadores académicos que trabajen este tema
    Conozco el trabajo de grupos como la EFF, pero más que activistas de ONG estoy buscando profesores universitarios o gente de laboratorios de investigación pura como MSR o PARC
    Como alguien muy interesado en la privacidad, siento que con mi holy trinity personal de noscript, ublock origin y firefox containers puedo cubrir bastante bien la seguridad, pero la anonimidad se me sigue escapando entre los dedos por culpa del fingerprinting
    Si ampliamos el concepto de fingerprinting para incluir también la stylometry, aún más

    • El fingerprint web es un área muy investigada tanto en ataque como en defensa
      Por ejemplo, te puede servir buscar conferencias como PETS
  • Me parece cuestionable que un sitio web pueda acceder a este tipo de información sin siquiera preguntarle ni avisarle al usuario
    Me pregunto por qué los navegadores no están hechos para pedir permiso igual que un teléfono cuando un servidor o una app quieren acceder a este tipo de datos

    • Creo que el fingerprinting del navegador se parece más a un efecto secundario de las funciones que ofrece el navegador
      El user agent que informa la versión del navegador es más o menos razonable, y tampoco es fácil eliminar por completo funciones que preguntan qué tipografías hay en el sistema porque hacen falta para el soporte de fuentes
      La zona horaria, el idioma, la distribución del teclado, el tamaño de la pantalla y el tamaño de la ventana también son necesarios para el funcionamiento normal de la web
      También es lógico tener que saber qué formatos soporta un reproductor de video o audio para poder entregar el medio adecuado
      Mientras JavaScript pueda leer la hora, también será fácil inferir la desviación del reloj del sistema comparándola con la hora del servidor
      Si vas acumulando todo eso, casi cualquier navegador termina quedando identificado de forma única
    • La organización que hace el navegador más usado es una empresa de publicidad
      Y además esa empresa financia en buena parte a su mayor competidor
      Así que esta realidad no me sorprende
    • Aun así, siento que sigue siendo mejor que las apps
      Las apps pueden acceder mucho más a identificadores y características del dispositivo
      Incluso en sistemas relativamente bien protegidos y sin Google Play services
    • Eso me hace pensar en teléfonos como Android
      De hecho, del lado de Apple me decepciona que casi no haya control granular
    • Creo que hay una línea muy delicada entre mantener la usabilidad de la web, impedir el fingerprinting y no bombardear al usuario con decenas o cientos de pop-ups de permisos
      Como el navegador ya tiene una complejidad comparable a la de un sistema operativo, cualquier parte del sistema puede terminar expuesta y ser explotada sin intención
  • La expresión process-scoped del texto me confundió un poco
    Recuerdo que Mozilla explicó en 2021, al presentar su experimento de one-process-per-site para Firefox, que en Firefox de escritorio pondrían límites a nivel de proceso del sistema operativo entre todos los sitios
    El artículo relacionado es Introducing Site Isolation in Firefox
    Entonces me pregunto si esta función todavía no se ha desplegado por completo, o si sí se desplegó pero IndexedDB queda fuera de ese aislamiento

    • Solo después de ver este comentario entendí que lo que querían decir es que todavía quedan algunos comportamientos globales, y que por ahí se puede hacer fingerprinting
      Si es así, me parece una explicación bastante interesante
  • Por como está explicado, parecería que no persiste después de reiniciar el navegador; si es así, da la impresión de que para un atacante pierde bastante utilidad, ¿no?

    • Siento que esta parte citada en el artículo explica bien el riesgo
      En Firefox Private Browsing, el identificador puede persistir aunque cierres todas las ventanas privadas, siempre que el proceso de Firefox siga vivo
      En Tor Browser, entiendo que el identificador estable se mantiene incluso si usas New Identity, que se supone que hace un reinicio total borrando cookies e historial y usando un nuevo circuito de Tor
    • La técnica que se usa en este caso es id bridging
      Primero, el sitio hace fingerprinting del navegador y guarda en una cookie un ID junto con el fingerprint
      En la siguiente sesión vuelve a hacer fingerprinting, lo compara con la cookie y, si cambió, le informa al servidor tanto el fingerprint anterior como el nuevo para vincularlos
    • Mucha gente deja el navegador abierto durante meses
    • Tengo dudas de que realmente pierda tanta utilidad
      Es posible que los organismos estatales ya conozcan o puedan rastrear muchos nodos, y que cruzando varios metadatos se pueda identificar a una persona con bastante precisión
      Tampoco hace falta tener 100% de exactitud siempre; basta con reunir mucha información indirecta ajena al objetivo en sí, como datos del área cercana o información obtenida desde detrás de una pared
      Siento que es una forma de identificar usando una especie de información proxy
  • Francamente, gran parte de los Web Standards parece usarse más para fingerprinting que para funcionalidad real
    Incluso IndexedDB da la impresión de que pocos sitios lo usan de verdad para almacenamiento, y uno se pregunta quién lo necesita tanto
    Por eso creo que está mal la dirección de seguir expandiendo los estándares web
    El navegador debería ofrecer solo APIs mínimas para interactuar con el dispositivo, y funciones como IndexedDB podrían implementarse como bibliotecas WebAssembly que no filtren datos valiosos
    Por ejemplo, si canvas solo diera acceso al buffer de dibujo sin rutinas de renderizado que llamen a bibliotecas distintas según la plataforma, su valor para fingerprinting sería mucho menor

    • Si usas extensiones del navegador como "Local Storage Editor", puedes ver directamente el contenido de Local Storage de un sitio
      En los casos que yo he visto, se usa para cachear imágenes de larga duración en sitios como gmail o como otra forma de mantener la sesión iniciada en lugar de usar cookies
  • Aquí sí me confundí un poco
    Si el UUID de IndexedDB se comparte entre todos los origin, entonces ¿no bastaría con identificar el navegador por el contenido de la base de datos en vez de por el orden?

    • En la página hay un ejemplo fácil de entender
      Si una página crea las bases de datos a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p y consulta el orden, puede obtener algo como g,c,p,a,l,f,n,d,j,b,o,h,e,m,i,k según la asignación global nombre-UUID
      La vulnerabilidad clave es que, mientras el proceso de Firefox siga vivo, cualquier sitio web que cree un mismo conjunto de nombres de base de datos verá exactamente el mismo orden, sin importar el contenido
      Por eso esto se convierte en un identificador estable de alta entropía a lo largo del tiempo, es decir, un fingerprint
      Se comparte entre origin, y aun después de borrar los datos del sitio se puede recuperar el fingerprint simplemente recreando los mismos nombres y observando el orden
    • El contenido de los datos, por supuesto, sí está limitado al alcance del origin
      Si no fuera así, IndexedDB sería una evercookie demasiado fácil
    • Lo que comparte el navegador entre origin no es el contenido de la base de datos, sino la asignación UUID
      Entiendo que a cada origin solo se le expone el subconjunto de bases de datos vinculado a ese origin
  • Me preguntaba si Tor Browser todavía permite JavaScript por defecto
    Según entiendo, si bloqueas la ejecución de JavaScript, esta vulnerabilidad no debería afectarte

    • En la práctica, desactivar JavaScript hace que tu fingerprint sea mucho más visible
      No hay tantos usuarios con JS desactivado, así que entras de inmediato en un grupo mucho más pequeño y dentro de él es más fácil volverte único
      Claro que sin JS se reducen las opciones para recolectar detalles, pero también se vuelve más fácil distinguirte con menos información
      Además, de forma extraña, Tor Browser no spoofea navigator.platform en absoluto, así que aunque el User-Agent finja ser Windows, el sitio todavía puede ver si usas Linux