Browser fingerprint test: Can your browser fool me?
I read your browser in JavaScript, then ask the network layer what it actually saw. A browser controls its own JavaScript; it does not control the network it connects over. Every disagreement is a finding - and then I check whether a hand is driving you at all.
Provisional, and 8 points short: a coherent environment still does not prove a hand is here. Hit Human challenge and keep the pointer moving for a few secondsdrag a finger around this page for a few seconds - no clicking or tapping needed. How I score you ↓
- Your IP
- …
- Timezone
- …
- WebRTC
- …
Your live scan. Every check below is computed in your browser right now.
- WebRTC leak testAsks a public STUN server for your address and compares it with the IP this connection came from.
- Bot detection testOnly the automation axis: webdriver, framework residue, DevTools-protocol traces and headless tells.
- Headless browser detection testThe checks that tell headless Chrome from a windowed one: UA token, browser UI height, software GPU, empty device list.
- Canvas fingerprintDraws the same canvas twice and compares the reads; noise that changes between them is a spoof. Runs in the scan above.
- WebGL and WebGPUTwo independent views of your GPU, which must name the same chip. Runs in the scan above.
- FontsChecks that the fonts your browser lists can actually be measured on this host. Runs in the scan above.
- Timezone vs IPBrowser clock against the timezone of the IP the edge saw. Runs in the scan above.
- TLS and HTTP versionWhat the handshake negotiated, read at the edge where JavaScript cannot reach. Runs in the scan above.
The score is internal coherence, and it is not a ban prediction. It starts from one question: does this browser's JavaScript story agree with itself, and with what the network layer saw? A coherent story is not proof that a person is here, so the challenge next to the score asks the second question directly, and until you answer it the score stays provisional.
Detection runs on three separate axes, and they fail independently.
- Fingerprint · does this look like a real device? Canvas, WebGL, WebGPU, audio, fonts, timezone, the plugin face. measured here
- Network · does the wire agree with the page? TLS version, HTTP protocol, ASN, header shape, exit-IP geography. measured here
- Automation · is a program driving this browser? Passively:
navigator.webdriver, a removedwebdriverproperty, framework residue, headless GPU and device tells. Then by challenge: coalesced pointer samples, path curvature, event timing.measured here
Two things are worth being blunt about. First, the behavioural layer runs only on liarjs.dev: the open-source package ships the passive probes, not the challenge. Second, a completely unpatched, headed Chrome has nothing inconsistent about its environment. Stock Playwright and Puppeteer still give themselves away on this site, because the DevTools domain they switch on for every page leaves traces I can read. A driver that never switches it on leaves none, and the passive layer may well find nothing. That is exactly why the challenge exists, and why a score you never verified stays provisional instead of turning green. Why the axes are orthogonal →
The checks above are an open-source package. Point it at a browser you're building (a patched Chromium, a stealth automation stack, an anti-detect profile) and get the same score with an exit code, in CI, before a silent regression becomes a ban rate.
npx liarjsHow each of these dimensions actually works, one at a time, from reverse-engineering real detectors and testing real anti-detect browsers.
- Fingerprinting the fingerprinters: telling which anti-bot a site runs
- WebAuthn as a fingerprint: platform authenticators and the capability map nobody reads
- What 32 detectors actually read: reverse-engineering the probe list
- The runtime underneath: heap limits, clock grain and the numbers V8 leaks
- The anti-detect browser Royal Rumble: what independent testing says vs the marketing
- Emoji are an operating system: rasterisation, ZWJ sequences and the font you cannot ship
- Detection strength is the vendor stack: Kasada, Akamai, DataDome and the ladder
- getLayoutMap(): the physical keyboard as an OS and region signal
- WebRTC IP leaks: ICE candidates, mDNS and the public-IP mismatch
- Beyond width: the other eleven numbers TextMetrics gives you
- The layer JavaScript never sees: TLS, JA3/JA4 and HTTP/2 fingerprints
- Three majors behind: version lag is a fingerprint of its own
- DOMRect and subpixel geometry: the fingerprint DataDome loves and the dpr trap that breaks spoofers
- Which signal actually blocked you: running a controlled bisect
- Workers and OffscreenCanvas: fingerprinting in the thread you forgot to patch
- The plugin face Android never had: five entries that kill a mobile persona
- The plugin face: modern Chrome's five PDF entries and the version it betrays
- Static says phone, events say mouse: the device-class contradiction
- [native code]: why JS-override stealth loses to engine-level spoofing
- I scored eleven Chromium stealth setups with my own tool. One launch flag ties the libraries, and the most popular plugin loses.
- Mobile texture formats on a desktop GPU: the capability table under the string
- Timezone vs IP: the cross-layer check that catches proxies
- A window cannot be bigger than its screen: the geometry invariants
- Audio fingerprinting: the oscillator, the compressor and why silence must stay silent
- The interface census: an Android persona is a different build, not a different User-Agent
- Named but not measurable: the font check every cross-OS persona fails
- WebGPU, the new GPU oracle: adapter.info and the cross-interface triad
- WebGL fingerprinting: it's the whole parameter set, not just the renderer string
- Automation tells are orthogonal: CDP, Runtime.enable and the isolated world
- Font fingerprinting without a font API: the offsetWidth measurement method
- Inside the CreepJS lie detector: four checks deterministic noise can't beat
- Canvas fingerprinting and the deterministic-noise rule
- Two layers, one browser: why consistency beats any single fingerprint