Worker navigator matches the main thread
Check id worker-navigator-coherence
What an ordinary browser yields
Worker and main thread report identical platform, hardwareConcurrency, webdriver and UA.
What a detector infers
A Blob-URL Worker is spawned and reports its own navigator.platform, navigator.hardwareConcurrency, navigator.webdriver and navigator.userAgent; the check compares each against the main thread (webdriver via Boolean coercion, userAgent only when the worker returned one). A WorkerGlobalScope is a separate execution context with a WorkerNavigator supplied straight from the engine — page scripts never run there, so anything patched on the document's navigator simply does not exist in the worker. A detector reading both sides sees one browser reporting two different identities for the same immutable facts, which is not a state a genuine browser can occupy; the divergence localises the spoof to the main thread. The probe is memoized and shares one worker with the WebGL worker check; if it times out (4s) or errors, the check reports N/A and is not scored.
How to resolve it
Apply identity values at the engine level so WorkerNavigator is constructed with the same values as Navigator. If you must stay in userland, the same override has to be installed in every worker scope too — which is unreliable for Blob and module workers and still leaves the descriptor and toString artifacts the other checks read.
Read in the wild by
CreepJS
CreepJS, an open-source fingerprinting research demo rather than a production detector, ships a worker probe that reports its own navigator and compares platform, userAgent, deviceMemory, hardwareConcurrency and languages against the main thread, setting its `lied` flag on divergence.
abrahamjuliot/creepjs, src/worker/index.ts (getWorkerData) destructures `hardwareConcurrency, language, languages, platform, userAgent, deviceMemory` from the worker scope's `navigator || {}` (lines 164-171) and returns them (lines 228-236). src/navigator/index.ts declares `export default async function getNavigator(workerScope)` (line 9) and compares them back against the main thread — line 51: `if (platform != workerScope.platform) {` / `lied = true // documented in the worker source`; same pattern at line 84 (userAgent), 134 (deviceMemory), 187 (hardwareConcurrency), 207 (language), 215 (languages). Neither file contains the string `webdriver` (grep: 0 hits in both), so the worker probe does not compare it.
Every attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Native function integrity
- Function.toString not proxied (native code)
tostring-nativeThe check stringifies two functions and requires both to match /\{\s*\[native code\]\s*\}/: Function.prototype.toString itself (read as… - navigator props resolve via native prototype getters
navigator-descriptorsFor deviceMemory, hardwareConcurrency, language, languages and platform, the check reads the property descriptor twice. - key native functions are untampered (toString + no prototype)
native-integrityThis runs a battery over roughly forty engine-owned callables — canvas, WebGL, navigator, iframe, shadow-DOM and fetch natives, plus the JS… - a fresh iframe (contentWindow) matches the main realm
iframe-coherenceThe check appends a hidden same-origin iframe to documentElement and reads its contentWindow — a brand-new JavaScript realm with its own… - page-world natives that extensions commonly wrap
page-world-wrappersThis probe stringifies window.fetch and window.Request and asks whether each still renders as native code, then checks whether document… - nonexistent navigator properties return undefined
navigator-proxy-honeypotThis reads five navigator property names that exist on no browser — rml, ln, rnd, webdriverPatched and __clearcoteProbe — and additionally… - native methods enforce their C++ receiver check
native-brand-checksTwo native methods are invoked with their own bare prototype as the receiver… - iframe srcdoc/src/contentWindow live on the prototype
iframe-srcdoc-placementA fresh <iframe> is created with document.createElement and inspected for own property descriptors on srcdoc, src and contentWindow.
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 Native function integrity 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 Native function integrity — the family worker-navigator-coherence belongs to.