navigator.appVersion is the user agent minus its leading token
Check id appversion-vs-useragent
What an ordinary browser yields
On Blink and WebKit, appVersion is byte-for-byte the user agent minus its leading "Mozilla/". On Gecko the check reports N/A, because that engine does not mirror the UA there.
What a detector infers
navigator.appVersion is not an independent fact. In Blink and WebKit it is computed from the User-Agent at read time — literally the UA with everything up to the first slash removed — so it is the same sentence with eight characters missing. Overriding navigator.userAgent from page script replaces one reader and leaves the other quoting the original build, which is why a spoofed UA is so often betrayed by the property nobody remembers exists. PerimeterX collects both readers in one payload, next to productSub, platform and the rest of the NavigatorID surface, and lets the pair speak for itself. The check goes quiet on the entire Gecko family, and that restraint is the interesting part: Firefox deliberately answers a truncated form like "5.0 (Windows)" and does not mirror the UA at all, so there is nothing to compare and the honest move is silence. That includes Firefox with a UA override or a UA-switcher addon — the check simply has no power there, which is the price of not false-positiving. It was nearly built the looser way, asserting that appVersion's platform token must prefix the UA's; browser testing killed that variant, because Firefox for Android in desktop mode serves a Linux user agent while appVersion keeps saying Android, and one tap on an ordinary phone would have thrown a critical.
How to resolve it
Set the user agent at launch, or through the browser's own override, so every reader derives from one source. Assigning navigator.userAgent moves one reader and leaves appVersion — computed from the real UA when you read it — quoting the build underneath. A Chrome-family UA-switcher extension produces exactly this shape, so seeing it here does not necessarily mean automation; it means two readers of one fact disagree.
Read in the wild by
Kasada
Kasada's fingerprinting script reads navigator.appVersion and navigator.userAgent into separate slots of its payload, and collects the pair twice — once from the page's own window and once from an iframe's contentWindow.
blog.txt:666-684 (emro.cat Kasada ips.js teardown, solver output "mapped: 427/427 probes") assigns four distinct payload slots: "124:window_navigator_app_version(fn_129709)", "171:window_navigator_user_agent(fn_177174)", "263:iframe_navigator_app_version(fn_9673)", "146:iframe_navigator_user_agent(fn_169577)". Corroborated in the decompiled IR (1.txt), where each is a probe function reading off one of two realm handles: 1.txt:1296-1297 "r5 = a0.lrc; r5 = r5.navigator.appVersion;"; 1.txt:37347-37348 "r5 = a0.lrc; r5 = r5.navigator.userAgent;"; 1.txt:45469 "r4 = r4.kcm.navigator.appVersion;"; 1.txt:47972-47973 "r4 = r4.kcm.navigator; return r4.userAgent;". The lrc/kcm handles are the batch-context realm pair built at 1.txt:24390-24394 "r4 = { lrc: _882, kcm: r6 };" beside "_912.contentWindow"; blog.txt documents the structure as a batch context storing "a reference to window under .exg and a reference to an iframe's contentWindow under .ukz". (probes.txt lines 164/167/391/394 list the same four names, but is a derived index of this solver output.)
PerimeterX / HUMAN
Collects navigator.appVersion and navigator.userAgent as two separate fields in the same payload, alongside product, productSub, appName and platform, and ships both raw — a deployed collector sends the user agent and the user agent minus its leading "Mozilla/" as independent values.
PerimeterX main.min.js on ifood.com.br: `t[0][hQ(855)]=hU[hQ(856)]` with hQ(855)="PSkIY3hPC1U=" and hQ(856)='appVersion', a few statements from `t[0]["RBBxWgJydmw="]=hU[hQ(845)]` with hQ(845)='userAgent' — in the same `t[0]` collection block as `t[0][hQ(851)]=hU[hQ(852)]` (product), `t[0][hQ(853)]=hU[hQ(854)]` (productSub), `t[0]["NkZDDHArQz8="]=hU.appName` and `t[0][hQ(844)]=hU.platform`. Decoded EV2 payload carries both keys in one object: "PSkIY3hPC1U=" = "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36" beside "RBBxWgJydmw=" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36".
Every attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Navigator identity
- navigator.vendor is the constant the measured engine compiles in
navigator-vendor-vs-enginenavigator.vendor is not a preference or a setting — it is a string constant compiled into the engine. - navigator.oscpu names the same OS family as the user-agent
ua-oscpu-os-family-coherencenavigator.oscpu is a property only Gecko still exposes — Chromium removed it and WebKit never had it — so this check is silent on every… - a worker resolves the same IANA timezone as the main thread
worker-main-timezone-coherenceA browser has one host timezone, and the specification ties both the main-thread global and every worker global to it, so a real browser… - the keyboard layout maps the OEM keys the way one real Windows layout would
keyboard-layout-single-originA keyboard layout is not a set of independent key mappings — it is one artifact the operating system hands over whole. - Trusted Types hands back the branded object its own type demands
trusted-types-value-invariantTrusted Types is a typed API, not a boolean feature flag, and that is the whole of the check. - the user agent on the wire and the one JavaScript reports describe the same browser
ua-wire-vs-navigatorYour user agent is asserted on two channels built by different layers: the network stack writes the header, and the renderer answers… - a Date's own text agrees with the Date's own offset
date-tostring-coherenceA Date's text is not opaque. ECMA-262 defines toString() as toDateString() + " " + toTimeString(), fixes the weekday and month tables to… - Origin-scoped storage and browsing state
origin-storage-historyCookies, storage, IndexedDB, and same-tab history reveal only this origin's state.
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 Navigator identity 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 Navigator identity — the family appversion-vs-useragent belongs to.