Browser Fingerprint Visualizer — What Websites Know About You
// browser fingerprint inspector
Without cookies, logins or permissions, every website you visit can silently build a persistent profile of your device. This tool collects the same signals a tracker would — then explains exactly what was found, why each signal matters, and how to reduce your exposure.
Scan Your Browser
This tool runs entirely in your browser. No data leaves this page — no network requests are made during the scan. Results are computed locally and discarded when you close the tab.
zero network requests
no data stored
canvas & webgl
audio fingerprint
font detection
hardware probes
permissions audit
scanning…
initialising
Identity & locale signals
Hardware & display probes
Canvas 2D rendering fingerprint
WebGL & GPU renderer
AudioContext fingerprint
Installed font probes (52 fonts)
Browser capability flags
Connection & permissions
Hashing all signals (SHA-256)
privacy risk at a glance
signals
—
attributes collected
entropy bits
—
estimated uniqueness
canvas unique
—
2D rendering path
webgl unique
—
GPU renderer exposed
fonts detected
—
out of 52 probed
overall risk
—
fingerprint strength
identity & locale
What is this? These signals are sent by your browser automatically with every HTTP request and are exposed to every JavaScript file loaded on any page you visit — no interaction required.
User Agent is the most information-dense single string your browser transmits. It contains your browser name and full version number, the rendering engine and its version, your operating system name and version, and sometimes device class. A 2024 Chrome user agent looks like:
Language preferences (
Timezone via
Do Not Track is an HTTP header that browsers can send to request sites not track you. It is entirely ignored by the advertising industry and is actually counterproductive: enabling it makes you one of a smaller set of users who opted in, which is itself a rare signal that narrows the crowd you blend into.
User Agent is the most information-dense single string your browser transmits. It contains your browser name and full version number, the rendering engine and its version, your operating system name and version, and sometimes device class. A 2024 Chrome user agent looks like:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
From this one string, a tracker knows: you are on Windows 10 or 11, using Chrome 124, on a 64-bit processor. That alone narrows you from ~5 billion internet users to a much smaller cohort.
Language preferences (
navigator.language and navigator.languages) reveal your primary locale and ordered fallback list. A list of ["fr-CH","fr","de","en"] strongly implies Switzerland. Your language list is set by your OS and browser preferences — it persists across reboots and private browsing sessions.
Timezone via
Intl.DateTimeFormat().resolvedOptions().timeZone returns your IANA timezone string (e.g. Europe/Zurich). Unlike your IP address — which a VPN can mask — your browser timezone comes from your OS clock settings and cannot be hidden without special extensions or a browser mode that lies about it. Timezone cross-referenced with IP gives extremely accurate location.
Do Not Track is an HTTP header that browsers can send to request sites not track you. It is entirely ignored by the advertising industry and is actually counterproductive: enabling it makes you one of a smaller set of users who opted in, which is itself a rare signal that narrows the crowd you blend into.
hardware
CPU logical cores (
Device memory (
Max touch points (
Network API (
navigator.hardwareConcurrency) returns the number of logical processors — threads, not physical cores. A value of 2 suggests a low-end phone or VM; 8 suggests a mid-range laptop; 16+ suggests a workstation or Mac Pro. This value is stable across sessions and requires no permission.
Device memory (
navigator.deviceMemory) returns RAM in coarse buckets: 0.25, 0.5, 1, 2, 4, 8 GB. Firefox and Safari intentionally omit this API — its absence is itself a signal (you are likely not on Chrome).
Max touch points (
navigator.maxTouchPoints) distinguishes: 0 = desktop with no touchscreen, 1 = old single-touch device, 5–10 = modern phone or tablet, 10+ = some laptops. Combined with user agent, this resolves exact device class.
Network API (
navigator.connection) is Chrome-only and exposes effective connection type (4g, wifi, slow-2g), estimated downlink speed, and round-trip time. This can correlate with location (poor mobile coverage in rural areas, fibre in cities).
display
Screen resolution (
Device pixel ratio (
Window size changes as users resize — so trackers usually record it as a bucket range rather than exact pixels. It still helps distinguish whether you are in full-screen mode, windowed, or on a small display.
Colour depth is almost universally 24-bit on modern screens. If yours differs, it immediately places you in a tiny minority.
screen.width × screen.height) is one of the highest-entropy display signals. EFF's Panopticlick research found that ~80% of users have a screen resolution shared by fewer than 1 in 200 visitors. The combination of width, height, and available dimensions (which subtract the OS taskbar/dock) is even more specific.
Device pixel ratio (
window.devicePixelRatio) indicates screen density. A ratio of 1 is standard desktop; 2 is Retina/HiDPI (common on Apple hardware and modern laptops); 3 is found on high-end Android phones. Non-integer ratios (e.g. 1.25, 1.5) indicate Windows HiDPI scaling modes and are quite rare — making them very identifying.
Window size changes as users resize — so trackers usually record it as a bucket range rather than exact pixels. It still helps distinguish whether you are in full-screen mode, windowed, or on a small display.
Colour depth is almost universally 24-bit on modern screens. If yours differs, it immediately places you in a tiny minority.
canvas fingerprint 2D API
rendering…
why canvas uniquely identifies your device
The HTML5 Canvas API lets JavaScript draw text and shapes and then read back every pixel as raw data via toDataURL(). The drawing instructions are identical for every browser — but the output pixels are not.
The exact pixel values depend on: (1) the GPU driver's sub-pixel rasterisation algorithm, (2) the operating system's font rendering engine (Windows uses DirectWrite, macOS uses Core Text, Linux uses FreeType — all produce visibly different letter shapes), (3) anti-aliasing settings, (4) whether hardware acceleration is active, and (5) the specific font versions installed.
The SHA-256 hash of your pixel data is stable across every page load, every private browsing session, and every browser restart — as long as your GPU and OS remain the same. Changing your browser does not change this hash if the underlying render stack is the same.
To block it: Firefox with
privacy.resistFingerprinting = true returns a blank canvas. Brave injects per-session random noise. A CanvasBlocker extension can spoof or randomise the output.
webgl fingerprint GPU path
why WebGL exposes your GPU model
WebGL is a JavaScript API that gives direct access to your GPU via OpenGL ES. The extension WEBGL_debug_renderer_info was originally designed for bug reports — it exposes the exact GPU model string and vendor name that the driver reports.
On a real Mac you might see:
Apple M3 Pro GPU. On a gaming PC: NVIDIA GeForce RTX 4090/PCIe/SSE2. These strings are globally rare — the combination of GPU model + operating system + browser from the user agent is often unique to a single person.
A software renderer (SwiftShader, LLVMpipe, Mesa) means WebGL is running on the CPU — this happens in VMs, headless browsers, or when you have intentionally disabled GPU access. It hides your real GPU, which is better for privacy, but is itself a signal that you are in an unusual environment.
Brave replaces real GPU strings with
Apple GPU or Google SwiftShader. Firefox with resistFingerprinting blocks the debug extension entirely.
audiocontext fingerprint web audio API
What is this? The Web Audio API is designed for processing and synthesising sound in the browser. Like canvas, it produces results that vary slightly between devices — even with identical JavaScript instructions — because of differences in audio processing pipelines, sample rate handling, and floating-point arithmetic implementations.
The technique: an OscillatorNode generates a known frequency (e.g. 10,000 Hz triangle wave). An AnalyserNode measures the frequency spectrum. The floating-point values returned differ fractionally between CPU architectures, operating systems, and audio driver implementations. These differences are microscopic — but when hashed, they produce a stable, unique fingerprint that pairs with the canvas hash to give extremely high confidence identification.
This technique was first documented in research by Englehardt & Narayanan (2016) and is actively used by commercial tracking scripts today. It does not require microphone permission — it synthesises audio entirely internally, in a virtual audio graph, and reads back the processed numbers. No sound is played.
Browser defences: Firefox with
The technique: an OscillatorNode generates a known frequency (e.g. 10,000 Hz triangle wave). An AnalyserNode measures the frequency spectrum. The floating-point values returned differ fractionally between CPU architectures, operating systems, and audio driver implementations. These differences are microscopic — but when hashed, they produce a stable, unique fingerprint that pairs with the canvas hash to give extremely high confidence identification.
This technique was first documented in research by Englehardt & Narayanan (2016) and is actively used by commercial tracking scripts today. It does not require microphone permission — it synthesises audio entirely internally, in a virtual audio graph, and reads back the processed numbers. No sound is played.
Browser defences: Firefox with
privacy.resistFingerprinting disables the AudioContext API entirely. Brave adds per-session noise to the returned values. Safari limits the precision of returned floats. Chrome currently has no built-in protection.
audio hash
computing…
sample rate
—
max channels
—
state
—
installed font probes
—
How font detection works (no permission required): Each font is probed by rendering a test string on an offscreen canvas in three fonts: the font being tested, plus two fallback fonts (
Why this is identifying: Your font set is a direct record of your software history. Office 2016 installs Calibri, Cambria, and Franklin Gothic. Adobe Creative Suite installs dozens of unique fonts. Developers often have Fira Code, JetBrains Mono, or Cascadia Code. The specific intersection of fonts you have is highly personal and stable across years — you don't uninstall fonts often.
Across 52 probed fonts, most users detect between 6 and 20. The exact subset you have is often unique within 1 in 1,000 visitors. Combined with other signals, it dramatically narrows who you are.
Defence: Firefox with
serif and sans-serif). If the pixel-width or rendered height of the test string differs from the fallback measurement, the font is installed. This requires only the Canvas API — no font enumeration API, no file system access.
Why this is identifying: Your font set is a direct record of your software history. Office 2016 installs Calibri, Cambria, and Franklin Gothic. Adobe Creative Suite installs dozens of unique fonts. Developers often have Fira Code, JetBrains Mono, or Cascadia Code. The specific intersection of fonts you have is highly personal and stable across years — you don't uninstall fonts often.
Across 52 probed fonts, most users detect between 6 and 20. The exact subset you have is often unique within 1 in 1,000 visitors. Combined with other signals, it dramatically narrows who you are.
Defence: Firefox with
privacy.resistFingerprinting only reports fonts that the OS bundled — it hides every application-installed font. Brave does the same. There is no extension-based fix that works well — you would need the browser itself to intercept canvas text measurement calls.
browser capability flags
What this reveals: Modern browsers expose hundreds of API flags via JavaScript. Their presence or absence is not random — it reflects your exact browser version, operating system, and whether you have privacy extensions installed. Trackers cross-reference these flags against known browser fingerprint databases to identify your browser type and version with high confidence, even when your user agent string is spoofed.
Key high-risk flags:
WebRTC — Real-Time Communication API. Even behind a VPN, a WebRTC STUN request can reveal your local network IP address (e.g.
localStorage / sessionStorage / indexedDB — These are persistent storage mechanisms. If cookies are blocked, trackers often store identifiers here instead. They persist across private browsing sessions in many browsers unless the user explicitly clears site data.
Battery API (
SharedArrayBuffer — Enables high-resolution timing, which is required for Spectre-class side-channel attacks. It is disabled by default unless a page opts in with Cross-Origin Isolation headers. Its presence or absence is a signal of the exact browser configuration.
Permissions API — Browsers report whether specific permissions (notifications, geolocation, camera) are already granted, denied, or prompt state. A user who has previously granted camera access to this device has a different profile than one who has never been asked.
Key high-risk flags:
WebRTC — Real-Time Communication API. Even behind a VPN, a WebRTC STUN request can reveal your local network IP address (e.g.
192.168.1.x) and sometimes your real public IP. This is a well-known VPN bypass vector. Firefox has a setting to limit this; Chrome does not block it by default.
localStorage / sessionStorage / indexedDB — These are persistent storage mechanisms. If cookies are blocked, trackers often store identifiers here instead. They persist across private browsing sessions in many browsers unless the user explicitly clears site data.
Battery API (
navigator.getBattery()) — Exposed battery charge level and charge/discharge rate. Research in 2015 showed that battery drain patterns are unique enough per device to track users across different websites and even different browsers. Most browsers have since removed or restricted this API.
SharedArrayBuffer — Enables high-resolution timing, which is required for Spectre-class side-channel attacks. It is disabled by default unless a page opts in with Cross-Origin Isolation headers. Its presence or absence is a signal of the exact browser configuration.
Permissions API — Browsers report whether specific permissions (notifications, geolocation, camera) are already granted, denied, or prompt state. A user who has previously granted camera access to this device has a different profile than one who has never been asked.
connection & permissions
Connection information: While the Network Information API (
Permission state is readable via
Referrer and navigation: The
navigator.connection) is Chrome-only, browsers universally expose the protocol version via the current page's URL scheme and HTTP/2 support. Your effective connection type (wifi, 4g, ethernet) correlates with location and device type — nobody uses an ethernet connection from a phone.
Permission state is readable via
navigator.permissions.query() for most APIs. A site can silently check whether you have previously granted camera, microphone, geolocation, or notification permissions — without triggering the permission prompt. The pattern of what you've granted is identifying: a developer who granted notifications to a CI/CD tool has a different profile than an average user who has never granted any permissions.
Referrer and navigation: The
document.referrer tells the current page which URL you came from. The performance.navigation API distinguishes direct load, link click, form submit, browser back/forward, and refresh. These can be used to build a session graph of your browsing path.
connection signals
entropy per signal
estimated bits of identifying power
What is entropy in this context? Shannon entropy (measured in bits) quantifies how much information a signal carries. If a signal has 1 bit of entropy, it splits the population in half — like a coin flip. 10 bits means 1 in 1,024 people match your value. 33 bits would uniquely identify 1 person in 8 billion.
These estimates are based on EFF Panopticlick research, Laperdrix et al. (AmIUnique), and Englehardt & Narayanan (OpenWPM) crawl data. Real-world entropy depends on which population is visiting your site — the entropy of "Chrome on Windows" differs between a security blog and a mainstream news site.
The signals below are additive — not every combination is independent, but in practice the overlapping information is small. A tracker combining all visible signals routinely achieves 30–70 bits of effective entropy, which is enough to uniquely identify most users even without cookies. This is why fingerprinting is now the dominant tracking technique as third-party cookies are phased out.
These estimates are based on EFF Panopticlick research, Laperdrix et al. (AmIUnique), and Englehardt & Narayanan (OpenWPM) crawl data. Real-world entropy depends on which population is visiting your site — the entropy of "Chrome on Windows" differs between a security blog and a mainstream news site.
The signals below are additive — not every combination is independent, but in practice the overlapping information is small. A tracker combining all visible signals routinely achieves 30–70 bits of effective entropy, which is enough to uniquely identify most users even without cookies. This is why fingerprinting is now the dominant tracking technique as third-party cookies are phased out.
how to reduce your fingerprint
The fundamental tension: Every change you make to your browser to become less unique is itself a signal. A user running Tor Browser with JavaScript disabled is highly private but easily identified as a "Tor Browser user" — they blend in with other Tor users, not with the general web population. The goal of anti-fingerprinting is not to have no fingerprint, but to have a common one — to blend into the largest possible crowd.
Why extensions often backfire: A "privacy" extension that spoofs your canvas output produces a different canvas hash every time — but if you are the only one using that exact extension version, your canvas hash being different every load is itself a pattern. The most effective defences are browser-level, standardised, and shared by millions of users simultaneously.
Why extensions often backfire: A "privacy" extension that spoofs your canvas output produces a different canvas hash every time — but if you are the only one using that exact extension version, your canvas hash being different every load is itself a pattern. The most effective defences are browser-level, standardised, and shared by millions of users simultaneously.