Browser Identity
The largest group here, because it is where most detection actually starts: the plain-JavaScript properties a page reads in the first few milliseconds, before it draws anything. Individually most of these are one line each. What makes them a fingerprint is that a detector reads several and checks whether they agree - a navigator.webdriver of false next to a font set that belongs to a different operating system is caught by the comparison, not by either value alone.
What a fingerprint is, and what does not defeat it
- Can two devices share a browser fingerprint? - Sharing a fingerprint hides you in a crowd of real users; a unique one tracks you.
- Can you be fingerprinted in incognito mode? - Private mode clears cookies but leaves canvas, fonts, timezone and TLS fully readable.
- Does clearing cookies stop fingerprint tracking? - No: fingerprinting is stateless and rebuilds the same identity after every clear.
- Can a website tell you are running on a server? - How software WebGL, a missing audio device, headless metrics and datacenter ASN expose a server.
- Headless vs headful: what is actually being detected - Headlessness is rarely the tell; the hardware and rendering signals around it are.
- Is changing the user agent enough to avoid detection? - No: detectors cross-check the string against platform, TLS, WebGL renderer and Client Hints.
- Playwright User Agent: Why You Should Not Set It - Setting a Playwright user agent does not change fonts, GPU, codecs or TLS.
- fake-useragent is archived: what changes and what doesn’t - The Python package was archived in 2026; what breaks and what to use instead.
- What privacy.resistFingerprinting actually does - What it changes, what it breaks, and why this project leaves it off.
- navigator.webdriver is not the tell you think it is - A specified property, not a leak; patching it alone buys almost nothing.
Navigator strings and headers that must agree
- navigator.platform and oscpu on a spoofed OS - platform, oscpu and appVersion come from the real OS, so a Linux build leaks Linux.
- navigator.vendor and productSub: the Firefox tells - vendor is empty and productSub is 20100101 on real Firefox; a spoof gets these wrong.
- navigator.buildID and the stale build date tell - A Firefox-only build-date property; freezing it to a constant is a worse tell.
- Is navigator.connection a fingerprint in Firefox? - The Network Information API is Chromium-only, so a real Firefox returns undefined.
- Accept-Language header vs navigator.languages - One Firefox pref feeds both, so moving one and not the other is a clear tell.
- Client Hints and Sec-Fetch: headers that must agree - Sec-CH-UA and Sec-Fetch come from browser state, cheap to compare and hard to fake.
- hardwareConcurrency, deviceMemory and storage quota - Three one-line reads that go wrong on a server and are cross-checked against each other.
- navigator.maxTouchPoints and pointer consistency - maxTouchPoints reads 0 on a spoofed desktop and the pointer media queries must agree.
Screen, display and rendering signals
- Screen size and viewport tells in headless browsers - A headless browser invents screen and viewport values; which combinations never occur.
- window.devicePixelRatio: the pref that spoofs it - Set it with the layout.css.devPixelsPerPx string pref, and the values it must match.
- Color-gamut and HDR media queries as a fingerprint - color-gamut and dynamic-range media features expose display capability and must agree with colorDepth.
- CSS fingerprinting: what media queries reveal - Media queries and CSS system colours fingerprint a machine with no JavaScript.
- Can scrollbar width reveal my operating system? - Native scrollbar width is set by the OS and theme, leaking the real platform.
- Codec fingerprinting: canPlayType and MediaCapabilities - The formats a browser claims to play reveal its build and platform.
- prefers-reduced-motion and other OS-setting tells - How OS accessibility settings leak through pure CSS media features.
Device and sensor APIs
- Do accelerometer and gyroscope APIs leak on desktop? - Desktop Firefox stays silent; a spoofed desktop must not invent motion events.
- Battery API fingerprint: does Firefox expose it? - Desktop Firefox removed the Battery Status API in 2017, so a battery object is fake.
- Can the Gamepad API fingerprint or detect a bot? - Firefox returns an empty getGamepads() until a real gesture; match that stock shape.
- Permissions API: the two answers that must agree - The Permissions API and Notification.permission answer one question two ways.
- speechSynthesis.getVoices() returns an empty array - An async timing gotcha in every browser, and a voice list that names the wrong OS.
- Does storage quota estimate reveal disk size? - storage.estimate() buckets as a device fingerprint; keep it in a plausible bucket.
Automation surfaces beyond the page
- BFCache and pageshow.persisted under browser automation - Automation disables the back/forward cache, so pageshow.persisted is always false.
- Service workers, storage partitioning and automation - Service workers survive cookie clears, and blocking them is a signal real browsers avoid.
- Web Workers: where page-level fingerprint patches fail - A Web Worker is a separate realm, so page-level stealth patches never run there.
- Browser extensions are a fingerprint surface - An installed extension is a surface a page can detect three ways.
Table of contents
- navigator.webdriver is not the tell you think it is
- hardwareConcurrency, deviceMemory and storage quota
- Screen size and viewport tells in headless browsers
- Playwright headless vs headed: what detectors see
- Playwright User Agent: Why You Should Not Set It
- Client Hints and Sec-Fetch: headers that must agree
- Codec fingerprinting: canPlayType and MediaCapabilities
- Permissions API: the two answers that must agree
- CSS fingerprinting: what media queries reveal
- What privacy.resistFingerprinting actually does
- speechSynthesis.getVoices() returns an empty array
- Browser extensions are a fingerprint surface
- BFCache and pageshow.persisted under browser automation
- Service workers, storage partitioning and automation
- Web Workers: where page-level fingerprint patches fail
- fake-useragent is archived: what changes and what doesn't
- navigator.buildID and the stale build date tell
- navigator.maxTouchPoints and pointer consistency
- navigator.platform and oscpu on a spoofed OS
- navigator.vendor and productSub: the Firefox tells
- Accept-Language header vs navigator.languages
- window.devicePixelRatio: the pref that spoofs it
- Can you be fingerprinted in incognito mode?
- Is changing the user agent enough to avoid detection?
- Can a website tell you are running on a server?
- Can two devices share a browser fingerprint?
- Does clearing cookies stop fingerprint tracking?
- Color-gamut and HDR media queries as a fingerprint
- Battery API fingerprint: does Firefox expose it?
- Is navigator.connection a fingerprint in Firefox?
- Can the Gamepad API fingerprint or detect a bot?
- Do accelerometer and gyroscope APIs leak on desktop?
- prefers-reduced-motion and other OS-setting tells
- Does storage quota estimate reveal disk size?
- Can scrollbar width reveal my operating system?