1 pontos por GN⁺ 2026-04-23 | 1 comentários | Compartilhar no WhatsApp
  • Apenas a ordem de retorno de indexedDB.databases() já permite gerar um identificador estável que persiste durante a vida do processo em navegadores baseados em Firefox
  • Esse identificador é compartilhado além do escopo de origin, permitindo que sites sem relação entre si observem o mesmo valor dentro do mesmo runtime do navegador e o usem para rastreamento cross-origin
  • No Private Browsing do Firefox, o identificador continua existindo se o processo seguir vivo mesmo após fechar todas as janelas privadas, e permanece até depois de um New Identity no Tor Browser
  • A causa está na implementação do IndexedDB no Gecko, que mapeia nomes de bancos de dados privados para nomes de arquivo baseados em UUID e expõe o resultado sem ordenação
  • A Mozilla distribuiu a correção no Firefox 150 e no ESR 140.10.0, e projetar o sistema sem expor a ordem interna do armazenamento é essencial para proteger a privacidade

Visão geral da vulnerabilidade

  • Em todos os navegadores baseados em Firefox, é possível extrair um identificador que persiste durante a vida do processo pela ordem dos itens retornados por indexedDB.databases()
    • Se um site criar vários bancos de dados IndexedDB e depois verificar a ordem de retorno, ele pode gerar um identificador único e determinístico do processo do navegador em execução
    • Esse comportamento aparece no escopo do processo, não no escopo de origin, então até sites sem relação entre si podem observar o mesmo identificador dentro do mesmo runtime do navegador
  • No Private Browsing do Firefox, o identificador permanece se o processo do Firefox continuar em execução mesmo depois de fechar todas as janelas privadas
    • No Tor Browser, o identificador estável continua existindo até depois de um New Identity, que apaga cookies e histórico e usa um novo circuito Tor
    • Isso entra em conflito com a expectativa de que a atividade posterior do navegador não possa ser vinculada à atividade anterior, enfraquecendo a garantia de não vinculação na qual o usuário confia
  • Foi feita uma divulgação responsável à Mozilla e ao Tor Project
    • A Mozilla distribuiu a correção no Firefox 150 e no ESR 140.10.0
    • O patch está sendo acompanhado no Mozilla Bug 2024220, e a causa está na implementação do IndexedDB do Gecko, afetando também o Tor Browser e outros navegadores baseados em Firefox
  • O princípio da correção é simples
    • O navegador não deve expor externamente a ordem interna do armazenamento no escopo do processo
    • Se os resultados forem normalizados ou retornados em ordem classificada, é possível eliminar a entropia e bloquear o abuso desse identificador estável

Por que isso importa

  • O modo de navegação privada e os navegadores focados em privacidade existem para dificultar a identificação do usuário em contextos diferentes
    • Expectativa geral 1: na ausência de armazenamento compartilhado ou de mecanismos explícitos de identidade, sites sem relação entre si não deveriam conseguir saber se estão interagindo com a mesma instância do navegador
    • Expectativa geral 2: quando uma sessão privada termina, as informações associadas a ela também deveriam desaparecer
  • Esse comportamento quebra as duas expectativas
    • Um site pode derivar um identificador apenas a partir do comportamento interno de armazenamento do navegador, sem cookies, localStorage ou canais explícitos entre sites
    • A ordem dos nomes de bancos de dados retornada pela API fornece um sinal de identificação de alta capacidade
  • Há uma lição importante do ponto de vista de desenvolvimento
    • Vulnerabilidades de privacidade não surgem apenas do acesso direto a dados identificadores
    • Também pode haver vazamento de privacidade quando detalhes internos de implementação são expostos de forma determinística
  • Ponto central sob a ótica de segurança e produto
    • Mesmo uma API aparentemente inofensiva pode virar um vetor de rastreamento entre sites se vazar um estado estável em nível de processo

