What Is Browser Fingerprinting? A Developer's Guide
Browser fingerprinting is the process of collecting information about a browser's configuration and environment to create a unique identifier, a "fingerprint", that can distinguish one browser from another without cookies or login sessions.
If you build web scrapers, automated tests, or bot detection systems, understanding fingerprinting is essential. It's the core technique behind both detecting bots and evading detection.
How fingerprinting works
Browser fingerprinting was first studied in depth by the EFF's Panopticlick project (now Cover Your Tracks), which demonstrated that the combination of browser properties is almost always unique.
Every browser exposes hundreds of data points through standard Web APIs. Individually, these signals aren't unique. Combined, they form a fingerprint that's statistically unique across millions of browsers.
Here's what gets collected:
Navigator properties
The navigator object is the richest source of fingerprinting data:
navigator.userAgent // "Mozilla/5.0 (Windows NT 10.0; Win64; x64)..."
navigator.platform // "Win32"
navigator.language // "en-US"
navigator.languages // ["en-US", "en"]
navigator.hardwareConcurrency // 8
navigator.deviceMemory // 8
navigator.maxTouchPoints // 0 (desktop) or 5+ (mobile)
navigator.cookieEnabled // true
navigator.pdfViewerEnabled // true
Screen and display
screen.width // 1920
screen.height // 1080
screen.colorDepth // 24
window.devicePixelRatio // 1 (standard) or 2 (HiDPI/Retina)
screen.availWidth // 1920 (or less with vertical taskbar)
screen.availHeight // 1040 (minus horizontal taskbar)
WebGL and GPU
WebGL reveals your graphics hardware:
const canvas = document.createElement('canvas')
const gl = canvas.getContext('webgl')
const ext = gl.getExtension('WEBGL_debug_renderer_info')
const vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL) // "Google Inc. (Intel)"
const renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL) // "ANGLE (Intel, Mesa Intel(R)...)"
GPU configurations vary widely and are hard to spoof consistently, making this one of the strongest fingerprinting signals.
Canvas fingerprinting
The same text rendered on different browser/OS/GPU combinations produces pixel-level differences due to different font rasterizers, anti-aliasing algorithms, and GPU drivers:
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
ctx.font = '14px Arial'
ctx.fillText('fingerprint test', 2, 15)
const dataUrl = canvas.toDataURL() // Different data URL per browser/OS/GPU
The resulting data URL is typically hashed to create a compact fingerprint value.
Audio fingerprinting
The AudioContext API processes audio signals slightly differently depending on the platform's audio stack:
const ctx = new OfflineAudioContext(1, 44100, 44100)
const oscillator = ctx.createOscillator()
oscillator.type = 'triangle'
oscillator.frequency.setValueAtTime(10000, ctx.currentTime)
oscillator.connect(ctx.destination)
oscillator.start(0)
ctx.startRendering().then((buffer) => {
// Hash the audio samples, varies by platform
const samples = buffer.getChannelData(0)
})
Font detection
Available fonts vary by OS and installed software. Detection scripts test for font presence by rendering text with a candidate font and comparing the width against a generic fallback:
// If text rendered with "Segoe UI" has a different width
// than the same text with "monospace", the font is installed
Windows, macOS, and Linux each have distinct default font sets. Segoe UI is Windows-only, for example.
Timezone and locale
Intl.DateTimeFormat().resolvedOptions().timeZone // "America/New_York"
new Date().getTimezoneOffset() // 300 (EST is UTC-5)
Intl.NumberFormat().resolvedOptions().locale // "en-US"
Note: getTimezoneOffset() returns a positive number when local time is behind UTC. For EST (UTC-5), the return value is 300 (not -300).
Why fingerprinting matters for bot detection
Automated browsers have fingerprints that look different from real users:
- Missing signals. Headless browsers may lack plugins, report a software GPU renderer, or have incomplete API implementations.
- Impossible combinations. A "Chrome on Windows" fingerprint with macOS-only fonts.
- Homogeneity. All instances in a headless browser farm may share identical fingerprints, unlike real users whose hardware and settings vary.
- Abnormal values. Zero plugins,
SwiftShaderas GPU renderer, or default viewport sizes like 800x600.
Detection systems combine these signals into a risk score. A few anomalies might be tolerated. A cluster of them triggers blocking.
Fingerprinting vs. cookies
| Aspect | Cookies | Fingerprinting |
|---|---|---|
| Storage | Client-side file | Server-side computation |
| User control | Can be deleted | Cannot be "deleted" |
| Consent | Required under GDPR | Regulatory gray area |
| Uniqueness | Explicit identifier | Statistical identifier |
| Persistence | Until expiry or deletion | Until hardware/software changes |
| Evasion | Clear cookies | Change browser configuration |
Fingerprinting is harder to evade because there's nothing to delete. The fingerprint is computed from your browser's inherent properties.
Fingerprint entropy
Not all signals contribute equally. Entropy measures how much each signal narrows down your identity. Higher entropy means more identifying power.
The EFF's 2010 Panopticlick study measured these approximate entropy values from a sample of ~470,000 browsers:
| Signal | Approximate entropy |
|---|---|
| Plugins | ~15 bits |
| Fonts | ~14 bits |
| User-Agent string | ~10 bits |
| Screen resolution | ~5 bits |
| Timezone | ~3 bits |
Canvas and audio fingerprinting were not measured in the original study but are widely used today.
You need roughly 33 bits of entropy to uniquely identify one person among 8 billion (since 2^33 ≈ 8.6 billion). Fingerprinting systems collect well over 33 bits, which is why they're effective.
Defensive fingerprinting
If you run automated browsers and want to avoid detection, the key principles are:
- Know your fingerprint. You can't fix what you can't see.
- Match a real profile. Your fingerprint should be consistent with a real browser on a real OS.
- Stay consistent. Every signal needs to agree with every other signal.
- Monitor for changes. Browser updates can alter your fingerprint.
Testing your fingerprint
StealthCheck analyzes your browser's fingerprint across 190+ checks in 9 scoring categories. It flags exactly which signals are anomalous and explains why.
- Run a free fingerprint test to see your score and detailed breakdown
- How spoofing detection works covers the techniques detection systems use
Test your browser stealth for free
Run a free fingerprint test and see exactly what detection systems see.