the user agent on the wire and the one JavaScript reports describe the same browser
Check id ua-wire-vs-navigator
What an ordinary browser yields
The user agent our server received is byte-identical to the one this page reports — or is that string with a proxy's token appended, which is ordinary.
What a detector infers
Your user agent is asserted on two channels built by different layers: the network stack writes the header, and the renderer answers navigator.userAgent. A detector gets the join for free — PerimeterX HMACs the JavaScript-side string and lets its edge compare the result against the header it actually received, which is why the reverse-engineering study's recurring symptom is an HMAC computed perfectly and rejected anyway. An override applied in only one place is a self-contradiction that costs the detector nothing to find. There is no client-only way to run this check: User-Agent is a forbidden header name, attached below JavaScript, so not even a ServiceWorker's FetchEvent can see what was really sent — the server has to echo back what it received. The shape of the difference carries the meaning, and the check is built around that rather than around a verdict. A TLS-inspecting corporate proxy — Zscaler, Netskope, Blue Coat — APPENDS a product token to the outbound header while navigator.userAgent, which never leaves the renderer, stays clean. That is common in exactly the enterprise and VDI population an audit must not flag, so an appended token is reported as what it is. A platform group that disagrees is a different claim entirely: a middlebox does not turn Windows NT into Linux. The row is unscored for now on purpose — if a CDN in front of this site ever normalises the user agent before we see it, the check would fire for every visitor, and that would be our infrastructure rather than their browser.
How to resolve it
Set the user agent at a layer that owns both channels: at launch, or through the browser's own override, both of which move the header and the renderer together. Assigning navigator.userAgent from page script moves only the one the network never sees.
Read in the wild by
PerimeterX / HUMAN
PerimeterX's collector reads navigator.userAgent into its encrypted EV2 body as field "RBBxWgJydmw=", and feeds that same UA string as the message into its HMAC-MD5 fields — HMAC(uuid, UA) unconditionally, plus HMAC(state.vid, UA) and HMAC(state.pxsid, UA) when those identifiers are present. The reverse-engineering study records that this UA must be byte-identical to the request's own User-Agent header, and lists "HMAC fields computed correctly but still rejected" as the signature of a mismatch between the two.
EV2 "RBBxWgJydmw=" = navigator.userAgent — /root/re/PerimeterX_RE/stample/ifood/source/main.min.js: `t[0][hQ(844)]=hU.platform,t[0][hQ(714)]=hU.languages,t[0]["RBBxWgJydmw="]=hU[hQ(845)]`, with bug_report/sdk_drift_cases/2026-05-19_ifood/hQ_map.json:847 `"845": "userAgent"` (hU=navigator by adjacency); decoded value in ev2_template.json:158 = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Chrome/148.0.0.0 Safari/537.36". HMAC fields — main/EN/EV1_EV2_UNIFIED_REFERENCE.md §D table: HMAC(uuid, UA)=`M2MGKXUOBB8=`, HMAC(state.vid, UA)=`FmYjbFAEJVg=`, HMAC(state.pxsid, UA)=`BzdyfUFRd04=`; latter two conditional per source `("FmYjbFAEJVg="] = iR(r, n)); var h = qf(); h && (e["BzdyfUFRd04="] = iR(h, n))` and validated-sites.md:52 (marked 条件); iR=HMAC / oB()=uuid / t=UA per skill/AI_re/playbooks/locate-field-sources.md:219 `d["M2MGKXUOBB8="] = iR(oB(), t)`. UA/header consistency — EV1_EV2_UNIFIED_REFERENCE.md:134: "⭐ UA must equal the HTTP `User-Agent` header (gotcha #9). Changing the UA string requires changing both places in sync"; :207 gotchas index: "| HMAC fields computed correctly but still rejected | gotcha #9 (UA consistency) |"; root cause at skill/AI_re/references/gotchas.md Bug #9: "HMAC(uuid, UA) 的 UA 和 HTTP `User-Agent` header 必须字符串完全相同" (the UA in HMAC(uuid, UA) and the HTTP User-Agent header must be exactly identical strings).
Every attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Navigator identity
- 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. - navigator.appVersion is the user agent minus its leading token
appversion-vs-useragentnavigator.appVersion is not an independent fact. In Blink and WebKit it is computed from the User-Agent at read time — literally the UA with… - 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. - 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. - Profile age and cross-site history boundary
profile-age-boundaryPrivacy boundaries prevent reading global history or true profile age. - Account reputation boundary
account-reputation-boundaryAccount reputation needs authentication and server history, neither of which this public audit has.
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 ua-wire-vs-navigator belongs to.