Browser Fingerprinting: Passive Signals Leak Before You Click
Passive browser signals like screen size and timezone enable fingerprinting without permission prompts. Learn how to audit your site and minimize privacy risks.
A Hacker News demo exposed the passive signals my browser leaked before I clicked. That's browser fingerprinting in action.
The BrowserLeaks demo reveals screen size, timezone, language, and dozens of other details. Privacy conversations often focus on permission prompts, but the web receives context before any prompt. Your browser, network, device, and runtime expose tiny facts that combine into a unique fingerprint. Developers should understand how this works and what to do about it.
How Browser Fingerprinting Works with Passive Signals
A website you've never visited can learn all this without explicit consent:
- Screen size, viewport size, and color depth
- Color scheme preference (light/dark mode)
- Timezone and language settings
- User-Agent string and client hints
- Touch support and media codec capabilities
- Network connection type (4G, Wi-Fi, etc.)
- Performance timings from the Navigation API
- Device memory and hardware concurrency
- Installed fonts (via CSS)
JavaScript observes API response times. CSS queries reveal layout constraints. HTTP headers carry negotiation preferences. Without third-party cookies, every page still gets a rich set of passive signals.
These signals are not just diagnostic curiosities. Many services, including large ad platforms, use them to fingerprint devices even after cookies are cleared. The Electronic Frontier Foundation's Cover Your Tracks project shows that passive signals alone carry significant entropy, capable of identifying browsers even with JavaScript disabled.
const signals = {
userAgent: navigator.userAgent,
screenWidth: screen.width,
screenHeight: screen.height,
colorDepth: screen.colorDepth,
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
language: navigator.language,
deviceMemory: navigator.deviceMemory,
hardwareConcurrency: navigator.hardwareConcurrency,
connection: navigator.connection?.effectiveType || 'unknown',
prefersDarkMode: window.matchMedia('(prefers-color-scheme: dark)').matches
};
Fingerprinting builds a persistent identity without cookies. Your timezone alone is not unique, but combined with screen size, browser version, installed fonts, device memory, language stack, and GPU quirks, it may create an identifier stable enough to track you across sessions. The Mozilla glossary on fingerprinting explains how these signals combine.
Treat Passive Browser Signals as User Data
If you collect it, you own the responsibility. Passive does not mean harmless. Storing raw user agent strings, full IP addresses, exact viewport dimensions, and detailed device data forever creates a privacy liability.
A better default is data minimization:
- Bucket values instead of storing exact ones. Use "mobile/tablet/desktop" instead of exact viewport dimensions when that suffices.
- Store country or region only when city-level precision is unnecessary.
- Truncate IP addresses (e.g., last octet to zero) where possible.
- Set short retention windows for diagnostic data (e.g., 30 days).
- Don't send every browser feature flag to five analytics vendors just because a dashboard might look interesting later.
Here's a concrete example: instead of storing exact viewport width, bucket it:
function getViewportBucket(width) {
if (width < 768) return 'mobile';
if (width < 1024) return 'tablet';
return 'desktop';
}
For timezone, you rarely need the full IANA timezone identifier. Storing the UTC offset (e.g., +0, +1) is often sufficient for analytics and reduces fingerprinting surface.
Security teams understand secrets minimization. Privacy engineering applies the same discipline to behavioral and device data. For more, see the web.dev guide on data minimization.
Threat-Model Your Analytics Pipeline for Privacy Risks
Most teams threat-model authentication flows, payment flows, and admin panels with concrete abuse cases. Fewer teams threat-model their analytics. Analytics often becomes the most complete behavioral database in the company.
Ask basic questions:
- What passive browser signals do we collect before consent?
- Which third parties receive them?
- Can you explain why each field is needed?
- How long do you retain it?
- Could this data identify a user even without cookies?
- Do you need exact values, or would buckets work?
If the answer is "I don't know," that's not a moral failure—it's a missing engineering task. Browser fingerprinting risks increase when teams collect without intention. Document the minimum data needed for each feature, and audit third-party scripts that might add extra signals.
Browser Vendors Tighten Anti-Tracking Protections
The browser platform is slowly reducing ambient leakage. User-Agent Client Hints replaced the bloated user agent string with structured negotiation. Storage partitioning makes cross-site tracking harder.
Safari and Firefox have been aggressive with anti-tracking protections. Chrome is moving through its Privacy Sandbox strategy, though not without controversy.
Still, compatibility pressure is real. The web depends on adaptive behavior, and adaptive behavior requires signals. The goal cannot be "the browser tells sites nothing." The goal should be proportional disclosure: enough information to render and function, not enough to silently build persistent identity graphs.
Tools like Cover Your Tracks and BrowserLeaks let you see your own passive signal profile. Use them as part of your security reviews to understand what data your site could be sending before you implement collection.
The Takeaway: Practice Data Minimization for Privacy
Be honest about the invisible contract: when a user visits your website, they don't arrive empty-handed. Their browser brings a bag of context and places it on the table.
- Build fast, responsive, localized experiences—but collect less than you can.
- Treat passive signals like personal data.
- Prefer coarse buckets.
- Delete diagnostics quickly.
- Audit third-party scripts.
- If a piece of browser context is not clearly improving the product, don't store it just because it's available.
Privacy isn't only about permission prompts. It starts before the first click.