Skip to content
All fingerprint checksScreen & display

a mobile UA has a real touch stack

Check id touch-createevent-coherence

What an ordinary browser yields

A mobile UA reports maxTouchPoints > 0 and document.createEvent('TouchEvent') succeeds.

What a detector infers

This check asserts in one direction only: if navigator.userAgent matches iPhone, iPad, iPod or Android, then the environment must also have navigator.maxTouchPoints > 0 and a constructible TouchEvent via document.createEvent('TouchEvent'). It does not assert the converse — touch present therefore UA must be desktop — because that would hard-fail real iPadOS desktop-mode Safari and every touchscreen laptop. The createEvent leg is the load-bearing one: it is gated by the engine's internal event-factory table, not by a navigator binding, so no amount of defineProperty on navigator reaches it. A mobile UA with maxTouchPoints=0 or a non-constructible TouchEvent therefore indicates that the user-agent string was changed without the touch stack behind it. Severity is warn; a desktop UA yields N/A.

How to resolve it

Enable real touch emulation at the engine level rather than only swapping the user-agent string. maxTouchPoints can be overridden from JS, but the event-factory table that governs createEvent('TouchEvent') cannot.

How is mobile emulation detected?

Read in the wild by

Kasada

Kasada's collector reads all three inputs this check uses: `touch_event_check` — a `document.createEvent('TouchEvent')` try/catch — is its own payload slot beside separate `window_max_touch_points` and `iframe_max_touch_points` slots, and one function in the decompiled script combines `/iPhone/.test(navigator.userAgent)`, `navigator.maxTouchPoints <= 0`, and whether `createEvent('TouchEvent')` throws into a single reported `verdict`.

Kasada corpus at C:/Users/pim_d/Downloads/cc/antidetect (provider confirmed: 3.txt `{"x-kpsdk-v":"j-1.2.381","x-kpsdk-ct":...}`; `kpsdk` 35x in 2.txt). Probe slots — probes.txt:298 `touch_event_check`, :157 `iframe_max_touch_points`, :385 `window_max_touch_points`; blog.txt 427-probe dump: `batch 1: fn_131858 -> 24 slots [... 323:touch_event_check(fn_134582) ...]`. Probe body — 2.txt func_011263: `try { _944.efg.document.createEvent("TouchEvent"); return true; } catch {...}` (same at 1.txt func_000b8f via `_7507.lrc.document`). Combined verdict function — 2.txt func_0002c8 (also 1.txt func_0240ef, 3.txt @745822): `r6 = new RegExp("iPhone",""); tmp1009 = r6.test(globalThis.navigator.userAgent);` … `r7 = r4["maxTouchPoints"]; r5 = r7 <= 0;` … `try { globalThis["document"].createEvent("TouchEvent"); _7489 = true; } catch {...}` … `return { verdict: _7490, raw: stringify({tpz, dt}), error: false }` where `dt` = the createEvent success boolean. `maxTouchPoints` appears 10x in 2.txt. Our check: knowledge.ts:589.

CreepJS

CreepJS — an open-source research demo rather than a production detector — records touch support in its screen fingerprint via a `hasTouch()` helper that requires both `'ontouchstart' in window` and a successful `document.createEvent('TouchEvent')` construction; it separately reads `navigator.maxTouchPoints` in its navigator module.

src/screen/index.ts:6-11 — `function hasTouch() { try { return 'ontouchstart' in window && !!document.createEvent('TouchEvent') } catch (err) { return false } }`, consumed at src/screen/index.ts:68 as `touch: hasTouch()` in the screen fingerprint. Separately, src/navigator/index.ts:225-230 reads `navigator.maxTouchPoints`. (github.com/abrahamjuliot/creepjs, master)

Every attribution traces to a published artifact. See the sources and their limits.

Nearby checks in Screen & display

See all 15 checks in Screen & display
Who builds this test

Clearcote is a browser built for fingerprint coherence

It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.

This audit takes no position on how Clearcote scores on Screen & display checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.

See the other checks in Screen & display — the family touch-createevent-coherence belongs to.