IndexedDB e indexedDB.databases()

  • IndexedDB é uma API de navegador para armazenamento estruturado de dados no lado do cliente
    • Aplicações web a utilizam para suporte offline, cache, estado de sessão e outros fins de armazenamento local
    • Cada origin pode criar um ou mais bancos de dados nomeados, com object stores e armazenamento de grandes volumes de dados
  • indexedDB.databases() retorna metadados dos bancos de dados visíveis para o origin atual
    • Desenvolvedores podem usar isso para verificar bancos existentes, depurar uso de armazenamento e gerenciar o estado da aplicação
  • Sob expectativas normais de proteção de privacidade, a própria ordem de retorno dessa API não deveria carregar informações identificadoras
    • É necessária uma representação neutra ou normalizada dos metadados dos bancos de dados
    • O problema real foi que, em navegadores baseados em Firefox, a ordem de retorno não era neutra de forma alguma

Como indexedDB.databases() virou um identificador estável

  • No Private Browsing do Firefox, indexedDB.databases() retorna metadados em uma ordem derivada da estrutura interna de armazenamento, e não da ordem de criação dos bancos de dados
    • A implementação relacionada fica em dom/indexedDB/ActorsParent.cpp
  • No Private Browsing, os nomes dos bancos de dados não são usados diretamente como identificadores em disco
    • Em vez disso, eles são mapeados para uma base de nome de arquivo baseada em UUID por meio da tabela hash global StorageDatabaseNameHashtable = nsTHashMap<nsString, nsString>
    • Esse mapeamento ocorre em GetDatabaseFilenameBase() dentro de OpenDatabaseOp::DoDatabaseWork()
  • Quando aIsPrivate é true, o nome do banco de dados fornecido pelo site é substituído por um UUID gerado e armazenado na StorageDatabaseNameHashtable global
    • A chave usa apenas a string do nome do banco de dados
    • Persiste durante a vida do QuotaClient do IndexedDB
    • É compartilhado entre todos os origins
    • Só é reinicializado quando o Firefox é totalmente reiniciado
  • Depois, ao chamar indexedDB.databases(), o Firefox coleta os nomes de arquivo dos bancos em GetDatabasesOp::DoDatabaseWork() por meio de QuotaClient::GetDatabaseFilenames(...)
    • Os nomes-base dos bancos são inseridos em um nsTHashSet
    • Nenhuma ordenação é feita antes da iteração
  • A ordem final dos resultados é determinada pelo percurso do layout interno dos buckets do conjunto hash
    • Como o mapeamento UUID permanece estável durante a vida do processo do Firefox, a ordem retornada também permanece como uma função determinística dos valores UUID gerados, do comportamento da função de hash, da capacidade da tabela hash e do histórico de inserção
    • Essa ordem persiste entre abas e janelas privadas, sendo redefinida apenas com um reinício completo do Firefox
    • Tanto o mapeamento UUID quanto a iteração do conjunto hash existem no escopo do processo, e não no escopo de origin

Como reproduzir

  • É possível demonstrar o comportamento com um PoC simples
    • Dois origins diferentes hospedam o mesmo script
    • Cada script cria bancos de dados com um conjunto fixo de nomes, chama indexedDB.databases(), extrai a ordem retornada e a imprime
  • Em builds afetadas do Firefox Private Browsing e do Tor Browser, os dois origins observam a mesma permutação durante a vida do mesmo processo do navegador
    • Ao reiniciar o navegador, a permutação muda
  • Exemplo conceitual de saída
    • Ordem de criação: a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p
    • Ordem de retorno: g,c,p,a,l,f,n,d,j,b,o,h,e,m,i,k
  • O ponto principal não é a ordem exata em si
    • Ela difere da ordem de criação original
    • A mesma ordem aparece em origins sem relação entre si
    • Persiste após recarregar a página, abrir uma nova janela privada e até depois de fechar todas as janelas privadas
    • Só uma reinicialização completa do navegador gera uma nova ordem
    • Isso permite verificar diretamente uma propriedade indesejada do ponto de vista da privacidade

