Browser Fingerprinting Explained: How Websites Identify You Without Cookies
Table of Contents
What Browser Fingerprinting Is
Browser fingerprinting is a tracking technique that identifies users by collecting attributes of their browser and device configuration. Unlike cookies, which store an explicit identifier on your device, fingerprinting derives an identifier from characteristics your browser reveals during normal operation.
Every time your browser loads a web page, it shares information with the server: your user agent string (browser name, version, operating system), screen resolution, installed plugins, time zone, language preferences, and many other attributes. Individually, each attribute is shared by millions of users. But the combination of all these attributes can be unique or nearly unique to a specific browser installation.
A 2010 study by the Electronic Frontier Foundation (Panopticlick, now Cover Your Tracks) found that 83.6% of browsers in their dataset had a unique fingerprint. Among browsers with Flash or Java enabled (which exposed additional attributes), 94.2% were unique. The study concluded that browser fingerprinting is a viable tracking mechanism that works without any cooperation from the user - no cookies need to be accepted, no storage needs to be permitted.
Since then, fingerprinting has become more sophisticated. New web APIs have introduced additional surfaces for fingerprint extraction, while privacy-focused browsers and extensions have developed countermeasures. The result is an ongoing technical competition between fingerprinters and defenders.
Entropy and Uniqueness
Fingerprinting effectiveness is measured in bits of entropy. Each attribute contributes entropy based on how many distinct values it takes across the user population. An attribute with two equally common values contributes 1 bit of entropy. An attribute with 256 equally common values contributes 8 bits.
To uniquely identify one person among a billion (roughly the number of active web users), you need about 30 bits of entropy. The practical question is whether browser attributes collectively provide enough entropy to achieve this.
graph TD
subgraph Fingerprint_Components["Fingerprint Entropy Sources"]
A[User Agent String
~10 bits]
B[Screen Resolution
~5 bits]
C[Timezone
~4 bits]
D[Language
~4 bits]
E[Installed Fonts
~14 bits]
F[Canvas Hash
~8 bits]
G[WebGL Renderer
~10 bits]
H[Audio Fingerprint
~6 bits]
I[Plugin List
~7 bits]
J[Do Not Track
~1 bit]
end
subgraph Total["Combined Entropy"]
K[Total: ~50-70 bits]
L[Needed for uniqueness: ~30 bits]
M[Result: Highly identifying]
end
A --> K
B --> K
C --> K
D --> K
E --> K
F --> K
G --> K
H --> K
I --> K
J --> K
K --> L
L --> M
Individual browser attributes provide modest entropy, but combined they far exceed the ~30 bits needed for unique identification
User agent strings alone provide roughly 10 bits of identifying information. They reveal the browser name and version, operating system and version, and sometimes additional details like the device model. Screen resolution adds about 5 bits. Timezone and language add a few more bits each. These low-entropy attributes combine additively (when independent) to create a composite fingerprint with far more entropy than any single attribute.
High-entropy attributes like installed fonts (which can provide 14+ bits on their own) and canvas rendering (8+ bits) push the total well beyond the uniqueness threshold. Research consistently shows that a typical browser fingerprint contains 50 to 70 bits of entropy, far more than needed to uniquely identify users even in very large populations.
Canvas Fingerprinting
Canvas fingerprinting exploits the HTML5 Canvas API, which allows web pages to draw 2D graphics programmatically. The technique works because the same drawing instructions produce slightly different pixel-level results on different hardware and software configurations.
A fingerprinting script creates a hidden canvas element and draws a complex image on it - typically a combination of text in specific fonts, shapes with gradients, and emoji. It then reads back the pixel data using toDataURL() or getImageData() and hashes the result.
The rendering differences arise from multiple sources: the GPU and its drivers, the font rendering engine (ClearType on Windows, Core Text on macOS, FreeType on Linux), anti-aliasing algorithms, sub-pixel rendering settings, and color management profiles. Two computers with different GPUs, different operating systems, or even different driver versions will produce detectably different canvas outputs for the same drawing instructions.
Canvas fingerprinting was first documented in a 2014 Princeton study ("The Web Never Forgets") that found canvas fingerprinting scripts on 5% of the top 100,000 websites. The most prominent deployer at the time was AddThis, a social sharing widget present on millions of websites. Since then, canvas fingerprinting has become widespread in commercial tracking libraries.
The technique is difficult to defend against because the Canvas API is used for legitimate purposes (games, data visualization, image processing), so blocking it entirely breaks web functionality. Browsers can add noise to canvas output (as Tor Browser and Brave do), but the noise must be consistent across page loads to avoid breaking legitimate applications while still differing between users.
WebGL Fingerprinting
WebGL (Web Graphics Library) provides a JavaScript API for rendering 3D graphics in the browser. Like the Canvas API, WebGL exposes hardware-dependent rendering differences that can be used for fingerprinting.
WebGL fingerprinting operates at two levels. The first is attribute-based: the WebGL API exposes information about the GPU through the WEBGL_debug_renderer_info extension, which reveals the GPU vendor and model (for example, "NVIDIA Corporation" and "GeForce RTX 3080"). This alone is moderately identifying, as GPU model distributions are not uniform.
The second level is rendering-based, similar to canvas fingerprinting. A script renders a 3D scene with specific shaders, textures, and lighting, then reads back the pixel data. Differences in GPU hardware, driver versions, and shader compilers produce different outputs for the same instructions. These differences are subtle (often at the sub-pixel level) but consistent and detectable through hashing.
WebGL also exposes a set of parameters through getParameter() that reveal technical details about the GPU's capabilities: maximum texture size, maximum render buffer size, supported shader precision, available extensions, and more. The combination of these parameters is highly identifying because it reflects the specific hardware and driver combination.
Font Enumeration
The set of fonts installed on your system is one of the highest-entropy fingerprinting vectors. Most systems come with a default set of fonts, but users and applications install additional fonts over time. A system with Adobe Creative Suite installed has a distinctly different font set than one without. Regional language packs add their own fonts. Custom fonts installed by the user make the set even more unique.
Font enumeration works through several mechanisms. The traditional approach uses JavaScript to test whether specific fonts are present. The script creates hidden text elements, sets them to a known fallback font, measures the text width and height, then changes the font to a test font. If the measurements change, the font is present. By testing hundreds or thousands of fonts, the script can determine which are installed.
This measurement-based approach does not require any special permissions. It uses standard CSS and JavaScript APIs that every website has access to. The browser does not report the installed font list directly (with the exception of the now-deprecated document.fonts enumeration in some browsers), but the measurement technique achieves the same result.
The CSS font-access API (proposed but limited in adoption) would provide direct access to the installed font list, which would simplify font fingerprinting but also make it more visible and easier to control through permissions.
AudioContext Fingerprinting
The Web Audio API, designed for processing and synthesizing audio in the browser, provides another fingerprinting surface. AudioContext fingerprinting generates a sound using oscillators and dynamic compressors, processes it through the audio stack, and reads back the resulting waveform. Differences in the audio processing hardware, drivers, and software implementation produce distinct waveforms on different systems.
A typical AudioContext fingerprint involves creating an OscillatorNode, connecting it to a DynamicsCompressorNode, rendering the output to an OfflineAudioContext, and hashing the resulting Float32Array of audio samples. No sound is played to the user - the processing happens entirely in memory.
AudioContext fingerprinting is less well-known than canvas fingerprinting but provides meaningful additional entropy. A 2016 study found that the technique could distinguish between devices with different audio hardware or driver versions, adding 5 to 7 bits of entropy to a composite fingerprint.
Other Fingerprinting Vectors
Beyond the major techniques, numerous other browser attributes contribute to fingerprinting.
Navigator API properties. navigator.hardwareConcurrency reveals the number of CPU cores. navigator.deviceMemory reveals approximate RAM. navigator.maxTouchPoints reveals touch screen capability. Each adds a few bits of entropy.
CSS media queries. JavaScript can query window.matchMedia() to determine the user's preferred color scheme (light/dark), reduced motion preference, contrast preference, and display characteristics. These preferences vary across users and contribute to fingerprint uniqueness.
Battery Status API. Now restricted in most browsers, this API previously exposed battery level, charging status, and time to charge/discharge - providing surprisingly high entropy and even enabling short-term tracking through battery state correlation.
Network information. The Network Information API exposes connection type (4G, WiFi, etc.), effective bandwidth, and round-trip time. While less precise than other methods, it adds additional identifying signals.
Keyboard layout and language. The keyboard event's getLayoutMap() method and various input event properties can reveal the keyboard layout, which varies by language and region.
WebRTC. WebRTC can expose local IP addresses (including private/internal IPs), which are identifying within local networks. Many browsers now restrict this, but legacy configurations still leak.
Combining Signals
The power of fingerprinting comes from combining multiple low-to-moderate entropy signals into a high-entropy composite identifier. A fingerprinting library collects dozens of attributes, concatenates them, and hashes the result to produce a single identifier.
Commercial fingerprinting libraries like FingerprintJS (now Fingerprint.com) report identification accuracy above 99% for returning visitors. Their open-source library collects over 70 signals and combines them using a hashing algorithm that produces a consistent identifier across page loads.
The stability of a fingerprint over time is as important as its uniqueness. Browser updates, driver updates, font installations, and hardware changes all modify the fingerprint. Sophisticated fingerprinting systems account for this by using fuzzy matching: if a new fingerprint differs from a stored one in only a few low-weight attributes, it is treated as the same user with an updated configuration.
Some systems combine fingerprinting with other identification methods as a fallback. If a user's cookies are deleted, the fingerprint can re-identify them and restore their tracking profile. This is sometimes called "respawning" - recreating a deleted cookie based on a persistent fingerprint.
What Actually Stops Fingerprinting
Defending against fingerprinting is harder than defending against cookies. Cookies are stored locally and can be deleted. Fingerprints are computed from attributes that your browser must expose to function correctly. The defense options fall into three categories.
Uniformity (Tor Browser approach). Make your browser look identical to every other browser using the same defense. Tor Browser normalizes window size to specific increments, disables or spoofs WebGL, returns generic font lists, adds consistent noise to canvas output, and restricts JavaScript APIs that provide fingerprinting signals. The goal is not to have no fingerprint but to have the same fingerprint as every other Tor Browser user.
Randomization (Brave approach). Add random noise to fingerprinting signals on each page load. Brave randomizes canvas output, audio processing results, and WebGL rendering so that the same browser produces a different fingerprint every time. This prevents fingerprints from being used to track users across sessions because the identifier changes constantly.
Restriction (Firefox Enhanced Tracking Protection). Block known fingerprinting scripts based on blocklists. Firefox's Enhanced Tracking Protection uses the Disconnect.me blocklist to identify and block scripts from known fingerprinting domains. This is effective against commercial fingerprinting services but does not protect against custom or first-party fingerprinting code.
Each approach has tradeoffs. Uniformity restricts browser customization and can break websites that depend on accurate attribute reporting. Randomization can cause inconsistent behavior within a page load if the noise is not carefully implemented. Blocklists require continuous maintenance and miss new or unlisted fingerprinting scripts.
graph TD
subgraph Defense_Strategies["Anti-Fingerprinting Strategies"]
A[Uniformity
Tor Browser]
B[Randomization
Brave]
C[Restriction
Firefox ETP]
end
subgraph Uniformity_Detail["Uniformity"]
A --> D[Same window size]
A --> E[Generic fonts]
A --> F[Spoofed WebGL]
A --> G[Normalized canvas]
D --> H[Pro: Blends with crowd]
D --> I[Con: Less customizable]
end
subgraph Randomization_Detail["Randomization"]
B --> J[Random canvas noise]
B --> K[Random audio output]
B --> L[Random WebGL noise]
J --> M[Pro: Different every load]
J --> N[Con: May break sites]
end
subgraph Restriction_Detail["Restriction"]
C --> O[Block known scripts]
C --> P[Disconnect.me blocklist]
O --> Q[Pro: No site breakage]
O --> R[Con: Misses custom scripts]
end
Three strategies for defending against browser fingerprinting, each with distinct tradeoffs
The Fingerprinting Arms Race
Browser fingerprinting exists in a perpetual arms race between trackers and privacy defenses. As browsers restrict access to fingerprinting surfaces, trackers find new ones. As trackers develop new techniques, browsers develop new countermeasures.
Recent developments in this arms race include the deprecation of high-entropy APIs (Battery Status, Network Information access restricted), the introduction of privacy budgets (proposals to limit the total amount of identifying information a site can access), and Client Hints (a replacement for the User-Agent string that provides less information by default and requires sites to explicitly request additional detail).
The W3C's Privacy Interest Group (PING) now reviews new web standards for fingerprinting potential before they are adopted. New APIs must justify their fingerprinting surface and ideally provide mechanisms to limit it. This has not eliminated the problem, but it has slowed the introduction of new high-entropy fingerprinting vectors.
For privacy-conscious users, the practical recommendation is to use a browser with built-in fingerprinting resistance (Tor Browser for maximum protection, Brave or Firefox with strict privacy settings for daily use), avoid installing unusual browser extensions (which modify your browser's behavior in detectable ways), and understand that fingerprinting resistance reduces but may not eliminate tracking.
Understanding what your devices expose at every layer - from browser attributes to wireless signals - is fundamental to making informed privacy choices. While browser fingerprinting tracks you at the application layer, tools like the BLEShark Nano reveal what your devices broadcast at the physical layer through BLE and WiFi, completing the picture of your digital footprint.
Get the BLEShark Nano - $36.99+