Em 2018, rastrear um visitante de site parecia um problema de JavaScript: um script dispara um sinalizador no carregamento da página ou em um clique, e se o scripting for bloqueado, desativado ou filtrado, todo o canal se apaga. Crooked Style Sheets, uma prova de conceito do desenvolvedor jbtronics, mostrou que uma página pode ser rastreada sem nenhum JavaScript, usando apenas o próprio motor CSS do navegador.

As abordagens óbvias dependiam todas de scripts ou pixels: um trecho de rastreamento que envia dados para casa, uma tag de imagem, um SDK de análise de terceiros. Cada uma delas é uma classe de requisição visível que bloqueadores de script e filtros de anúncios foram feitos para capturar, e nenhuma delas dispara em uma página onde o scripting nunca é executado.

O truque estava em quando os navegadores buscam recursos url() do CSS: apenas quando um seletor corresponde. O estilo :active de um link com content: url(track.php?action=link2_clicked) faz, portanto, o navegador requisitar essa URL exatamente quando o link é clicado. O mesmo princípio cobria passar o mouse, caixas marcadas, texto correspondente a um padrão via :valid, detecção de navegador via @supports e detecção de fontes instaladas por meio de um fallback @font-face que carrega quando Calibri está ausente. Toda requisição atingia uma página PHP que registrava o carimbo de data/hora e a ação codificada em sua URL.

Como as requisições são carregamentos comuns de recursos acionados por CSS, elas não carregam nenhuma chamada de script que um bloqueador possa identificar, e as folhas de estilo ainda se aplicam quando o JavaScript está desativado. O post no Hacker News de janeiro de 2018 atraiu 532 pontos e 175 comentários, e o repositório havia crescido para cerca de 3,3 mil estrelas e 132 forks até 2026. A defesa que ele provocou incluiu a extensão CSS Exfil Protection, e o autor argumentou que a correção robusta seria os navegadores buscarem conteúdo externo referenciado por CSS no carregamento da página em vez de sob demanda, uma mudança que ele reconheceu que teria custo de desempenho.

Tratar as buscas preguiçosas de recursos CSS do navegador como sinalizadores de eventos: seletores que correspondem apenas no clique, no hover ou em uma fonte ausente disparam uma requisição que o servidor pode registrar

Os navegadores decidem quando buscar o conteúdo url() do CSS, então um seletor correspondente produz uma requisição de rede sem nenhuma chamada de JavaScript que um bloqueador de anúncios possa visar.

As requisições parecem carregamentos comuns de imagem ou fonte, indistinguíveis de ativos legítimos nos logs e na maioria das ferramentas de bloqueio.

Seletores dependentes de estado codificam o significado na própria URL: o caminho do recurso nomeia o evento, e o servidor apenas registra os carimbos de data/hora de chegada.

O CSS ainda se aplica em páginas onde o scripting está desativado, fechando a lacuna que fazia o sem-JavaScript parecer privacidade.

Formatos declarativos ainda realizam trabalho condicional: qualquer carregamento de recurso dependente de estado é um sinal observável, então as defesas devem tratar requisições originadas de CSS como comportamento que vale a pena restringir

O repositório chegou ao Hacker News em 16 de janeiro de 2018 e atraiu 532 pontos e 175 comentários; no rastreamento de 2026, mostrava cerca de 3,3 mil estrelas e 132 forks. A demonstração gerou pelo menos uma defesa, a extensão CSS Exfil Protection vinculada no próprio README, e o texto do autor argumentou que a correção duradoura é os navegadores carregarem conteúdo externo referenciado por CSS quando a página carrega, em vez de quando um seletor corresponde, uma mudança que ele observou que teria custo de desempenho. O site de demonstração original posteriormente saiu do ar, deixando os exemplos de código do repositório como o registro funcional da técnica.

CONFIRA AS EVIDÊNCIAS

As fontes

  1. CrookedStyleSheets - Webpage tracking only using CSS (and no JS) GitHub · github.com
  2. Crooked Style Sheeding - Webpage tracking using only CSS Hacker News · news.ycombinator.com ·