Impacto na privacidade

  • Essa vulnerabilidade permite tanto rastreamento cross-origin quanto same-origin dentro de um único runtime do navegador
  • Impacto cross-origin

    • Sites sem relação entre si podem derivar independentemente o mesmo identificador e inferir que estão interagindo com o mesmo processo em execução do Firefox ou do Tor Browser
    • Torna possível vincular atividades entre domínios mesmo sem cookies ou outro armazenamento compartilhado
  • Impacto same-origin

    • No Private Browsing do Firefox, o identificador permanece se o processo do Firefox continuar em execução mesmo depois de todas as janelas privadas serem fechadas
    • Um site pode reconhecer novamente visitas posteriores que aparentam ser uma nova sessão privada
    • No Tor Browser, o identificador estável praticamente neutraliza o isolamento de New Identity dentro do processo do navegador em execução
    • Isso permite vincular sessões que deveriam estar totalmente separadas
  • Por que isso é especialmente grave no Tor Browser

    • O Tor Browser foi projetado para reduzir a possibilidade de ligação entre sites e minimizar a identificação em nível de instância do navegador
    • Um identificador estável que persiste durante a vida do processo entra em choque direto com esse objetivo de design
    • Mesmo sobrevivendo apenas até um reinício completo do processo, isso já basta para enfraquecer a não vinculação durante uso ativo

Entropia e capacidade de fingerprinting

  • Esse sinal não é apenas estável, como também tem alta capacidade
    • Se um site controla N nomes de bancos de dados, o número de permutações observáveis é N!
    • A entropia teórica é log2(N!)
  • Com 16 nomes controláveis, o espaço teórico é de cerca de 44 bits
    • Um nível suficiente para distinguir instâncias simultâneas de navegador em ambientes reais
  • Por causa do comportamento da tabela hash interna, o número de permutações realmente atingível pode ser um pouco menor
    • Mas isso não muda o ponto central do ponto de vista de segurança
    • A ordem exposta ainda fornece entropia suficiente para funcionar como um identificador forte

Como corrigir

  • A correção correta é interromper a exposição de entropia derivada do layout interno do armazenamento
    • A mitigação mais limpa é retornar os resultados em uma ordem canônica, como ordenação lexicográfica
    • Isso preserva a utilidade da API para desenvolvedores enquanto remove o sinal de fingerprinting
  • Randomizar a saída a cada chamada também poderia ocultar a ordem estável
    • Ainda assim, ordenar é uma opção mais simples, previsível e fácil para desenvolvedores entenderem
  • Condições ideais da correção sob a ótica de engenharia de segurança
    • Baixa complexidade conceitual
    • Risco mínimo de compatibilidade
    • Eliminação direta do vazamento de privacidade

Divulgação responsável

  • Foi feita uma divulgação responsável à Mozilla e ao Tor Project
    • A Mozilla distribuiu a correção no Firefox 150 e no ESR 140.10.0
    • O patch está sendo acompanhado no Mozilla Bug 2024220
  • A origem do comportamento está na implementação do IndexedDB do Gecko
    • Navegadores derivados do Gecko, incluindo o Tor Browser, também entram na área de impacto se não tiverem uma mitigação própria

Design centrado em privacidade

  • Até pequenos detalhes de implementação podem levar a problemas relevantes de privacidade
    • Sites sem relação entre si podem vincular atividades além do origin durante o mesmo runtime do navegador
    • O identificador sobrevive mais tempo do que o usuário espera, enfraquecendo os limites de sessões privadas
  • O lado positivo é que a correção é simples e eficaz
    • Normalizar a saída antes de retorná-la remove essa fonte de entropia
    • Isso permite restaurar os limites de privacidade esperados
  • É um tipo de vulnerabilidade fácil de ignorar, mas com grande impacto e que merece atenção especial ao criar funcionalidades sensíveis à privacidade

