the markup this page was served with is the markup that reached the DOM
Check id served-markup-integrity
What an ordinary browser yields
The probe subtree arrives with exactly the structure it was rendered with. Anything else means something between this server and your DOM edited the page.
What a detector infers
Every other check on this page asks the browser about itself. This one asks a different question: did the HTML we sent arrive as we sent it? Between a web server and the DOM sit a CDN, sometimes a corporate TLS-terminating proxy, sometimes an intercepting debugging proxy, and every extension the visitor has installed — and several of those rewrite markup as a matter of course. The page renders a tiny, inert, hidden subtree with a known structure, and the run reads that structure back out of the DOM and compares. What makes this worth a row of its own is not that markup rewriting is exotic — it is that it is invisible in every other kind of report, and it is routinely misdiagnosed. A proxy that rewrites HTML on the way through is also rewriting requests on the way out, and request rewriting is a documented cause of otherwise-good CAPTCHA tokens being rejected server-side with no explanation. Someone chasing that spends days auditing their fingerprint, because nothing in a fingerprint report points at the proxy. The technique is in live use on the other side of the fence, too: a deployed CAPTCHA provider computes a locality-sensitive structural digest of the page its widget is embedded in — tag names, attribute names, selected attribute values, text words, and adjacent-tag bigrams — and submits it with the challenge, precisely so it can distinguish a widget running on the real page from one running against a stripped, proxied or replayed copy. The scoping here is deliberately narrow and is the whole reason the check can be trusted: hashing the entire document would disagree for a large share of honest visitors, because password managers, translators and dark-mode extensions legitimately inject nodes into real pages all day. The probe therefore contains no text, no links, no form fields and no class names — nothing any content blocker has a reason to act on. What still moves it is rewriting that does not care what it is rewriting.
How to resolve it
Nothing in the browser to change — this is not a fingerprint property. If it reports a difference, find what is editing the page: disable extensions one at a time on this page, and check whether traffic is going through a TLS-terminating proxy that rewrites content (corporate middleboxes and debugging proxies both do). It is worth tracking down even when nothing looks broken, because the same component that rewrites markup on the way in tends to rewrite headers on the way out, and that is the part a server refuses without telling you why.
Read in the wild by
Prosopo / Procaptcha
The proof-of-work client submits a structural digest of the embedding page's DOM alongside the challenge, tying the widget to the page it claims to be running on rather than a stripped, proxied or replayed copy.
Prosopo/Procaptcha 'headHash': a 128-bit locality-sensitive digest over tag names, attribute names, selected attribute values (href/src weighted), text words and adjacent-tag bigrams, sent with the frictionless session request.
chris-period/procaptcha-pow — page_tags.pyEvery attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Automation surface
- clicks landed on different points, not the same one repeatedly
pointer-landing-dispersionAiming is imprecise. A hand lands somewhere inside a control and the spread shows up within two or three clicks; a driver resolves the… - the button stayed pressed for the whole hold
hold-button-state-coherentThe gate's press-and-hold step asks for a button to be held for over a second, which is two orders of magnitude longer than a click's dwell… - the pointer travelled to each control it pressed
pointer-approach-per-targetThe gate asks for four separate acts in four separate places - three markers, a text field, a slider and a dropdown - and a pointer has to… - the pointer accelerated and slowed on its way to each control
pointer-approach-speed-profileA pointer moved by an arm leaves rest, accelerates, and brakes into its target, so the distance covered between consecutive samples rises… - no automation pointer-flash artifact is present
pointer-flash-keyframe-artifactThe only row on this page that works by recognising a specific string, which needs justifying because a name table is exactly what this… - pageXOffset/pageYOffset match their scrollX/scrollY aliases
scroll-alias-coherencewindow.pageXOffset is not a second scroll position, it is a legacy alias of window.scrollX — the specification defines them as the same… - a focused child frame implies its parent document is focused
document-focus-vs-realmdocument.hasFocus() is true when the document OR any of its descendants holds focus, which makes it hierarchical rather than local: a… - no non-standard shadow-root escape hatch exists on Element.prototype
shadow-escape-hatch-absentClosed shadow roots exist to be unreachable: element.shadowRoot returns null for them, and that is the whole contract.
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 Automation surface 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 Automation surface — the family served-markup-integrity belongs to.