Where the entropy comes from
Set an element to size itself to a string of text and measure it. The width is not a round number: it is the sum of the advance widths of every glyph, computed after font selection, hinting, and sub-pixel positioning. Change the font file, the rasteriser, or the platform text-shaping library and the fractional part of that sum changes with it.
This gives DOMRect measurements a useful property from a detection standpoint - they are a proxy for the font and rendering stack that does not require enumerating fonts directly. A probe can render a handful of strings in a handful of font stacks, read the resulting rects, and hash the fractional components. The result correlates strongly with the operating system and its installed font set without ever asking which fonts are present.
Several other APIs expose the same underlying geometry through different objects: getClientRects() returns the individual boxes of a fragmented inline element, a Range over the same text returns its own rects, IntersectionObserver reports a bounding rect for an observed element, and SVG exposes a screen coordinate matrix. All of them are computed from one layout, which is what makes the surface interesting for coherence work as well as for entropy.
Why perturbation is unusually hard here
Because rect values are arithmetically related to one another, small random offsets added to defeat hashing create contradictions rather than noise. The relationships a probe can test are simple and exact:
- Bounding rect against Range rects - the bounding box of an element must be consistent with the rects of the text inside it.
- Layout box arithmetic -
clientWidth,offsetWidth, and the computed style width, padding, and border are related by a documented formula. The rect must satisfy it. - Origin anchoring - an element positioned at the document origin must measure its own origin as zero. A perturbed rect puts it near zero instead.
- Observer agreement - the rect reported by
IntersectionObserverdescribes the same element asgetBoundingClientRect()and must match. - Advance additivity - a string of N identical glyphs must measure N times the width of one, within rounding. Independent noise per measurement breaks the proportion.
This is the same lesson that appears in canvas and WebGL readback: the check is not "is this value rare" but "is this value arithmetically possible". Uniform per-session offsets applied consistently to every geometry API can preserve the relationships, but doing so requires the perturbation to live below the layout engine rather than in front of the JavaScript API - which is the difference between an engine-level implementation and a patched accessor that integrity checks can see directly.
How much it actually matters
DOMRect entropy is real but modest, and it overlaps heavily with signals a probe is already collecting. If font fingerprinting, canvas text metrics, and platform oracles are all being read, the incremental information from layout geometry is small - it mostly confirms what those already said.
Its practical importance is therefore as a consistency check rather than an identifier, and as a trap for perturbation applied at the wrong layer. A configuration that returns clean, self-consistent geometry matching its declared platform passes without the surface ever mattering. One that adds noise to getBoundingClientRect alone announces that something is intercepting measurement, which is a stronger signal than the layout hash it was trying to suppress.
The straightforward path is to render honestly on a real platform with a normal font set, and let the geometry be whatever the layout engine computes. Managed browser infrastructure does this by default, so the relationships hold without any perturbation strategy to get right.