O que é WebGL Pixel Hash? Como Sua GPU Produz uma Impressão Digital Única
Navegador & Dispositivo

O que é WebGL Pixel Hash? Como Sua GPU Produz uma Impressão Digital Única

O WebGL pixel hash fingerprinting executa um shader GLSL e lê os pixels de saída com gl.readPixels() — explorando diferenças de aritmética de ponto flutuante da GPU para criar um identificador único.

8 min de leitura·

O WebGL pixel hash fingerprinting (impressão digital por hash de pixels WebGL) renderiza uma cena de teste invisível usando um shader GLSL e lê os pixels resultantes com gl.readPixels() — explorando o fato de que cada GPU computa aritmética de ponto flutuante de forma ligeiramente diferente, produzindo um hash estável que identifica seu hardware em todos os navegadores, sobrevive à limpeza de cookies e não pode ser ocultado por uma VPN. Você pode ver seu próprio pixel hash WebGL agora mesmo no whatsmy.fyi.

Resumo

Um programa de shader GLSL é compilado e executado na sua GPU dentro de um canvas WebGL oculto. Os valores de pixel renderizados são lidos de volta e hasheados em um identificador compacto. Como o arredondamento de ponto flutuante nas unidades de shader de GPU varia entre fabricantes, arquiteturas e versões de driver, o mesmo shader produz saídas de pixel sutilmente diferentes em hardware diferente — mesmo em duas máquinas com o mesmo modelo de GPU mas diferentes instalações de driver. Isso torna o pixel hash um identificador mais refinado do que simplesmente ler a string de renderer da GPU.

O que é WebGL Pixel Hash Fingerprinting?

O WebGL pixel hash fingerprinting é uma técnica específica dentro da família mais ampla de WebGL fingerprinting que tem como alvo a saída computacional da sua GPU em vez de seus metadados. Enquanto ler a string do renderer de GPU via WEBGL_debug_renderer_info informa o modelo da GPU a um rastreador, não pode distinguir duas GPUs idênticas rodando versões de driver diferentes. O pixel hash fecha essa lacuna.

A técnica funciona porque a API WebGL dá ao JavaScript acesso direto à execução de shader de GPU. Um script de fingerprinting pode escrever um fragment shader GLSL que realiza operações matemáticas — funções trigonométricas, partes fracionárias, ruído pseudoaleatório — e fazer a GPU executá-lo. Os valores de cor resultantes escritos em cada pixel dependem de como as unidades de ponto flutuante da GPU tratam essas operações internamente.

Isso está intimamente relacionado ao canvas fingerprinting, que também lê saída de pixel — mas o canvas fingerprinting tem como alvo a renderização de fontes 2D e diferenças de anti-aliasing. O hashing de pixel WebGL tem como alvo diretamente a aritmética de shader 3D da GPU, tornando-o de maior entropia e mais difícil de normalizar.

Como Funciona o WebGL Pixel Hash Fingerprinting?

Todo o processo roda em JavaScript, leva menos de 50 milissegundos e é completamente invisível para o usuário.

Estágio 1 — Criando um Canvas WebGL Oculto

O script cria um elemento canvas fora da tela — nunca anexado ao documento — e obtém um contexto de renderização WebGL. O tamanho do canvas é tipicamente pequeno (256×128 ou 512×256 pixels) para manter a execução rápida.

Estágio 2 — Compilando um Shader Projetado para Maximizar a Variação

Um fragment shader GLSL é escrito para realizar operações sensíveis a diferenças de precisão de ponto flutuante. Os shaders mais eficazes combinam sin(), cos(), fract() e multiplicações de coeficientes grandes — porque essas operações acumulam erros de arredondamento entre arquiteturas de GPU de formas diferentes.

// GLSL fragment shader used for pixel hash fingerprinting
precision highp float;

void main() {
  float x = gl_FragCoord.x / 256.0;
  float y = gl_FragCoord.y / 128.0;

  // These sin/fract combinations amplify GPU floating-point differences
  float r = fract(sin(x * 12.9898 + y * 78.233) * 43758.5453);
  float g = fract(sin(x * 93.989 + y * 17.211) * 43421.631);
  float b = fract(cos(x * 51.234 + y * 31.456) * 12345.678);

  gl_FragColor = vec4(r, g, b, 1.0);
}

Estágio 3 — Lendo Pixels com gl.readPixels()

Após o shader ser executado, o script chama gl.readPixels() para transferir os dados de pixel renderizados da memória da GPU de volta para um Uint8Array JavaScript.

// JavaScript: compile shader, render, and extract pixels
const canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 128;
const gl = canvas.getContext('webgl');

// Compile and link vertex + fragment shaders (abbreviated)
const program = compileAndLinkShaders(gl, vertexSrc, fragmentSrc);
gl.useProgram(program);

// Draw a full-screen triangle strip
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(
  gl.ARRAY_BUFFER,
  new Float32Array([-1, -1,  1, -1,  -1, 1,  1, 1]),
  gl.STATIC_DRAW
);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

