Hiding is the wrong goal
The instinct behind most anti-detect tooling is to hide: override navigator.webdriver, randomize the canvas hash, strip the automation flag. Each of these treats detection as a checklist of individually suspicious values to suppress.
But modern detection isn't a checklist of "unusual values." It's a consistency test. It reads dozens of signals together and asks a single question: do these agree with each other, and with a real device? A browser can be perfectly ordinary on every individual axis and still fail because two axes contradict.
Incoherence is the tell
Consider a session that claims to be Chrome on Windows in its User-Agent, but whose UA Client Hints say something else, whose timezone doesn't match its IP geolocation, and whose TLS handshake is a version Chrome never shipped. No single value is alarming. The combination is impossible.
This is why naïve spoofing can make things worse. Randomizing the canvas every read produces a value that changes when a real device's would stay stable — a signal that didn't exist before the spoof. The safest fingerprint isn't the rarest or the noisiest; it's the one where every part corroborates every other part.
The practical bar, then, is not "be invisible." It's "be a plausible, self-consistent machine." Consistency-checking tools make this concrete: they cross-reference UA against UA-CH, workers against the main thread, and flag exactly these disagreements.
Coherence has to survive re-checking
A value is only coherent if it stays coherent when the page looks again, from somewhere else. Two kinds of re-checking break most JavaScript spoofs:
- Across realms. A detector can spawn a fresh iframe or a Web Worker and re-read a property from that pristine context. If the override only patched the main window, the worker reports the real value — and the disagreement is the signal.
- Down the stack. JavaScript can claim anything, but the TLS ClientHello and HTTP-2 frames underneath are emitted by the network layer, not the page. If the JS identity and the wire don't match, no amount of JavaScript can reconcile them.
This is why durable approaches move identity control into the engine itself. When the getter is native in every realm and the network layer follows the same persona as the JavaScript, there's no seam to cross-check — the browser is coherent all the way down rather than papered over on one surface. Clearcote is one open-source implementation of this idea; the detection breakdown covers the mechanics.
What this means in practice
Designing for coherence changes what you optimize. Instead of a pile of independent toggles, you derive every signal from one seed so they move together; instead of hiding automation, you simply don't create the artifacts; instead of a fixed "safe" value, you keep the natural per-connection variation a real browser has.
It also changes what "more stealth" means. Adding another spoofed value is only an improvement if it stays consistent with everything else — otherwise it's another axis a detector can catch you on. Coherence is the constraint that turns a collection of tricks into a believable identity.