Saltar al contenido principal
it/blog/obscura/research/uncontrollable/gpu-rendering/

obscura/research/uncontrollable/gpu-rendering

5 min di lettura

Categoria: Hardware / Rendering di Basso Livello


1. Descrizione

Il fingerprinting GPU sfrutta il fatto che il rendering grafico non è bit-identico su hardware diversi. Lo stesso codice JavaScript produce output pixel diversi su GPU diverse a causa di:

  • Microarchitettura GPU (conteggio ALU, unità rasterizer, TMU, ROP)
  • Versione del driver e ottimizzazioni del compilatore shader
  • Precisione in virgola mobile nei calcoli degli shader
  • Algoritmi di anti-aliasing e loro implementazione
  • Ordine di rendering subpixel (RGB vs BGR)
  • Matrici di conversione spazio colore
  • Supporto compressione texture
  • Dimensione massima texture e altri limiti hardware

2. Vettori

2.1 Canvas Fingerprinting

const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
ctx.font = '14px Arial'
ctx.fillStyle = '#f60'
ctx.fillRect(125, 1, 62, 20)
ctx.fillStyle = '#069'
ctx.fillText('Test string', 2, 15)
const hash = md5(canvas.toDataURL())

Entropia: ~5-7 bit (32-128 dispositivi distinguibili)

Stabilità: Alta: stabile tra riavvii del browser, moderata tra aggiornamenti del browser

2.2 WebGL Fingerprinting

const gl = canvas.getContext('webgl')
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info')
// Modello GPU esatto:
const renderer = debugInfo.UNMASKED_RENDERER_WEBGL
// "NVIDIA GeForce RTX 3080/PCIe/SSE2"
const vendor = debugInfo.UNMASKED_VENDOR_WEBGL
// "NVIDIA Corporation"

Segnali WebGL aggiuntivi:

  • Hash rendering scena WebGL (renderizza una scena 3D, applica hash ai pixel)
  • Precisione shader (supporto e precisione highp, mediump, lowp)
  • MAX_TEXTURE_SIZE, MAX_VERTEX_ATTRIBS, MAX_VIEWPORT_DIMS (50+ parametri numerici)
  • Elenco estensioni WebGL

Entropia: ~20-25 bit (renderer + estensioni + limiti)

Stabilità: Molto Alta: cambia solo con aggiornamenti del driver GPU

2.3 WebGPU Fingerprinting

const adapter = await navigator.gpu.requestAdapter()
const info = await adapter.requestAdapterInfo()
// { vendor: "nvidia", architecture: "ampere", device: "GA102", driver: "535.129.03", backend: "Vulkan" }
// adapter.limits contiene 50+ capacità numeriche
// adapter.features contiene ~30+ flag di funzionalità

Entropia: ~30+ bit (info adattatore + limiti + funzionalità)

Stabilità: Molto Alta: ancorato all'hardware


3. Punti di Forza dell'Attaccante

Forza Spiegazione
Ancorato all'hardware Il fingerprint GPU non può cambiare senza sostituzione hardware
Cross-browser La stessa GPU produce fingerprint simili su Chrome, Firefox, Edge
Passivo Non richiede interazione utente, funziona in background
Nessuna dipendenza dalla rete Il rendering è locale, nessuna richiesta necessaria
Preciso Il modello GPU esatto è altamente identificativo (GPU rare sono molto uniche)
Coerente Stessa versione driver GPU = stesso output di rendering ogni volta

4. Debolezze dell'Attaccante

Debolezza Spiegazione Sfruttabile?
Bloccabile WebGL/WebGPU possono essere disabilitati nelle impostazioni del browser Sì, ma rilevabile
Iniezione rumore CanvasBlocker aggiunge pixel casuali all'output canvas, rompendo il fingerprint Sì, ma rilevabile
Aggiornamenti driver Nuovi driver cambiano l'output di rendering, invalidando i fingerprint memorizzati Occasionale
Tor Browser Il rendering software normalizza tutto l'output GPU Sì, ma costo prestazionale massiccio
Identifica GPU, non utente Tutti gli utenti con lo stesso modello GPU appaiono identici Solo per GPU comuni

5. Rilevamento della Manipolazione

Gli attaccanti possono rilevare lo spoofing canvas/WebGL tramite:

Tecnica Come Funziona
Confronto lettura sequenziale Leggi canvas 2-3 volte, confronta hash. L'iniezione di rumore produce hash diversi.
Analisi statistica L'output hardware reale ha pattern di rumore caratteristici; il rumore iniettato appare diverso
Correlazione cross-API Hash canvas + renderer WebGL + AudioContext dovrebbero essere tutti coerenti
Presenza funzionalità WEBGL_debug_renderer_info che restituisce null è sospetto
Informazioni adattatore WebGPU mancanti Se WebGL funziona ma WebGPU no, è insolito

6. Mitigazioni per Obscura

6.1 Cosa Può Fare Obscura

Mitigazione Efficacia Rilevabilità Implementazione
Blocca WEBGL_debug_renderer_info Alta (nasconde modello GPU) Media Iniezione JS: restituisci null
Blocca informazioni adattatore WebGPU Alta (nasconde info GPU) Media Iniezione JS: requestAdapter → null
Iniezione rumore Canvas Media Alta Iniezione JS: algoritmo CanvasBlocker
Blocca WebGL completamente Molto Alta Alta Iniezione JS: getContext → null
Blocca WebGPU completamente Molto Alta Alta Iniezione JS: requestAdapter → null
Arrotonda dimensioni canvas Bassa Media Iniezione JS: Math.round()

6.2 Cosa Non Può Fare Obscura

Non Può Perché
Cambiare il rendering GPU effettivo Il rendering avviene sull'hardware GPU locale
Falsificare hash rendering scena WebGL L'output di rendering dipende dall'hardware
Falsificare limiti WebGPU I limiti vengono interrogati dall'adattatore fisico
Normalizzare l'output canvas tra utenti Richiede GPU software (SwiftShader): solo Tor Browser

6.3 Approccio Raccomandato

1. Blocca WEBGL_debug_renderer_info      (nasconde modello GPU: alto valore, basso costo)
2. Blocca WebGPU adapterInfo              (nasconde info GPU di nuova generazione: alto valore, basso costo)
3. Inietta rumore canvas                   (rompe fingerprint canvas: valore medio, costo medio)
4. Se il dispositivo è potente: suggerisci Tor (protezione completa: alto valore, alto costo utente)

7. Riferimenti di Ricerca

  • Mowery, K. & Shacham, H. (2012). "Pixel Perfect: Fingerprinting Canvas in HTML5." WOOT 2012.
  • Acar, G. et al. (2014). "The Web Never Forgets: Persistent Tracking Mechanisms in the Wild." CCS 2014.
  • Cao, Y. et al. (2017). "WebRTC and Canvas-based Device Fingerprinting." PET Symposium 2017.
  • FingerprintJS (2026). "Canvas Fingerprinting: What It Is and How It Works." fingerprintjs.com/blog.