1 pontos por GN⁺ 2024-10-08 | 1 comentários | Compartilhar no WhatsApp
  • O commit do uBlock Origin reescreve o fluxo de CNAME uncloaking no processamento de rede do Firefox e passa a refletir em details.ip o IP obtido pela consulta DNS
  • O cache cnames em Map foi removido e substituído por um buffer circular de 256 entradas com base em dnsList, dnsDict e dnsWritePtr, além de cache TTL de 60000ms
  • A consulta DNS usa browser.dns.resolve(hn, [ 'canonical_name' ]), aproveitando canonicalName e addresses[0] do resultado como CNAME e IP, respectivamente
  • O tratamento de exceções de CNAME mantém as condições de 1st-party, lista de ignorados e documento raiz, e nomes de host em formato de endereço IPv4 ou iniciados por [ ficam excluídos de nova consulta
  • A versão mínima do Chromium sobe para 80.0, a do Opera para 67.0, e o valor padrão oculto de cnameMaxTTL é removido

Reescrita da estrutura de cache DNS no Firefox

  • O código relacionado a CNAME uncloaking em platform/firefox/vapi-background-ext.js mudou de uma estrutura global centrada em Map para uma estrutura interna de cache DNS dentro da classe
  • No lugar do estado global cnameUncloakEnabled e do Map cnames, o cache passa a ser gerenciado pelos seguintes campos
    • dnsList: buffer circular
    • dnsWritePtr: próxima posição de escrita
    • dnsMaxCount: máximo de 256
    • dnsDict: mapeamento do nome de host para o índice no buffer circular
    • dnsEntryTTL: 60000ms
  • No construtor, canUncloakCnames e cnameUncloakEnabled são inicializados como true

Fluxo de processamento de requisições

  • onBeforeSuspendableRequest(details) extrai o nome de host da URL da requisição e primeiro verifica o cache com dnsFromCache(hn)
  • Se a entrada DNS em cache tiver ip, ele é definido em details.ip
  • Se o resultado da chamada padrão super.onBeforeSuspendableRequest(details) terminar em cancelamento, redirecionamento ou equivalente, esse resultado é retornado como está
  • Se a entrada DNS em cache não for um Promise, o processamento continua em onAfterDNSResolution(hn, details, dnsEntry)
  • Se as condições para nova resolução DNS não forem atendidas, ou se details.proxyInfo?.proxyDNS existir, nenhum processamento DNS adicional é feito

Forma de consulta e armazenamento DNS

  • dnsShouldResolve(hn) exclui da consulta DNS nomes de host vazios, nomes iniciados por [ e formatos de endereço IPv4
  • dnsResolve(hn, details) registra o nome de host na posição atual do buffer circular e chama dnsAPI.resolve(hn, [ 'canonical_name' ])
  • Em caso de sucesso, dnsToCache(hn, rec, details) é executado; em caso de falha, dnsToCache(hn) deixa uma entrada vazia no cache
  • dnsToCache armazena na nova entrada de cache o hn e o instante de expiração
    • Se cnameFromRecord retornar valor, ele é salvo em dnsEntry.cname
    • Se ipFromRecord retornar valor, ele é salvo em dnsEntry.ip
  • dnsFromCache retorna a entrada diretamente se ela for um Promise, e remove de dnsList e dnsDict entradas expiradas

Condições para aplicar CNAME e IP

  • cnameFromRecord(hn, record, details) não retorna CNAME se record.canonicalName não existir ou for igual ao nome de host original
  • Se cnameIgnore1stParty estiver ativado, CNAMEs cujo domínio seja igual ao do nome de host original são excluídos
  • Se houver cnameIgnoreList, CNAMEs que não corresponderem à expressão regular são excluídos
  • Se cnameIgnoreRootDocument estiver ativado, a entrada é excluída quando o nome de host da requisição for igual ao nome de host de details.documentUrl || details.url
  • ipFromRecord(record) retorna o primeiro endereço addresses[0] quando record.addresses for um array não vazio

Reescrita de URL e filtragem posterior

  • onAfterDNSResolution reescreve a URL com uncloakURL quando a entrada DNS tiver CNAME e cnameUncloakEnabled estiver ativado
  • Ao alterar a URL, a URL original é salva em details.aliasURL e a nova URL é refletida em details.url
  • Se a entrada DNS tiver IP e ele for diferente do details.ip atual, details.ip é atualizado
  • A chamada à implementação base de onBeforeSuspendableRequest(details) é refeita apenas quando houver reescrita de CNAME ou mudança de IP
  • uncloakURL localiza a posição do nome de host dentro da URL e o substitui pelo CNAME; dependendo do valor de cnameReplayFullURL, concatena a URL inteira ou preserva apenas até o início do caminho

Alterações de configuração e manifest

  • O tratamento de cnameMaxTTL foi removido de setOptions
  • Ao mudar opções, em vez de limpar o Map cnames, o cache DNS é esvaziado com dnsList.fill(null) e dnsDict.clear()
  • cnameMaxTTL: 120 foi removido dos valores padrão ocultos em src/js/background.js
  • Em platform/chromium/manifest.json, minimum_chrome_version muda de 73.0 para 80.0
  • Em platform/opera/manifest.json, minimum_opera_version muda de 60.0 para 67.0

1 comentários

 
GN⁺ 2024-10-08
Comentários no Hacker News
  • Acho que o título está errado. O uBlock Origin já oferecia suporte a esse recurso há vários anos, mas apenas no Firefox
    Este caso parece mais uma refatoração desse código do que um recurso totalmente novo

    • Ainda oferece suporte, e já oferecia antes :P
    • Parece mais do que uma simples refatoração. Agora parece ser possível fazer o bloqueio por IP em uma etapa anterior, antes de a requisição real sair
      Mas não é perfeito, porque, quando um domínio tem vários IPs, não dá para saber qual IP o navegador vai escolher
    • Reverti o título para o título da página. O título enviado era “uBlock Origin supports filtering CNAME cloaking sites on Firefox now”
      Posso mudar de novo se alguém sugerir um título mais preciso e neutro. Mas commits do GitHub sem contexto adicional normalmente não dão threads muito boas no HN
  • Ainda não fui afetado diretamente, mas, se o Chrome realmente acabar com o uBO, já estou retrabalhando minhas extensões para Firefox para conseguir migrar

    • Não é uma questão de “se”, mas de “quando”. Desde 2020 já era “quando”, e agora está realmente chegando
      Deve chegar em alguns releases, então é bom se preparar
    • Estou migrando minha família para o Brave. Eles quase não percebem diferença, e tenho mais confiança de que o navegador continuará dando suporte a filtragem de conteúdo centrada no usuário
    • Já foi removido nas versões Canary
    • Não entendo o que você quer dizer com “reescrever extensões para Firefox”. O Firefox usa a mesma API
      No máximo, é trocar background.service_worker por background.scripts; literalmente só mudar o nome da chave
    • Perguntando para quem não conhece bem: o que é uBO e que impacto isso tem na maioria das extensões?
  • O uBlock Origin é algo que torna o Firefox muito melhor, e um dos grandes motivos para usar Firefox em vez de Chrome e outros
    Ele torna a internet realmente navegável

    • Migrei para essa combinação alguns anos atrás e nunca vi motivo para sair. O mesmo vale no meu celular Android: é a única experiência de web móvel realmente utilizável que já vi
      Em mais de 10 anos, houve problemas de exibição em alguns sites, mas esses sites também tinham problemas no Chrome
      Pessoalmente, vejo a publicidade como um câncer da sociedade moderna. Ela mistura mentiras brancas, mentiras que não são tão brancas e manipulação; e o fato de haver tanto dinheiro envolvido nisso só a torna ainda menos digna de respeito
    • Isso pode mudar, já que a Mozilla está se tornando uma empresa de publicidade
    • Usei tanto Brave quanto Firefox e, sinceramente, não senti grande diferença. Ainda assim, prefiro o Firefox pela filosofia e por vir de uma organização sem fins lucrativos
      O Brave também é um projeto de boa qualidade e uso como backup; às vezes também misturo com o Vivaldi por causa da divisão de janelas e do gerenciamento de abas bem melhor
  • CNAME cloaking significa que sites de anúncios usam subdomínios gerados aleatoriamente que apontam para registros wildcard?

    • Isso é parte da questão
      Normalmente, quando você visita contentsite.com, os anúncios são servidos por adsite.com. Regras de bloqueio de anúncios bloqueiam adsite.com, e os anúncios não aparecem
      CNAME cloaking é quando o site principal faz um subdomínio como adsite.contentsite.com apontar para adsite.com. Aí o bloqueador de anúncios fica com a tarefa quase impossível de bloquear milhões de subdomínios que parecem pertencer ao site legítimo
      O site legítimo pode continuar trocando os subdomínios, e o bloqueador de anúncios não tem como saber quais subdomínios são conteúdo legítimo e quais são anúncios. Além disso, como o conteúdo é servido pelo mesmo domínio, isso também pode contornar algumas políticas de cookies e rastrear melhor o usuário
      Esta atualização permite configurar regras para filtrar com base no IP resolvido
    • Sim. Provedores de anúncios e analytics começaram a usar isso para contornar as proteções contra cookies de terceiros
  • Este é um ótimo exemplo de por que o Manifest V3 é ruim. Por definição, ele não permite fazer esse tipo de coisa, e heurísticas baseadas em código em tempo de execução também não são possíveis
    É uma corrida armamentista contra anunciantes, e o Google é o traficante de armas vendendo para os dois lados. Ele não vai dar aos usuários o que eles precisam para vencer

    • Não há motivo para uma API declarativa do Manifest V3 não oferecer esse recurso. Se li o commit corretamente, ela poderia até funcionar melhor, integrando-se melhor ao fluxo da requisição antes que qualquer coisa seja enviada ao servidor real, bloqueando com base no endereço IP que realmente será usado
      Claro que tudo isso depende de o fornecedor do navegador — ou seja, o Google — querer adicionar essa API. Poder fazer processamento imperativo com “código em execução” permite inovar no espaço do usuário antes que os fabricantes de navegadores adicionem suporte nativo
    • Tecnicamente, o Manifest V3 em si é separado da API que o navegador oferece às extensões. No Firefox, o Manifest V3 é suportado junto com requisições web bloqueantes[1], que é uma API de filtragem anterior ao “Manifest V3”
      Portanto, é incorreto dizer que determinado recurso é impossível “por definição”
      [1] https://blog.mozilla.org/addons/2022/05/18/manifest-v3-in-fi...
    • Basta abandonar o Chrome e adotar o Firefox
  • Cloaking de CNAME: por exemplo, digamos que o fornecedor SaaS A queira oferecer à empresa Q um software sofisticado de rastreamento de anúncios.
    No modelo antigo, A teria dito à empresa Q para inserir no site dela em https://q-company.example um script de, por exemplo, https://A-ads-tracking.example
    Então, nas listas de bloqueio usadas pelo uBlock Origin, surgiria uma regra do tipo “bloqueie requisições para o domínio A-ads-tracking.example”, e o anúncio seria bloqueado.
    O cloaking de CNAME é quando o fornecedor SaaS A coloca o serviço de rastreamento de anúncios não no domínio A-ads-tracking.example, mas em um endereço IP específico, como 29.1.2.3. E a parte importante é que o SaaS A exige que a empresa Q crie um subdomínio de q-company.example e faça o registro CNAME dele apontar para 23.1.2.3. Eles dão um nome plausível, como media.q-company.example.
    Depois que a empresa Q configura esse CNAME e adiciona ao site uma tag de script para media.q-company.example, o SaaS A consegue rastrear todos os usuários desse site. Por causa dessa camada de contorno, cria-se na prática um jogo infinito de gato e rato entre os proprietários da empresa Q e as listas públicas de bloqueio.
    Para evitar esse problema, o software que executa extensões como o uBlock Origin precisa conseguir ver não apenas o domínio de destino da requisição do navegador, mas também o endereço IP real desse domínio. Este commit parece ter relação com viabilizar esse comportamento, ou pelo menos fazer esse código funcionar melhor.

    • Na verdade, é um pouco diferente. Como o nome diz, usa-se CNAME: é um registro que aponta para outro registro, não um registro A que aponta para um IP.
      Por exemplo, media.q-company.example é um CNAME que aponta para q-company.ads-tracking.example, e então q-company.ads-tracking.example tem um registro A que fornece o IP.
      Não sei se o navegador fornece o nome DNS intermediário para a extensão. Por isso, algo como o uBlock talvez precise depender de listas de IPs, mas a filtragem baseada em DNS, como o pihole, consegue simplesmente bloquear com uma regra para ads-tracking.example.
      De qualquer forma, é bom usar tanto bloqueadores maliciosos baseados no navegador quanto baseados em DNS.
    • É por isso que, no modo avançado do uBlock, faz sentido bloquear todo JavaScript e ir colocando lentamente na lista de permissões os scripts visíveis até que o site funcione corretamente.
      É lento e propenso a erros, mas, quando você se acostuma, fica fácil, e você se torna totalmente imune a esse tipo de palhaçada.
  • O Chrome vai bloquear o uBO? Não acompanho sempre a situação mais recente.
    Pelo que sei, cookies de terceiros agora serão permitidos, então talvez ainda haja alguma possibilidade.

    • Não é que ele vá bloquear o uBO em si; ao lançar a nova API de plugins, o Manifest V3, está removendo recursos do navegador que permitiam ao uBO funcionar.
      Estão removendo APIs essenciais necessárias para que o uBO identifique o que não deve ser carregado e, em seguida, impeça esse carregamento.
      O Google afirma que isso é por “desempenho” ou “segurança”. Claro que o único “desempenho” ou “segurança” realmente afetado de forma significativa é a capacidade de identificar, interceptar e interromper downloads nocivos ou relacionados a anúncios antes que comecem.
    • Também é arriscado não atualizar o navegador. É muito melhor migrar para o Firefox, receber atualizações e continuar tendo suporte completo ao uBO.
    • Eles estão fazendo uma remoção gradual e lenta ao longo de um período longo para evitar que a reação negativa contra o monopólio dos navegadores exploda de uma vez. Mas esse cronograma já começou em junho.
      https://developer.chrome.com/docs/extensions/develop/migrate...
      https://www.bleepingcomputer.com/news/google/google-chrome-w...
    • Por enquanto, o uBlock Origin ainda está na Chrome Web Store para navegadores Chromium que oferecem suporte ao Manifest V2.
      Se você usa uma versão do Chromium que só oferece suporte ao Manifest V3, ele fica oculto.
    • Sinceramente, provavelmente depende de os EUA continuarem mantendo uma administração disposta a levar monopólios escancarados aos tribunais.
  • Alguns servidores DNS não têm um recurso que se comporta como um CNAME resolvido pelo servidor? O administrador coloca um registro que aponta para outro nome DNS, mas o cliente vê apenas um registro A ou AAAA.

    • Acho que você está falando de registros ALIAS.
  • O uBO já tinha esse recurso há bastante tempo. Foi desde a versão 1.34.0; nas configurações avançadas, desde a 1.25.0.
    https://github.com/gorhill/uBlock/wiki/Dashboard:-Settings#u...
    Lembro que foi por volta de 2021.

  • Como está o estado do uBO no Brave, Edge e Opera?

    • Não tenho interesse nos dois navegadores proprietários mencionados, mas o Brave pretende oferecer suporte parcial ao Manifest V2 pelo maior tempo possível e manter a compatibilidade com o uBO.
      https://brave.com/blog/brave-shields-manifest-v3/
      Mas isso não é estritamente necessário. O Brave tem um bloqueador de anúncios próprio embutido bastante poderoso e, da última vez que verifiquei, ele era compilado em código nativo, tinha desempenho melhor que o uBO e também oferecia suporte completo às mesmas listas de anúncios.