1 comentários

 
GN⁺ 2026-04-23
Comentários do Hacker News
  • Achei esta pesquisa realmente impressionante, e o texto também foi muito bem escrito
    Fiquei até surpreso por não terminar com propaganda do produto
    Ainda assim, se o produto dessa empresa faz fingerprinting, fico curioso sobre por que eles reportaram essa vulnerabilidade à Mozilla
    Mesmo que fosse antiético, para se diferenciar da concorrência não faria mais sentido, do ponto de vista de negócio, manter isso em sigilo?
    Quase nunca vejo agentes de ameaça queimando seus próprios zero-days com divulgação responsável

    • Eu não uso vulnerabilidades no nosso produto
    • Acho que, para começo de conversa, eles não dependiam dessa vulnerabilidade, e o ponto importante é que, ao divulgá-la, os outros também deixam de poder usá-la
  • Como diz o artigo, o identificador pode persistir enquanto o processo do Firefox continuar vivo, então no Tor Browser é importante encerrar completamente ao fim da sessão
    Também é importante não misturar usos diferentes dentro de uma mesma sessão

  • O link postado pelo OP deu timeout no meu ambiente Tor, mas a versão no Wayback abriu sem problemas
    E também fiquei curioso se existem pesquisadores acadêmicos trabalhando nesse tema
    Conheço o trabalho de grupos como a EFF, mas estou procurando mais gente do meio universitário ou de institutos de pesquisa puros como MSR e PARC, em vez de ativistas de ONG
    Como alguém muito interessado em privacidade, sinto que com a minha santíssima trindade pessoal de noscript, ublock origin e firefox containers dá para cuidar razoavelmente bem da segurança, mas a anonimidade parece sempre escapar por entre os dedos por causa do fingerprinting
    Se ampliar fingerprinting para incluir stylometry, isso vale ainda mais

    • Fingerprinting na web é uma área ativamente pesquisada tanto no lado do ataque quanto no da defesa
      Como exemplo, vale procurar conferências como a PETS
  • Eu me pergunto como é que os sites podem acessar esse tipo de informação sem sequer perguntar ao usuário ou avisá-lo
    Queria entender por que os navegadores não funcionam mais como celulares, exigindo permissão quando um servidor ou app tenta acessar esse tipo de dado

    • Eu diria que fingerprinting de navegador é mais um efeito colateral das funcionalidades que o navegador oferece
      O user agent, que informa a versão do navegador, é razoavelmente justificável, e até perguntar quais fontes existem no sistema é difícil de eliminar completamente por causa do suporte tipográfico
      Fuso horário, idioma, layout de teclado, tamanho da tela e tamanho da janela também são necessários para o funcionamento normal da web
      Também é natural precisar saber quais formatos um player de vídeo ou áudio suporta para servir a mídia adequada
      Enquanto o JavaScript puder ler a hora, também é fácil descobrir o desvio do relógio do sistema comparando com a hora do servidor
      Quando tudo isso vai se acumulando, quase todo navegador acaba ficando identificável de forma única
    • Quem faz o navegador mais usado é uma empresa de publicidade
      E, além disso, essa empresa também financia em boa parte o maior concorrente
      Então não acho essa realidade surpreendente
    • Ainda assim, me parece melhor do que app
      Apps conseguem acessar muito mais identificadores e características do dispositivo
      Acho que isso vale até em sistemas relativamente bem protegidos, sem Google Play services
    • Isso me faz pensar em celulares Android
      Já no lado da Apple, sinto falta justamente de um controle detalhado
    • Acho que existe uma linha muito delicada entre manter a usabilidade da web, impedir fingerprinting e não bombardear o usuário com dezenas ou centenas de pop-ups de permissão
      Como o navegador já tem uma complexidade comparável à de um sistema operacional, qualquer parte do sistema pode acabar sendo exposta e explorada sem intenção
  • A expressão process-scoped no texto me deixou um pouco confuso
    Lembro que, em 2021, a Mozilla apresentou um experimento de one-process-per-site para o Firefox e explicou que isso criaria, no Firefox desktop, fronteiras no nível de processo do sistema operacional entre todos os sites
    O texto relacionado é Introducing Site Isolation in Firefox
    Então fiquei na dúvida se esse recurso ainda não foi totalmente distribuído, ou se foi distribuído mas o IndexedDB continua fora desse isolamento

    • Só depois de ler este comentário entendi que isso queria dizer que ainda restam alguns comportamentos globais, e que é por essa brecha que o fingerprinting se torna possível
      Nesse caso, achei uma explicação bem interessante
  • Por essa explicação, parece que isso não persiste depois de reiniciar o navegador, então será que, do ponto de vista do atacante, a utilidade disso não cai bastante?

    • Achei que este trecho citado no artigo explica bem o risco
      No Firefox Private Browsing, mesmo que todas as janelas privadas sejam fechadas, o identificador pode persistir se o processo do Firefox continuar ativo
      No Tor Browser, entendo que até o New Identity, que deveria fazer um reset completo limpando cookies e histórico e usando um novo circuito Tor, ainda mantém um identificador estável
    • O modo de uso nesse caso é id bridging
      Primeiro, o site faz fingerprinting do navegador e salva no cookie um ID e o fingerprint
      Na sessão seguinte, faz o fingerprinting de novo, compara com o cookie e, se o valor mudou, informa ao servidor tanto o fingerprint antigo quanto o novo para conectá-los
    • Muita gente deixa o navegador aberto por meses
    • Fico em dúvida se a utilidade realmente cai tanto assim
      Órgãos estatais talvez já conheçam ou consigam rastrear muitos nós, e cruzando vários metadados pode ser possível identificar alguém com bastante precisão
      Nem sempre é preciso estar 100% correto; também pode bastar acumular muita informação indireta, externa ao próprio alvo, como dados da área ao redor ou obtidos através da parede
      Para mim, isso parece um tipo de identificação por informações proxy
  • Para falar a verdade, boa parte dos Web Standards parece ser usada mais para fingerprinting do que para funcionalidade real
    IndexedDB também parece ser usado por poucos sites como armazenamento de verdade; fico me perguntando quem realmente precisa disso
    Por isso, acho que a própria direção de continuar expandindo os padrões web está errada
    O navegador deveria fornecer só APIs mínimas para interagir com o dispositivo, e recursos como IndexedDB poderiam ser implementados como bibliotecas em WebAssembly sem vazar dados valiosos
    Por exemplo, se canvas fornecesse apenas acesso ao buffer de imagem, sem rotinas de desenho que chamam bibliotecas específicas da plataforma, o valor de fingerprinting cairia bastante

    • Com extensões de navegador como "Local Storage Editor", dá para ver diretamente o conteúdo do Local Storage de um site
      Nos casos que eu vi até hoje, isso aparecia em lugares como o gmail, para cachear imagens de longa duração, ou como outra forma de manter o estado de login sem depender de cookies
  • Fiquei um pouco confuso aqui
    Se o UUID do IndexedDB é compartilhado entre todas as origins, então não daria para identificar o navegador pelo próprio conteúdo do banco, e não pela ordem?

    • Há um exemplo fácil de entender na página
      Se uma página cria bancos de dados chamados a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p e consulta a ordem, pode obter algo como g,c,p,a,l,f,n,d,j,b,o,h,e,m,i,k, de acordo com um mapeamento global nome-UUID
      A vulnerabilidade central é que, enquanto o processo do Firefox estiver vivo, qualquer site que criar um conjunto de bancos com os mesmos nomes verá exatamente a mesma ordem, independentemente do conteúdo
      Isso vira um identificador estável e de alta entropia ao longo do tempo, ou seja, um fingerprint
      Ele é compartilhado entre origins e, mesmo depois de apagar os dados do site, basta recriar os bancos com os mesmos nomes para recuperar o fingerprint pela ordem
    • O conteúdo dos dados, naturalmente, fica limitado ao escopo da origin
      Se não fosse assim, o IndexedDB seria um evercookie fácil demais
    • O que é compartilhado no navegador entre origins não é o conteúdo do banco, e sim o mapeamento de UUID
      Entendo que cada origin só enxerga o subconjunto de bancos ligado àquela origin
  • Fiquei me perguntando se o Tor Browser ainda permite JavaScript por padrão
    Pelo que entendi, se bloquear a execução de JavaScript, essa vulnerabilidade também não deveria afetar

    • Na prática, desligar JavaScript faz seu fingerprint ficar ainda mais chamativo
      Não há tantos usuários com JS desativado, então você entra imediatamente num grupo muito menor e fica mais propenso a ser único
      Claro que, sem JS, há menos formas de coletar detalhes, mas também fica mais fácil distinguir você com pouca informação
      Além disso, o Tor Browser, de forma estranha, não faz spoof de navigator.platform, então mesmo que o User-Agent finja ser Windows, o site ainda consegue ver que você usa Linux