Canvas, WebGL ve Ses Parmak İzi Açıklandı
These three vectors are the most reliable hardware-based fingerprinting methods in production today. They exploit the fact that every device renders graphics and processes audio slightly differently — differences determined by GPU, driver version, operating system, and audio stack.
Unlike cookies or IP addresses, these fingerprints can't be cleared by the user. They persist across sessions, across browsers (partially), and across IP changes. Understanding how they work at the technical level is essential for anyone building or defending against fingerprinting systems.
Canvas Fingerprinting Deep Dive
Canvas fingerprinting was first documented by Mowery and Shacham in 2012. The technique exploits rendering differences in the HTML5 Canvas API to generate a device-specific hash.
How It Works
The detection script creates a hidden canvas element, draws a specific combination of text, shapes, and gradients, then extracts the pixel data and hashes it.
function getCanvasFingerprint() {
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 50;
const ctx = canvas.getContext('2d');
ctx.textBaseline = 'top';
ctx.font = '14px Arial';
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
ctx.fillText('Cwm fjordbank glyph vext quiz', 2, 15);
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
ctx.fillText('Cwm fjordbank glyph vext quiz', 4, 17);
return canvas.toDataURL();
}
The text "Cwm fjordbank glyph vext quiz" is chosen because it contains every letter of the English alphabet, maximizing the rendering surface area for detecting differences.
Why Devices Render Differently
The rendering pipeline is: browser → OS graphics layer → GPU driver → GPU hardware → framebuffer. At each stage, implementation choices create variation:
- Font rasterization varies between operating systems. Windows uses DirectWrite, macOS uses Core Text, Linux uses FreeType. Each renders the same font at the same size with subtly different sub-pixel positioning and anti-aliasing.
- GPU hardware processes floating-point calculations with different precision. An Intel UHD 630 and an NVIDIA RTX 3060 produce different results for the same gradient calculation.
- Driver versions affect rendering behavior. The same GPU with driver version 531.41 vs 531.68 can produce different canvas output due to rendering pipeline optimizations.
- Sub-pixel rendering settings (ClearType on Windows, font smoothing on macOS) alter how text edges are rendered at the pixel level.
These differences are tiny — often just a few pixels — but deterministic. The same device produces the same canvas output every time. Different devices produce different output.
Detection Rate
Canvas fingerprinting alone identifies approximately 70-80% of unique devices in a population of 100,000. Combined with other vectors, it contributes significantly to near-100% identification.
WebGL Fingerprinting
WebGL fingerprinting takes hardware identification further by directly querying the GPU and its capabilities.
Parameter Extraction
WebGL exposes detailed information about the graphics hardware through standardized API calls:
function getWebGLFingerprint() {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
return {
vendor: gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL),
renderer: gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL),
maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE),
maxViewportDims: gl.getParameter(gl.MAX_VIEWPORT_DIMS),
maxRenderbufferSize: gl.getParameter(gl.MAX_RENDERBUFFER_SIZE),
shadingLanguageVersion: gl.getParameter(gl.SHADING_LANGUAGE_VERSION),
extensions: gl.getSupportedExtensions(),
maxAnisotropy: getMaxAnisotropy(gl),
aliasedLineWidthRange: gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE),
aliasedPointSizeRange: gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE),
vertexShaderHighFloat: getShaderPrecision(gl, gl.VERTEX_SHADER, gl.HIGH_FLOAT),
fragmentShaderHighFloat: getShaderPrecision(gl, gl.FRAGMENT_SHADER, gl.HIGH_FLOAT)
};
}
The UNMASKED_VENDOR_WEBGL and UNMASKED_RENDERER_WEBGL parameters are the most identifying. They return strings like "Intel Inc." / "Intel(R) UHD Graphics 630" or "NVIDIA Corporation" / "NVIDIA GeForce RTX 3060/PCIe/SSE2".
Shader Precision Fingerprinting
Beyond the basic parameters, WebGL exposes shader precision formats that vary across GPU architectures:
| Precision | Intel UHD 630 | NVIDIA RTX 3060 | Apple M1 |
|---|---|---|---|
| Vertex HIGH_FLOAT | {23, 127, 127} | {23, 127, 127} | {23, 127, 127} |
| Fragment HIGH_FLOAT | {23, 127, 127} | {23, 127, 127} | {23, 127, 127} |
| Vertex MEDIUM_FLOAT | {23, 127, 127} | {23, 127, 127} | {15, 15, 15} |
| Fragment MEDIUM_FLOAT | {10, 15, 15} | {23, 127, 127} | {15, 15, 15} |
The MEDIUM_FLOAT precision in fragment shaders differs between Intel, NVIDIA, and Apple GPUs. This single parameter narrows device identification significantly.
WebGL Rendering Fingerprints
Like canvas, WebGL rendering can produce hardware-specific output. Drawing a 3D scene with specific shaders, then reading the pixel buffer back produces a hash that varies by GPU, driver, and OS — the same principle as canvas fingerprinting but in the WebGL rendering pipeline.
Audio Fingerprinting
AudioContext fingerprinting is the subtlest of the three vectors. It was documented by Englehardt and Narayanan in 2016 and exploits differences in how devices process audio signals.
The Technique
The script creates an AudioContext, generates an audio signal through an oscillator, processes it through a dynamics compressor, and reads back the resulting waveform:
function getAudioFingerprint() {
const context = new (window.OfflineAudioContext ||
window.webkitOfflineAudioContext)(1, 44100, 44100);
const oscillator = context.createOscillator();
oscillator.type = 'triangle';
oscillator.frequency.setValueAtTime(10000, context.currentTime);
const compressor = context.createDynamicsCompressor();
compressor.threshold.setValueAtTime(-50, context.currentTime);
compressor.knee.setValueAtTime(40, context.currentTime);
compressor.ratio.setValueAtTime(12, context.currentTime);
compressor.attack.setValueAtTime(0, context.currentTime);
compressor.release.setValueAtTime(0.25, context.currentTime);
oscillator.connect(compressor);
compressor.connect(context.destination);
oscillator.start(0);
return context.startRendering().then(buffer => {
const data = buffer.getChannelData(0);
return hashFloat32Array(data.slice(4500, 5000));
});
}
Why Audio Processing Differs
The audio rendering pipeline — oscillator → compressor → output buffer — involves floating-point math that varies by:
- Audio stack implementation. Windows (WASAPI/DirectSound), macOS (Core Audio), Linux (ALSA/PulseAudio) use different DSP implementations.
- CPU floating-point handling. Different CPUs handle the same floating-point operations with slightly different rounding, producing different output values in the least significant digits.
- Sample rate conversion. Resampling between the oscillator's output and the context's sample rate introduces hardware-specific artifacts.
The differences are in the 8th-15th decimal places of the audio samples — completely inaudible but consistent and measurable. A 500-sample slice produces a unique hash that identifies the device.
Why Audio Fingerprinting Matters for Operators
Audio fingerprinting is harder to spoof than canvas or WebGL because:
- It doesn't involve visual rendering, so "add noise" approaches from canvas spoofing don't transfer directly.
- The signal processing pipeline is deeper in the OS than the graphics pipeline, making interception harder.
- Most anti-detect browsers focus on visual fingerprints and handle audio poorly or not at all.
Defense Strategies
Defending against these fingerprinting vectors requires different approaches depending on whether you're building privacy-respecting applications or operating stealth infrastructure.
For Application Builders
Block the APIs entirely. Brave browser and Firefox (with privacy settings) can block canvas readback, WebGL parameter queries, and AudioContext creation. This prevents fingerprinting but breaks websites that legitimately use these APIs.
Standardize output. Tor Browser's approach: make every browser produce identical canvas, WebGL, and audio output. This defeats fingerprinting but requires all users to use the same browser with the same settings.
For Operators Using Anti-Detect Browsers
Consistent spoofing over random noise. The fingerprint must be:
- Internally consistent (canvas GPU matches WebGL renderer matches audio characteristics)
- Deterministic (same output every render within a session)
- Realistic (values that match actual hardware combinations that exist in the real world)
Hardware-plausible values. If your WebGL renderer claims "NVIDIA GeForce RTX 4090," the canvas rendering speed, shader precision, and texture limits must all be consistent with that GPU. Detection systems maintain databases of real hardware parameters and flag impossible combinations.
Cross-vector consistency. The canvas fingerprint, WebGL fingerprint, and audio fingerprint must all be plausible for the same hardware. An Intel UHD canvas hash combined with an NVIDIA WebGL renderer and Apple Silicon audio characteristics is an immediate detection signal. See why setups get detected.
Test, then test again. Verify your spoofed fingerprints against CreepJS (checks for fingerprint lies), BrowserLeaks (individual vector analysis), and real platform behavior (the only test that ultimately matters).
FAQ
Do fingerprints change when I upgrade hardware or drivers? Yes. A GPU driver update, OS update, or hardware change will alter canvas and WebGL fingerprints. Audio fingerprints change with OS updates and audio driver changes. This is why platforms don't rely on fingerprint stability alone — they use fingerprints as one signal in a multi-factor identification system.
Can virtual machines be detected through rendering fingerprints? Yes. Virtual GPU drivers (VMware SVGA, VirtualBox Graphics Adapter) produce distinct WebGL renderer strings and canvas rendering artifacts that differ from physical hardware. Detection systems maintain lists of known virtual GPU identifiers. GPU passthrough (IOMMU) can mitigate this by exposing real hardware to the VM.
Are these fingerprinting methods used on mobile? Canvas and WebGL fingerprinting work on mobile browsers. Audio fingerprinting works but with less variation because mobile audio stacks are more standardized (especially on iOS). Mobile adds additional vectors — accelerometer data, touch pressure, battery status — that don't exist on desktop. See mobile fingerprinting.
How unique are these fingerprints really? In isolation: canvas identifies ~70-80% of devices, WebGL ~60-70%, audio ~50-60%. Combined with each other and with other signals (screen resolution, timezone, language, installed fonts), the combination uniquely identifies 95%+ of devices in populations up to several million. The remaining 5% are typically users of privacy browsers that standardize these values.