AntiDetect
Features Technology Pricing Who's It For
Docs Blog FAQ
Download

A Fingerprint Is a Story, Not a List

Detection systems stopped scoring signals one at a time years ago. What they check now is whether your signals agree with each other — and a profile assembled from a menu of independent dropdowns almost never does.

The shift from values to relationships

Early fingerprinting was a checklist. Collect canvas, WebGL, fonts, screen size, timezone; hash them together; compare the hash. If it matched a known-bad value, block.

That approach is long dead, for a simple reason: it was easy to beat by changing values. What replaced it is cross-attribute correlation — instead of asking what each value is, the system asks whether the values could belong to the same computer.

This changes the difficulty enormously. Faking one value is trivial. Faking forty values that all imply the same machine is a modelling problem, and it is the problem most anti-detect setups fail, because their interface invites you to pick each field independently from a dropdown.

You are not trying to produce an unusual fingerprint. You are trying to produce an unremarkable one — a plausible description of an ordinary computer that happens not to be yours.

The contradictions that get checked

These are the correlations that show up most often in real detection logic. None is exotic; all are cheap.

GPU versus platform

Your WebGL unmasked renderer string names an actual chip and an actual driver path. ANGLE (Apple, Apple M2, OpenGL 4.1) is a Mac. ANGLE (NVIDIA, NVIDIA GeForce RTX 4070 Direct3D11 vs_5_0 ps_5_0, D3D11) is Windows — Direct3D does not exist elsewhere. A user agent claiming macOS alongside a D3D11 renderer is not a rare device; it is an impossible one.

GPU versus screen

A machine with an M-series GPU and a 1366×768 screen at devicePixelRatio 1 does not exist — Apple has not shipped that panel in the relevant era. Integrated graphics from a decade ago paired with a 3840×2160 display is similarly unlikely. Detection vendors hold distribution tables for exactly these pairs.

Fonts versus operating system

Font sets are OS signatures. Segoe UI ships with Windows. SF Pro and Helvetica Neue with macOS. Ubuntu and the Liberation family with common Linux distributions. A "Windows" profile that cannot render Segoe UI has failed a check that costs the tracker one measureText call. The font surface deserves its own treatment, and gets it.

Timezone versus IP

The most common failure of all, and the least technical. Intl.DateTimeFormat().resolvedOptions().timeZone returns what the browser thinks it is; the IP says where the connection comes from. A Brazilian residential IP with Europe/Rome is a mismatch any junior engineer would flag. Worse, the browser also exposes the raw getTimezoneOffset(), so a profile that spoofs the IANA name but not the offset contradicts itself without any external data at all.

Language versus everything

There are three language surfaces and they are frequently set in only two places: the Accept-Language HTTP header, navigator.languages in JavaScript, and the locale the Intl API resolves to. We have seen live profiles announcing it-IT from JavaScript and en-US,en;q=0.9 in the header at the same time. That is a configuration error visible in a request log.

Hardware numbers versus device class

hardwareConcurrency and deviceMemory should describe a machine someone actually bought. deviceMemory is quantised by the spec to 0.25, 0.5, 1, 2, 4, 8 — a value of 6 is not merely unusual, it is out of spec. Sixty-four logical cores paired with 4 GB of reported memory describes nothing on the market.

Touch versus form factor

maxTouchPoints > 0 on a desktop user agent, without a corresponding touch-capable device profile, is a common leftover from copying a mobile fingerprint. So is a mobile user agent with a 1920×1080 screen and a mouse pointer.

Two-column table of claimed values against the values they imply, with two mismatches marked
Six pairs, four of which agree. The two marked describe a machine that cannot exist — and neither needs any external data to spot.

The two-context check

Beyond pairwise plausibility there is a stricter test, and it is the one that ends sessions: ask the same question in two places and compare.

The browser exposes several execution contexts that should all describe the same machine — the main window, a Web Worker, an iframe, and a Service Worker. A page-level override typically reaches only the first. Detection scripts read hardwareConcurrency, deviceMemory, platform, userAgent and the WebGL strings from a worker and diff them against the window.

There is no innocent explanation for a disagreement. It is not a heuristic with a false-positive rate; it is proof. This is the strongest argument for handling fingerprints in the engine rather than in an injected script, and it is covered in more depth in the CDP article.

Where random profile generators go wrong

Tools that generate a "random fingerprint" usually sample each field independently from a list of plausible values. Every individual field looks fine. The combination is often absurd.

Independent sampling produces a Mac GPU with a Windows font set, a 4K screen on integrated graphics from 2014, or a Chrome 147 user agent with a userAgentData brand list from Chrome 131. Each value passed its own validation; the machine described does not exist.

The fix is to sample the machine, not the fields. Start from a real device archetype — say, a 2023 ThinkPad with Iris Xe graphics, 16 GB of RAM, a 1920×1080 panel and a Windows 11 font set — and derive every value from it. Vary within the archetype's realistic range, never across archetypes.

A useful test of any tool: create ten profiles and read their WebGL renderer and their platform. If you can get an Apple GPU next to Win32, the generator is sampling fields.

Ordinary beats unique

A last point that runs against instinct. Uniqueness is not the goal. A fingerprint that matches nothing on record is itself a signal — it means the tracker has never seen this configuration, which is not what an ordinary user looks like.

The comfortable place is the middle of the distribution. A 1920×1080 screen, 8 or 16 GB of RAM, 8 logical cores, a mid-range GPU, the default font set for the OS, and a timezone that matches the exit IP. Boring in every dimension, and shared with millions of other machines.

Resist the temptation to pick impressive hardware. A 32-core workstation with 128 GB of RAM is memorable, and memorable is the opposite of what you want.

A checklist you can run

Before putting a profile to work, verify these in order. Any single failure is worth fixing before you continue:

  1. IP geolocation, timeZone and getTimezoneOffset() all point to one place.
  2. Accept-Language, navigator.languages and the resolved Intl locale agree.
  3. The WebGL renderer names a chip that ships with the platform in the user agent.
  4. The font list is the default set for that OS version, plus nothing exotic.
  5. Screen resolution and devicePixelRatio describe a panel that shipped with that GPU class.
  6. deviceMemory is a legal value and hardwareConcurrency is plausible beside it.
  7. A Web Worker returns the same values as the window.
  8. The canvas hash is stable across renders and across sessions — see why that matters.
  9. WebRTC does not report an IP other than the proxy's. This one leaks silently.
  10. navigator.userAgentData brands match the Chrome major version in the user agent string.

CreepJS will do most of this for you and will say plainly which pairs it considers inconsistent. Run it once per profile template, not once per profile — if the template is sound, the profiles derived from it will be too.

Profiles built from real device archetypes

P8 generates each fingerprint from a coherent hardware profile, so the GPU, fonts, screen and platform describe one machine instead of four.

Start for Free
All articles Next: Canvas Noise Is a Fingerprint of Its Own