navigator.userAgentData differs between the main thread and a Worker

br.uadata_worker_divergence  ·  convicts

browserlayer
coherencecategory

What it catches

Realm coherence for the User-Agent Client Hints object — the #1 target of OS-spoof tooling. navigator.userAgentData (platform, mobile, brands) is exposed in WorkerNavigator too (Blink), so a main-thread-ONLY patch of it (the standard way a tool fakes the JS-visible platform: Object.defineProperty(navigator,'userAgentData',...)) never reaches Worker scope and diverges. Compares platform|mobile across realms. A page init script (addInitScript / CDP addScriptToEvaluateOnNewDocument) does NOT run in Workers, so a main-only userAgentData override is caught here — the same context-isolation gap as br.languages_worker_divergence / br.devicememory_worker_divergence, extended to the highest-value spoof surface. FP-SAFE by TWO guards: the 'u' sentinel (both realms lacking userAgentData — Firefox/Safari — compare equal → silent) AND the wn.uad !== 'u' gate (fires only when the WORKER actually exposes userAgentData, so a browser whose worker lacks it never false-fires); a real Chromium reports the same platform|mobile in both realms → silent. Convicting (w0.8). GROUNDED LIVE: stealth with a main-only navigator.userAgentData override (KS_SPOOF_UADATA faking platform='Windows') fires uadata_worker_divergence — confirming the Chromium worker DOES expose userAgentData; the un-patched browser is SILENT.

Signals it reads

browser.uadata_worker_divergence

How it fires

present

Bypassed by 10

Frontier evaders that reach the detector uncaught (scored only suspicious, defeating every convicting tell) — this check is not one that stops them. The red-team frontier this detection still has to convict.

← all detections