Skip to content
All fingerprint checksEngine & OS oracles

typefaces the claimed OS ships as separate faces measure as separate faces

Check id claimed-os-typefaces-are-distinct

What an ordinary browser yields

Every probed typeface belonging to the claimed operating system measures a distinct advance width, because separate faces have separate metrics. Declined entirely under a Linux claim, which ships no universal face set, and declined when the metrics are flattened or a nonexistent face resolves.

What a detector infers

A font request is answered by the host's font stack, not by the browser and not by anything the user agent sets, so changing navigator.platform does not move a single glyph. That makes the font layer an OS oracle — but the obvious way to read it does not work, and the reason is worth stating because it is what shapes this check. Asking whether a named Windows face such as Segoe UI or Calibri is INSTALLED returns yes on a Linux machine that has none of them: fontconfig ships metric-compatible substitutions, mapping Calibri to Carlito and Cambria to Caladea, and those clones are built to match the original's advance widths exactly. Measured on stock Chromium on Linux, Calibri and Carlito both render a probe string at 853.559px, and Segoe UI returns 914.273px — the identical value a real Windows Chrome returns. A substitute designed to match the original's metrics cannot be detected by measuring the original's metrics, so no width table and no presence test can see it. What a substitution scheme cannot do is provide a distinct clone for every face. Faces without one fall back to the platform default and therefore collide WITH EACH OTHER: on that same Linux host, Tahoma and Arial both measure 905.203px, because Tahoma has no substitute and lands on the default sans-serif that Arial already maps to. On Windows those are two different typefaces and cannot share an advance width. So this row asks a self-referential question — do faces the claimed operating system ships as SEPARATE typefaces actually measure separate here — and it carries no expected widths at all, which is what keeps it from rotting when a font version changes. Two refusals are built in and both were measured rather than reasoned about. First, collapse onto a generic is never scored: on Windows Chrome the default monospace IS Consolas and the default sans IS Arial, so `Consolas === monospace` and `Arial === sans-serif` are true on a genuine Windows machine, and a check reading that as a missing font would fail every real Windows browser. Only collisions between two non-default named faces count. Second, a browser that defeats font enumeration flattens every metric, and pervasive collision is that defence rather than an OS lie — so the row requires a majority of the probed set to be mutually distinct before it will assert, and declines on a flattened palette. A face that does not exist is probed as a control; if it resolves to its own metrics the browser is answering synthetically and the whole reading is discarded.

How to resolve it

Font metrics come from the host's font stack, below anything the user agent controls, so a persona presenting another operating system carries the wrong ones no matter what it reports. A metric-compatible substitute hides the faces it covers — that is its purpose — but it cannot cover the whole set, and two different typefaces answering with one advance width means one of them fell back. The complete answer is to run on the operating system being claimed; a captured font profile is the partial one, and it has to supply the entire face set rather than the few names an open substitute package happens to clone.

What is font fingerprinting?

Read in the wild by

FingerprintJS

Its open-source font entropy source measures a probe string in each candidate face against the three generic base fonts and treats a difference in width or height as the face being present. That is the same measurement this row takes; the difference is what is done with it. FingerprintJS keeps the resulting presence vector as an identifier, whereas this row discards it — because, as measured here, the presence answer is wrong on Linux for exactly the faces a Windows persona would be asked about — and reads only whether two faces collide with each other.

src/sources/fonts.ts: a fixed font list measured span-by-span against monospace, sans-serif and serif base fonts, presence recorded when the rendered size differs from the base.

FingerprintJS (open-source agent)

Clearcote (measured)

Not a sighting of a vendor reading it, but the measurement that motivated the row, and the product's own documentation agrees. The SDK prints an unprompted warning when a Windows persona is requested on a Linux host: font, canvas and font-list hashes will be host-native and will not match a real Windows Chrome. Measured against that build, every probed font width under platform="Windows" was byte-identical to stock Chromium on the same host — the persona does not touch the font layer at all, exactly as the warning says.

Clearcote PRO 150.0.7871.114 on Linux, platform="Windows": Tahoma 905.203 = Arial 905.203 (collision); identical widths to stock Chromium on the same host across all probed faces. Real Windows headed Chromium: six named faces, zero pairwise collisions.

clearcote SDK launch warnings (_warnings.py)

Every attribution traces to a published artifact. See the sources and their limits.

Other checks in Engine & OS oracles

Who builds this test

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 Engine & OS oracles 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 Engine & OS oracles — the family claimed-os-typefaces-are-distinct belongs to.