Every signal, in one index
32 signals in 6 categories. 5 of them ask your permission first. The other 27 are read the moment a page opens, with no prompt and nothing to decline, which is the part most people are surprised by.
The Exposure column is our own estimate of how much each signal adds to a browser fingerprint, taken from the entropy model on the methodology page. High means 5 bits or more, Medium 2 to under 5 bits, Low under 2 bits. Signals the model does not count are marked Not scored.
Browser (5)
What your browser announces about itself on every request.
| Signal | JavaScript call | Asks permission | Exposure |
|---|---|---|---|
| User agent | navigator.userAgent | No | High, 10 bits |
| Browser | navigator.userAgentData?.brands ?? navigator.userAgent | No | Medium, 2 bits |
| Operating system | navigator.userAgentData?.platform ?? navigator.userAgent | No | Medium, 2 bits |
| Language | navigator.languages | No | Medium, 2.5 bits |
| Cookies enabled | navigator.cookieEnabled | No | Low, 0.3 bits |
Network (8)
What your connection reveals, from your public IP to your headers.
| Signal | JavaScript call | Asks permission | Exposure |
|---|---|---|---|
| IP address | fetch('/api/ip') | No | Not scored |
| IPv4 address | fetch('/api/ip') then check for ':' in the address | No | Not scored |
| Public IP | fetch('/api/ip') | No | Not scored |
| Private IP | not readable by a website | No | Not scored |
| IP location | fetch('/api/ip') returning the platform's geo headers | No | Not scored |
| Connection type | navigator.connection | No | Low, 1.5 bits |
| Request headers | reconstructed from navigator, not read directly | No | Not scored |
| Referrer | document.referrer | No | Not scored |
Location (6)
What the Geolocation API can pin down, only with your permission.
| Signal | JavaScript call | Asks permission | Exposure |
|---|---|---|---|
| Location | navigator.geolocation.getCurrentPosition(success, error) | Yes | Not scored |
| Zip code | navigator.geolocation.getCurrentPosition then a reverse geocode | Yes | Not scored |
| Postal code | navigator.geolocation.getCurrentPosition then a reverse geocode | Yes | Not scored |
| Address | navigator.geolocation.getCurrentPosition then a reverse geocode | Yes | Not scored |
| Timezone | Intl.DateTimeFormat().resolvedOptions().timeZone | No | Medium, 3 bits |
| Elevation | position.coords.altitude from getCurrentPosition | Yes | Not scored |
Display (6)
The size, density and graphics of the screen you are reading on.
| Signal | JavaScript call | Asks permission | Exposure |
|---|---|---|---|
| Screen resolution | screen.width and screen.height | No | Medium, 4.5 bits |
| Viewport size | window.innerWidth and window.innerHeight | No | Medium, 4 bits |
| Color depth | screen.colorDepth | No | Low, 0.5 bits |
| Device pixel ratio | window.devicePixelRatio | No | Low, 1.5 bits |
| WebGL renderer | gl.getParameter(gl.getExtension('WEBGL_debug_renderer_info').UNMASKED_RENDERER_WEBGL) | No | High, 7 bits |
| GPU | gl.getParameter(gl.getExtension('WEBGL_debug_renderer_info').UNMASKED_VENDOR_WEBGL) | No | Medium, 2 bits |
Device (5)
Hardware hints your browser exposes to any page you open.
| Signal | JavaScript call | Asks permission | Exposure |
|---|---|---|---|
| Device type | navigator.maxTouchPoints with navigator.userAgent | No | Low, 1 bit |
| Device memory | navigator.deviceMemory | No | Low, 1.2 bits |
| CPU cores | navigator.hardwareConcurrency | No | Low, 1.8 bits |
| Battery | navigator.getBattery() | No | Low, 1 bit |
| Touch support | navigator.maxTouchPoints | No | Low, 1 bit |
Privacy (2)
Signals about tracking, and how identifiable you are overall.
| Signal | JavaScript call | Asks permission | Exposure |
|---|---|---|---|
| Do Not Track | navigator.doNotTrack | No | Low, 0.5 bits |
| Browser fingerprint | the combination of every signal above, hashed locally | No | Not scored |