Beyond Cookies: The Silent Tracker
Most people think deleting cookies protects their privacy. It doesn't. Modern websites have evolved far beyond cookie-based tracking. Browser fingerprinting is a collection of techniques that identify you by the unique characteristics of your browser, hardware, and configuration — without storing anything on your device.
The Electronic Frontier Foundation's Cover Your Tracks project found that 83.6% of browsers have a unique fingerprint. That means a website can identify you across sessions, across incognito windows, and even across different websites, all without a single cookie.
This article breaks down every major fingerprinting vector, shows you how they work with code examples, and explains what you can do to defend yourself.
Canvas Fingerprinting
The <canvas> API lets JavaScript draw graphics. The problem: the exact same drawing code produces pixel-level different results across different GPU hardware, driver versions, operating systems, and font rendering engines.
Here's how a fingerprinting script works:
// 1. Create an offscreen canvas
const canvas = document.createElement('canvas');
canvas.width = 280;
canvas.height = 60;
const ctx = canvas.getContext('2d');
// 2. Draw specific text with a fallback font chain
ctx.textBaseline = 'top';
ctx.font = '14px Arial, sans-serif';
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
ctx.fillText('BrowserFingerprint', 2, 15);
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
ctx.fillText('BrowserFingerprint', 4, 17);
// 3. Extract the pixel data
const dataURL = canvas.toDataURL('image/png');
// This dataURL is your fingerprint — unique per device
Why it works: font sub-pixel rendering, anti-aliasing algorithms, and GPU rasterization differences mean no two systems produce identical pixel output. Even the same browser version on the same OS can differ based on installed fonts and graphics drivers.
Canvas fingerprinting is the most widely deployed technique. It's used by major ad networks and analytics platforms.
WebGL Fingerprinting
WebGL exposes your GPU directly. A fingerprinting script can query:
const gl = canvas.getContext('webgl');
// GPU vendor and renderer string
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
const vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
// e.g., "Google Inc. (NVIDIA)" / "ANGLE (NVIDIA GeForce RTX 3080)"
// Supported extensions — the list varies per GPU/driver
const extensions = gl.getSupportedExtensions();
// Maximum texture size, viewport dimensions, etc.
const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
const maxViewport = gl.getParameter(gl.MAX_VIEWPORT_DIMS);
The combination of GPU vendor, renderer string, extension list, and parameter values creates an extremely high-entropy fingerprint. Unlike canvas, WebGL fingerprinting is harder to spoof without breaking actual 3D rendering.
AudioContext Fingerprinting
The Web Audio API creates another fingerprinting surface. The same audio processing pipeline produces different floating-point output across different audio hardware and DSP implementations:
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioContext.createOscillator();
const analyser = audioContext.createAnalyser();
const gain = audioContext.createGain();
const scriptProcessor = audioContext.createScriptProcessor(4096, 1, 1);
// Generate a specific waveform
oscillator.type = 'triangle';
oscillator.frequency.setValueAtTime(10000, audioContext.currentTime);
// Process and capture the output
const dataArray = new Float32Array(analyser.frequencyBinCount);
// The exact float values in dataArray differ per hardware
AudioContext fingerprinting is particularly insidious because it works even when the user has muted their system audio. The DSP processing still runs; only the output is silenced.
Font Enumeration Fingerprinting
The fonts installed on your system are surprisingly identifying. A typical user has 200-400 fonts, and the exact combination is highly unique:
// Method 1: Measure text width with fallback detection
const baseFonts = ['monospace', 'sans-serif', 'serif'];
const testFonts = [
'Arial', 'Helvetica', 'Times New Roman', 'Courier New',
'Verdana', 'Georgia', 'Palatino', 'Garamond',
'Comic Sans MS', 'Impact', 'Lucida Console',
'Microsoft YaHei', 'PingFang SC', 'Noto Sans CJK'
];
function hasFont(font) {
const span = document.createElement('span');
span.style.fontFamily = `'${font}', monospace`;
span.textContent = 'mmmmmmmmmmlli';
document.body.appendChild(span);
const width = span.offsetWidth;
document.body.removeChild(span);
// Compare against baseline width
return width !== baselineWidth;
}
Each detected font adds entropy. A user with both PingFang SC and Microsoft YaHei installed is almost certainly on a Chinese-language system. A user with Segoe UI but not San Francisco is on Windows. Font fingerprinting can identify your OS, language, and even professional software (designers have more fonts than average).
Navigator & Screen Properties
The navigator object leaks dozens of data points:
// Browser and OS identification
navigator.userAgent // "Mozilla/5.0 (Windows NT 10.0; Win64; x64)..."
navigator.platform // "Win32"
navigator.language // "en-US"
navigator.languages // ["en-US", "en", "zh-CN"]
// Hardware capabilities
navigator.hardwareConcurrency // Number of CPU cores (e.g., 8)
navigator.deviceMemory // RAM in GB (e.g., 8)
navigator.maxTouchPoints // 0 for desktop, 5+ for mobile
// Screen properties
screen.width × screen.height // e.g., 2560×1440
screen.colorDepth // 24 or 30
screen.pixelDepth // Usually matches colorDepth
window.devicePixelRatio // 1.0, 1.25, 1.5, 2.0
// Timezone
Intl.DateTimeFormat().resolvedOptions().timeZone // "Asia/Shanghai"
The combination of hardwareConcurrency + deviceMemory + screen resolution + timezone + languages narrows you down to a very small group. Add the user agent string and you're often unique.
Advanced Fingerprinting Vectors
WebRTC Local IP Leak
Even behind a VPN, WebRTC can expose your local network IP address through STUN requests. This was a major privacy scandal when it was discovered in 2015, and it's still not fully fixed in all browsers.
Battery Status API
On some browsers, navigator.getBattery() exposes your exact battery level and charging status. A battery draining from 73% to 71% over 30 seconds is a unique temporal signal.
Speech Synthesis Voices
speechSynthesis.getVoices() returns the list of installed TTS voices. The exact list varies by OS, language packs, and installed software.
Media Devices
navigator.mediaDevices.enumerateDevices() lists your cameras, microphones, and speakers — including device names like "HD Pro Webcam C920" or "AirPods Pro".
Performance Timing
The performance.now() API has microsecond precision. By measuring how long specific operations take (DOM manipulation, Canvas rendering, memory allocation), scripts can fingerprint your hardware's performance characteristics.
Cross-Browser & Cross-Device Tracking
The most sophisticated fingerprinting goes beyond a single browser. By combining:
- IP address (from server-side logging)
- Browser fingerprint (from client-side scripts)
- Behavioral signals (typing speed, mouse movement patterns, scroll behavior)
Tracking companies can identify the same person across Chrome, Firefox, and Safari — and even across their phone and laptop. This is called cross-device tracking, and it's a multi-billion dollar industry.
How to Defend Yourself
Level 1: Basic Protection
- Use Firefox with strict tracking protection — Firefox has built-in fingerprinting resistance
- Install uBlock Origin — blocks many fingerprinting scripts at the network level
- Use a VPN — hides your real IP address (but doesn't stop client-side fingerprinting)
Level 2: Browser Extensions
This is where browser extensions shine. Tools like StylePatch can help by customizing how pages render on your machine, which can subtly alter your canvas fingerprint. More importantly, extensions that block unnecessary scripts and manage HTTP headers — like VKT WebHeader — give you granular control over what information your browser sends to each site.
The key principle: every piece of information you withhold reduces your fingerprint's entropy. You don't need to be invisible — you just need to look like everyone else.
Level 3: Tor Browser
The Tor Browser is the gold standard for anti-fingerprinting. It forces all users to have the same screen resolution, the same fonts, the same canvas output. The trade-off: it's slow, and many websites block Tor exit nodes.
Level 4: Compartmentalization
The most practical approach for most people: use different browsers for different purposes. Work browser for work. Personal browser for personal. A separate browser or profile for anything you want to keep anonymous. This way, even if each browser has a unique fingerprint, the tracking is confined to one compartment.
Building Privacy-First Extensions
As a developer who builds privacy-first browser extensions, I think about fingerprinting every day. My design philosophy is simple: the extension should never increase your fingerprint surface. That means:
- No external requests — all processing happens locally
- No unique identifiers — no analytics, no telemetry, no phone-home
- Minimal permissions — only request what's absolutely necessary
- Standard APIs — don't use exotic browser APIs that make you more identifiable
If you're building extensions, ask yourself: "Does this extension make my user more or less trackable?" The answer should always be "less".
The Arms Race Continues
Browser fingerprinting is an arms race. As browsers add privacy protections, trackers develop new techniques. The canvas fingerprint was novel in 2014; now there are 30+ vectors. WebGL fingerprinting was theoretical in 2016; now it's standard practice.
The good news: awareness is growing. Firefox, Brave, and Safari all ship fingerprinting protections. Chrome is slowly adding them. Regulations like GDPR and CCPA are forcing companies to be more transparent about tracking.
The best defense is still knowledge. Now that you know how fingerprinting works, you can make informed decisions about your browser configuration, your extensions, and your online behavior.
Stay private out there. 🔒