Skip to content
All fingerprint checksNavigator identity

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.

Anatomy of a browser fingerprint: every signal, and why they must agree

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

See all 26 checks in Navigator identity
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 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.