iframe.contentWindow really is a separate realm, and the one the browser says it is
Check id contentwindow-realm-identity
What an ordinary browser yields
contentWindow is a distinct realm with its own intrinsics, its top and parent are this window, it is strictly identical to the frame the indexed getter yields, and it names this origin as its ancestor.
What a detector infers
This is the check that guards the others. A large part of this audit — the global property diff, all six capability surfaces, the brand hints, the shadow DOM probe, the iframe scalar comparison — reaches through iframe.contentWindow and trusts that what comes back is a genuinely separate realm the browser built from its own binary. That trust has exactly one countermeasure, and it defeats every one of those checks simultaneously: stub contentWindow to return the MAIN window. Every cross-realm comparison then compares the page against itself, agrees trivially, and the whole suite reports green. So contentWindow has to be verified — and it cannot be verified using contentWindow. The way out is the WindowProxy indexed getter. window[0], window[1] and so on are backed by C++ on the Window object itself, are not configurable from JavaScript, and are the one handle on a child frame that a page-world patch cannot intercept. The check fetches the frame both ways and requires strict identity between them; it also requires the realm to own distinct intrinsics (its own Object, Array and navigator, because a realm that shares ours is not a second realm), to report this window as its top and parent, to name our iframe element as its frameElement, and to name this page's origin in its own ancestorOrigins. Every index is scanned rather than assuming zero, because the page has other frames — a chat widget, an ad slot — and this audit creates several of its own, so the position is not fixed; only the identity is. Note what is deliberately never compared here: values. Brave's farbling, Firefox's resistFingerprinting and Safari's ITP all rewrite values and none of them touches realm identity, which is what makes this check structurally immune to them.
How to resolve it
Do not stub or wrap HTMLIFrameElement.prototype.contentWindow. Returning the parent window from it is the single edit that would make every cross-realm comparison on this page agree at once — which is precisely why the frame is also fetched through window[i], a C++ getter that page script cannot shadow, and the two objects are required to be the same one.
Read in the wild by
Kasada
Stores an iframe contentWindow under an obfuscated key and reads the frame's ancestry back, so a stubbed contentWindow does not silently satisfy every cross-realm probe it runs.
window_parent_origin, window_top_origin, ancestor_origins
Kasada ips.js teardown — the full 427-probe listEvery attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Native function integrity
- Worker navigator matches the main thread
worker-navigator-coherenceA Blob-URL Worker is spawned and reports its own navigator.platform, navigator.hardwareConcurrency, navigator.webdriver and… - 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. - Element.attachShadow untampered (shape + closed/open behaviour)
shadow-dom-integrityThe check reads Element.prototype.attachShadow four ways and asserts they agree: its name is "attachShadow", its length (declared parameter… - Math.random / crypto.getRandomValues native and high-entropy
rng-integrityThe check verifies that Math.random is the engine's native generator and that its output is high-entropy. - the global object still has every global a fresh realm has, in the same order
window-globals-vs-realmThe audit builds a fresh same-origin iframe and enumerates the own properties of both global objects, then asserts two things a browser…
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 contentwindow-realm-identity belongs to.