// Read pixel data from GPU memory
const pixels = new Uint8Array(256 * 128 * 4); // width × height × RGBA
gl.readPixels(0, 0, 256, 128, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

// Hash the pixel buffer → stable GPU fingerprint
const hash = fnv1a(pixels); // or MurmurHash, xxHash, etc.

Estágio 4 — Hasheando o Buffer de Pixels

O array completo de pixels é hasheado em um valor compacto. O resultado é uma string hexadecimal curta que representa o comportamento exato de ponto flutuante das unidades de shader da sua GPU. Esse hash é estável entre reinicializações do navegador, sessões incógnitas e reboots. Muda apenas quando o driver da GPU é atualizado ou o hardware físico é substituído.

Como Isso é Diferente de Ler a String do Renderer de GPU?

PropriedadeString do Renderer de GPUHash de Pixel WebGL
O que lêNome do modelo + string do fornecedor da GPUSaída da computação do shader
API usadaWEBGL_debug_renderer_infogl.readPixels()
Distingue mesma GPU, drivers diferentes?Não — mesma GPU sempre dá mesma stringSim — diferenças de driver mudam a saída de pixel
Requer extensão WebGL?Sim — WEBGL_debug_renderer_infoNão — usa WebGL principal

Quão Único é o Hash de Pixel WebGL?

DescobertaValorFonte
Entropia da saída de renderização WebGL sozinha~5,7 bitsPesquisa Fingerprint.com
Estabilidade do pixel hash entre reinicializações do navegadorQuase 100% (muda apenas com atualização de driver)Cao et al., NDSS 2017
Consistência entre navegadores no mesmo hardwareAlta — aritmética de hardware é independente de navegadorCao et al., NDSS 2017
Identificabilidade quando combinado com renderer + vendor da GPU< 0,01% dos visitantes compartilham o mesmo trioPesquisa de campo Inria / KU Leuven
Suporte WebGL do navegador (Chrome, Edge, Safari, Firefox)95–99%BrowserLeaks WebGL Test

Por que o Pixel Hash Persiste Entre Navegadores

Quando você usa Chrome, Firefox e Edge na mesma máquina, cada navegador mantém jars de cookies e armazenamento local completamente separados. Mas os três navegadores compartilham a mesma GPU e driver subjacentes. O shader GLSL é compilado independentemente em cada navegador, mas executado no mesmo hardware — produzindo saída de pixel idêntica (ou quase idêntica) em todos eles. A pesquisa publicada no NDSS 2017 por Cao et al. demonstrou essa capacidade de fingerprinting entre navegadores.

Como se Proteger do WebGL Pixel Hash Fingerprinting

  • Tor Browser (proteção mais forte): O Tor Browser desabilita gl.readPixels() completamente em sua configuração padrão, tornando impossível para os scripts ler os dados de pixel renderizados.
  • Brave Browser (recomendado para uso diário): O Farbling do Brave injeta um pequeno valor de ruído randomizado por sessão na saída de pixel WebGL. O ruído é consistente dentro de uma sessão (para que aplicações WebGL funcionem corretamente), mas muda entre sessões e entre diferentes sites.
  • Firefox com privacy.resistFingerprinting: Ativar esta flag no about:config normaliza a saída WebGL no Firefox, tornando o hash de renderização menos distinto.
  • O que uma VPN não pode fazer: Uma VPN criptografa seu tráfego de rede e muda seu endereço IP visível, mas não tem efeito na execução do shader de GPU. O pixel hash é computado dentro do seu navegador. Verifique a proteção de IP da sua VPN no whatsmy.fyi, mas entenda que ela não aborda nenhum tipo de fingerprinting.

Perguntas Frequentes

Qual é a diferença entre um pixel hash WebGL e uma string de renderer WebGL?

A string do renderer é um rótulo de texto — por exemplo, "NVIDIA GeForce RTX 4080/PCIe/SSE2" — retornado pela extensão WEBGL_debug_renderer_info. Identifica seu modelo de GPU, mas é o mesmo para todas as máquinas com exatamente essa GPU. O pixel hash é uma impressão digital numérica da computação real da sua GPU — produzida executando um shader de teste e lendo os pixels de saída. Captura diferenças no nível de driver e silício que o tornam único mesmo entre máquinas com modelos de GPU idênticos.

O pixel hash funciona no modo incógnito?

Sim. O modo incógnito impede que seu navegador salve cookies, histórico e downloads no disco — mas não muda seu hardware ou driver de GPU. O pixel hash é gerado inteiramente da computação de GPU e é idêntico em janelas normais e privadas.

Duas GPUs diferentes podem produzir o mesmo pixel hash?

Sim, mas é estatisticamente incomum. GPUs de fabricantes diferentes (NVIDIA vs. AMD vs. Intel vs. Apple) quase nunca produzem o mesmo hash porque suas arquiteturas de shader tratam operações de ponto flutuante de forma fundamentalmente diferente.

Artigos Relacionados

Verifique seu endereço IP, localização e pontuação de privacidade — instantaneamente.

Zero logs. Zero rastreamento. Zero APIs externas.

Executar a verificação agora →

Artigos relacionados

O que é WebGL Pixel Hash? Como Sua GPU Produz uma Impressão Digital Única | whatsmy.fyi