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

obscura/research/uncontrollable/gpu-rendering

4 Min. Lesezeit

Kategorie: Hardware / Low-Level-Rendering


1. Beschreibung

GPU-Fingerprinting nutzt die Tatsache aus, dass Grafik-Rendering nicht bitidentisch über verschiedene Hardware hinweg ist. Derselbe JavaScript-Code erzeugt auf verschiedenen GPUs unterschiedliche Pixelausgaben aufgrund von:

  • GPU-Mikroarchitektur (ALU-Anzahl, Rasterizer-Einheiten, TMUs, ROPs)
  • Treiberversion und Shader-Compiler-Optimierungen
  • Gleitkomma-Präzision in Shader-Berechnungen
  • Anti-Aliasing-Algorithmen und deren Implementierung
  • Subpixel-Rendering-Reihenfolge (RGB vs. BGR)
  • Farbraumkonvertierungsmatrizen
  • Texturkomprimierungsunterstützung
  • Maximale Texturgröße und andere Hardware-Limits

2. Vektoren

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())

Entropie: ~5-7 Bits (32-128 Geräte unterscheidbar)

Stabilität: Hoch – stabil über Browser-Neustarts, moderat über Browser-Updates

2.2 WebGL-Fingerprinting

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

Zusätzliche WebGL-Signale:

  • WebGL-Szenen-Render-Hash (eine 3D-Szene rendern, Pixel hashen)
  • Shader-Präzision (highp, mediump, lowp-Unterstützung und Präzision)
  • MAX_TEXTURE_SIZE, MAX_VERTEX_ATTRIBS, MAX_VIEWPORT_DIMS (50+ numerische Parameter)
  • WebGL-Erweiterungsliste

Entropie: ~20-25 Bits (Renderer + Erweiterungen + Limits)

Stabilität: Sehr hoch – ändert sich nur mit GPU-Treiberupdates

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 enthält 50+ numerische Fähigkeiten
// adapter.features enthält ~30+ Feature-Flags

Entropie: ~30+ Bits (Adapterinfo + Limits + Features)

Stabilität: Sehr hoch – hardware-gebunden


3. Stärken des Angreifers

Stärke Erklärung
Hardware-gebunden GPU-Fingerprint kann sich nicht ohne Hardware-Austausch ändern
Browserübergreifend Gleiche GPU erzeugt ähnliche Fingerprints über Chrome, Firefox, Edge
Passiv Erfordert keine Benutzerinteraktion, läuft im Hintergrund
Keine Netzwerkabhängigkeit Rendering ist lokal, keine Anfrage nötig
Präzise Genaues GPU-Modell ist hochgradig identifizierend (seltene GPUs sind sehr einzigartig)
Konsistent Gleiche GPU-Treiberversion – gleiche Renderausgabe jedes Mal

4. Schwächen des Angreifers

Schwäche Erklärung Ausnutzbar?
Blockierbar WebGL/WebGPU können in den Browser-Einstellungen deaktiviert werden Ja – aber erkennbar
Rausch-Injektion CanvasBlocker fügt zufällige Pixel zur Canvas-Ausgabe hinzu, bricht Fingerprint Ja – aber erkennbar
Treiberupdates Neue Treiber ändern die Renderausgabe, ungültige gespeicherte Fingerprints Gelegentlich
Tor Browser Software-Rendering normalisiert alle GPU-Ausgaben Ja – aber massive Leistungseinbuße
Identifiziert GPU, nicht Benutzer Alle Benutzer mit demselben GPU-Modell sehen identisch aus Nur bei häufigen GPUs

5. Erkennung von Manipulation

Angreifer können Canvas-/WebGL-Spoofing erkennen über:

Technik Funktionsweise
Sequenzieller Lesevergleich Canvas 2-3 Mal lesen, Hashes vergleichen. Rausch-Injektion erzeugt unterschiedliche Hashes.
Statistische Analyse Echte Hardware-Ausgabe hat charakteristische Rauschmuster; injiziertes Rauschen sieht anders aus
API-übergreifende Korrelation Canvas-Hash + WebGL-Renderer + AudioContext sollten alle konsistent sein
Feature-Präsenz WEBGL_debug_renderer_info gibt null zurück – verdächtig
WebGPU-Adapterinfo fehlt Wenn WebGL funktioniert, aber WebGPU nicht – ungewöhnlich

6. Abschwächungen für Obscura

6.1 Was Obscura tun kann

Abschwächung Effektivität Erkennbarkeit Implementierung
WEBGL_debug_renderer_info blockieren Hoch (versteckt GPU-Modell) Mittel JS-Injection: null zurückgeben
WebGPU-Adapterinfo blockieren Hoch (versteckt GPU-Info) Mittel JS-Injection: requestAdapter → null
Canvas-Rausch-Injektion Mittel Hoch JS-Injection: CanvasBlocker-Algorithmus
WebGL vollständig blockieren Sehr hoch Hoch JS-Injection: getContext → null
WebGPU vollständig blockieren Sehr hoch Hoch JS-Injection: requestAdapter → null
Canvas-Abmessungen runden Niedrig Mittel JS-Injection: Math.round()

6.2 Was Obscura nicht tun kann

Kann nicht Warum
Tatsächliches GPU-Rendering ändern Rendering findet auf lokaler GPU-Hardware statt
WebGL-Szenen-Render-Hash spoofen Renderausgabe ist hardwareabhängig
WebGPU-Limits spoofen Limits werden vom physischen Adapter abgefragt
Canvas-Ausgabe über Benutzer hinweg normalisieren Erfordert Software-GPU (SwiftShader) – nur Tor Browser

6.3 Empfohlener Ansatz

1. WEBGL_debug_renderer_info blockieren      (versteckt GPU-Modell – hoher Wert, niedrige Kosten)
2. WebGPU adapterInfo blockieren              (versteckt GPU-Info der nächsten Generation – hoher Wert, niedrige Kosten)
3. Canvas-Rauschen injizieren                 (bricht Canvas-Fingerprint – mittlerer Wert, mittlere Kosten)
4. Wenn Gerät leistungsstark ist: Tor empfehlen (vollständiger Schutz – hoher Wert, hohe Benutzerkosten)

7. Forschungsreferenzen

  • 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.