Dual Login
Technical

Font Fingerprinting: How Sites Detect Installed Fonts

Dual Login Team·2026-08-08·16 min read

Font Fingerprinting: How Sites Detect Installed Fonts

How sites read your installed fonts without asking, why that list is so identifying, and what actually stops it from linking your accounts.

Font Fingerprinting: How Sites Detect Installed Fonts

Install Adobe Creative Cloud and you get roughly 60 fonts you never asked for. Install Microsoft Office, another few dozen. Add a Bengali language pack, a font your accountant sent you in 2019, and the free display face you grabbed for one client project, and your machine now carries a font inventory that almost nobody else on the internet shares. Websites can read most of that inventory in a few hundred milliseconds, without a permission prompt, without a cookie, and without you noticing anything at all.

That is font fingerprinting, and it is one of the oldest, cheapest, and most stubbornly effective techniques in the browser fingerprinting toolbox. This article walks through font fingerprinting and how sites detect installed fonts in practice — the actual measurement tricks, the code patterns detection vendors use, why the resulting signal is so stable, what browsers have done about it, and what genuinely works if you run multiple accounts and need those accounts to not share a font list.

Diagram-style illustration of font fingerprinting showing how sites detect installed fonts by measuring text rendering differences across browser profiles

Why your font list is a fingerprint at all

A fingerprint needs two properties: it must vary between users, and it must stay stable for the same user. Installed fonts score highly on both, which is why they featured in the earliest academic fingerprinting work and still show up in every commercial detection stack today.

Where fonts come from

Almost nobody curates their font list deliberately. It accretes:

  • The operating system ships a base set — and that set differs by OS, by OS version, and by edition. Windows 11 carries fonts Windows 10 doesn't. macOS ships families like Helvetica Neue and Avenir that no stock Windows machine has.
  • Language packs add script-specific fonts. A machine that renders Thai, Tamil, or Traditional Chinese natively carries fonts a monolingual English install never will. Your font list quietly encodes what languages your computer speaks.
  • Software installs fonts as a side effect. Office, the Adobe suite, CorelDRAW, LibreOffice, screen-recording tools, even some games. Each one stamps a recognisable cluster into the list.
  • You add the long tail: the fonts from old design jobs, the one you bought, the five you downloaded from a free-font site and forgot.

The result is that two machines with identical browsers, identical screens, and identical IP addresses can still be told apart purely by which typefaces respond when probed. The Electronic Frontier Foundation's Cover Your Tracks project has measured this for years: the font list routinely contributes double-digit bits of identifying entropy, which in plain terms means it can slice the population of internet users into thousands of distinguishable buckets on its own — before any other signal is even considered.

The math of uniqueness, briefly

Suppose a site probes for 500 candidate fonts and each font is independently present or absent. That's 2^500 theoretical combinations. Reality is far more correlated — fonts arrive in clusters, as we just saw — but even the correlated version leaves an enormous space. What matters is the practical outcome: in fingerprinting datasets, the exact set of detected fonts is frequently unique or near-unique per machine, and it's identical across every browser on that machine, because Chrome, Firefox, and Edge all draw from the same OS font directory. That cross-browser stability is something cookies never had. Clearing site data doesn't touch it. Reinstalling the browser doesn't touch it. It's a property of the computer, not the session.

If you want the broader picture of how this one signal fits alongside canvas, WebGL, audio, and the rest, our primer on browser fingerprinting for beginners covers the full surface. Here we'll stay on fonts, because fonts deserve the depth.

Font fingerprinting: how sites detect installed fonts in practice

Browsers deliberately do not expose a navigator.fonts.list() free-for-all. There is no classic API that hands over the font list. So detection scripts infer it — and the inference techniques are clever enough to be worth understanding one by one.

Technique 1: CSS fallback measurement (the classic)

This is the original method, dating back to Flash-era fingerprinting and still in wide use because it needs nothing but CSS and JavaScript.

The trick exploits font fallback. When a stylesheet says font-family: 'SomeFont', monospace, the browser uses SomeFont if it's installed and silently falls back to the generic monospace face if it isn't. The script:

  1. Renders a test string — a favourite is mmmmmmmmmmlli, chosen because wide m glyphs and narrow l/i glyphs exaggerate width differences between typefaces — in each of the three generic families (serif, sans-serif, monospace) and records the exact pixel width and height of the rendered span. These are the baselines.
  2. Renders the same string with font-family: 'CandidateFont', serif and measures again.
  3. If the dimensions differ from the serif baseline, the browser did not fall back — CandidateFont is installed. If they match exactly, it isn't. Repeat against sans-serif and monospace baselines to rule out coincidental width matches.

Run that loop over a candidate list of 300–1,000 known font names and you've enumerated the machine's font inventory without asking anyone. The test elements are typically rendered off-screen at a large size (bigger glyphs, bigger measurable differences), and the whole sweep finishes in well under a second. No canvas, no permissions, works in every browser back to the dark ages.

The one structural limit: the site can only test fonts it names. Your obscure hand-made font is invisible to this method unless the probe list includes it. In practice that limit barely matters — the standard probe lists cover the fonts that carry the identifying signal, because those are exactly the ones software installs in recognisable clusters.

Technique 2: Canvas measureText probing

A tighter variant of the same idea uses the 2D canvas. CanvasRenderingContext2D.measureText() returns the advance width of a string under the context's current font — no DOM elements, no layout, no reflow. The script sets ctx.font = '72px CandidateFont, monospace', measures, and compares against the pure-monospace measurement. Different width, font present.

Because it skips layout entirely, canvas probing is faster and quieter than DOM measurement — hundreds of candidates per frame, nothing ever painted where a user or a naive monitoring tool would see it. Modern TextMetrics also exposes fine-grained ascent and descent values, which distinguish fonts that happen to share widths. Most commercial fingerprinting libraries use this as their primary font path today.

Technique 3: document.fonts.check()

The CSS Font Loading API was built so web apps could know when their web fonts finished loading. But document.fonts.check('12px SomeFont') answers a yes/no question about whether a font is available — and locally installed fonts are available. It's a one-line oracle: no measurement, no baseline arithmetic, just a boolean per candidate name.

Browsers have partially hardened this (and its cousin, @font-face with a local() source) precisely because it was such a clean enumeration primitive, but hardening varies by browser and version, and the measurement techniques above remain as the universal fallback. A serious detection script tries the cheap oracle first and falls back to measuring.

Technique 4: Glyph rendering — fonts inside the canvas fingerprint

There's a second, subtler way fonts leak: not which fonts exist, but how they draw. When a script renders text to a canvas and hashes the pixels — the standard canvas fingerprint — the output depends on the font file's exact version, the OS text rasteriser, hinting, and anti-aliasing settings. Two machines with nominally the same font can produce different pixel hashes because one has Arial from Windows 10 and the other Arial from Windows 11.

This matters for anyone thinking about defence, because it means the font surface has two distinct layers: the list (which names respond) and the rendering (what the glyphs look like at the pixel level). Spoofing one and not the other is a detectable contradiction — a machine that claims a macOS font list but rasterises text with DirectWrite's characteristic sub-pixel pattern is advertising that something is lying.

Technique 5: The Local Font Access API — the polite one

Chromium added a real enumeration API, window.queryLocalFonts(), so web apps like Figma and Photoshop-on-the-web can offer your actual local fonts in a font picker. It returns full family and style data — but only after an explicit permission prompt, and only in a secure context with user activation.

Fingerprinting scripts don't use it. A permission dialog is the opposite of covert, and denial tells the script nothing. Its existence is still worth knowing about, because it marks the line browser vendors drew: deliberate font access requires consent; the problem is that thirty years of CSS behaviour still allows the inferential kind without it.

The techniques side by side

Technique What it reads Permission prompt Speed Where you'll meet it
CSS fallback measurement Presence/absence per named font None ~100s of fonts/sec Legacy and belt-and-braces scripts everywhere
Canvas measureText Presence/absence + metric detail None Fastest; no layout cost Primary path in modern fingerprint libraries
document.fonts.check() Boolean availability None Instant per query Opportunistic first attempt, browser-dependent
Glyph raster hashing Font version + OS rasteriser None One canvas draw Bundled into every canvas fingerprint
queryLocalFonts() Full font list with metadata Yes n/a Legitimate design tools only

The uncomfortable summary: four of the five need no consent, produce no visible artefact, and work in every mainstream browser.

Why the font signal is so sticky

Plenty of fingerprint signals are noisy. Screen resolution changes when you plug in a monitor. IP addresses rotate. Time zones shift when you travel. The font list has none of that volatility — it changes only when you install or remove software, which for most people happens a handful of times a year. Detection systems love slow-moving signals because they can anchor an identity to them and treat everything else as decoration.

Three properties make fonts especially valuable to the systems deciding whether your five accounts are one person:

It's cross-browser. Log into account A in Chrome and account B in Firefox on the same machine, and both browsers report the same OS font inventory. Anyone who thinks browser-switching is isolation should read that sentence twice.

It's semantically rich. The list doesn't just distinguish you — it describes you. Adobe cluster: designer. Corporate-licensed faces: enterprise machine. CJK and Cyrillic coverage together: a hint about geography and languages that had better agree with your IP and Accept-Language header. Risk engines cross-check these stories, and a mismatch (a machine claiming to be in the US whose font list screams a different region, say) raises exactly the kind of quiet score adjustment that later reads as a random ban. Sellers dealing with linked-account suspensions see this class of contradiction constantly — it's a recurring theme in our Amazon seller account ban playbook.

It contradicts lies told elsewhere. Spoof your user agent to macOS while your measurable fonts include Segoe UI and Calibri — Windows tells — and you haven't hidden anything; you've confirmed you're masking. Font data is one of the primary consistency checks that unravels amateur spoofing.

What browsers have done about it

Browser vendors know all of this, and the countermeasures they've shipped tell you a lot about what actually works.

Restriction to a known set

Safari's approach, later echoed by Firefox's privacy.resistFingerprinting mode and the Tor Browser: only expose fonts from a fixed, per-OS allowlist regardless of what's really installed. Your hand-installed fonts simply don't respond to probes. This genuinely collapses the entropy — every Safari-on-macOS user presents roughly the same font surface. The cost is that documents and sites using your custom fonts fall back to substitutes, which is why mainstream Chrome hasn't followed.

Randomisation and metric noise

Brave's farbling takes the other road: subtly perturb the measurements per-site and per-session so the fingerprint a site collects today doesn't match tomorrow's. Effective against naive hashing, but detectable in principle — a machine whose text metrics wobble between visits is itself unusual, and sophisticated systems flag instability just as readily as they match stable prints.

The lesson for multi-account work

Notice what neither approach does: neither makes you look like someone else. They make you look like a privacy-conscious person — a member of a smaller, more conspicuous crowd. For a journalist avoiding tracking, that trade is fine. For someone operating ten storefronts or ad accounts, being flagged as "fingerprint-resistant browser" on all ten is precisely the linkage you were trying to avoid. Blocking is a signal. Blankness is a signal. The device fingerprinting literature has repeated this for a decade: the absence of a normal-looking fingerprint is itself identifying.

What doesn't work

A quick demolition of the folk remedies, because each one costs people real accounts:

  • Incognito mode. Private windows isolate cookies and history. Fonts are read live from the OS on every visit; incognito reports exactly the same list.
  • A VPN. Changes your IP and nothing else. Your font list travels with you across every exit node, which is exactly how sites re-link "new" visitors to old ones. The difference is fundamental enough that we wrote a whole piece on why an antidetect browser and a VPN solve different problems.
  • Deleting fonts. You can prune your inventory toward a stock install, but you can't prune below stock without breaking your own system, you'll do it imperfectly, and the machine-level change applies to all your accounts at once — the opposite of per-account separation.
  • Extensions that block font enumeration. They tend to break the measurement APIs in detectable ways (impossible metrics, zero-width text, exceptions where none should occur) and they can't touch the glyph-rendering layer. An extension-shaped hole in the fingerprint is a fingerprint.
  • Switching browsers per account. As covered above: same OS, same fonts, same print. Two browsers on one machine are one machine.

How antidetect browsers handle the font surface

This is where the architecture question gets interesting, because font fingerprinting is one of the clearest examples of why how a tool spoofs matters more than that it spoofs.

The consistency requirement

A convincing font fingerprint isn't a random subset of font names. It has to be a list that a real machine would plausibly have: the correct OS base set for the claimed OS version, plausible software clusters, coherent language coverage — and it has to agree with every other claim the profile makes. If the profile presents a Windows 11 user agent, the fonts must be Windows fonts, the canvas text must rasterise like Windows text, and the metrics must be internally consistent between the DOM measurement path and the canvas path. Fail any one of those cross-checks and the profile is worse than unspoofed.

Injection versus native spoofing

Cheap tools do this with injected JavaScript: they override measureText, patch document.fonts.check, and hook the DOM measurement properties from a content script. The problem is that JavaScript overrides are themselves detectable — a modified function has a different toString(), executes at the wrong time, or misses one of the several redundant measurement paths, and detection scripts probe for exactly those seams. Worse, script injection typically doesn't reach Web Workers or the actual glyph rasteriser, so the pixel-level rendering still tells the truth while the API layer lies. That contradiction is a stronger bot signal than no spoofing at all.

Dual Login takes the native route: the fingerprint — fonts included — is applied inside a custom Chromium engine itself, not painted over the top with injected scripts. The font surface the page measures is the font surface the profile was assigned, at every layer, in every context, with zero JavaScript patches for a detector to find. Each profile carries its own internally consistent identity (fonts, canvas, WebGL, navigator, screen, time zone, languages) and its own persistent data directory, so profile three's font list never bleeds into profile four, and both survive restarts unchanged — because a fingerprint that's perfect but different every session is its own red flag. If you're new to the category, what an antidetect browser is and how it works walks through the full architecture; the font story here is one instance of the general principle that native beats injected.

Fonts are necessary, not sufficient

Worth saying plainly: fixing fonts alone fixes nothing. Fonts are one column in a consistency matrix that includes your IP's geography, your time zone, your Accept-Language, your canvas hash, and your WebGL renderer string. Serious platforms score the coherence of the whole picture. That's why the practical advice for people running many accounts — covered in depth in our guide to the best antidetect browser setup for multiple accounts — is always: one profile per account, one proxy per profile, geography matched end to end, and never mix profiles across accounts to save time.

Testing your own font fingerprint

Don't take any tool's word for it — including ours. Testing takes ten minutes:

  1. Baseline your real machine. Visit Cover Your Tracks in your daily browser and note the entropy attributed to system fonts. On a machine with a few years of software history, it's usually one of the top contributors.
  2. Check the list a profile presents. Open a fingerprint checker inside each browser profile you use for real work. You're looking for three things: the list matches the claimed OS, the list differs between profiles, and the list is identical for the same profile across sessions.
  3. Hunt for contradictions. OS in the user agent versus OS implied by fonts. Language coverage versus proxy geography. Canvas text hash stability across reloads.
  4. Probe the API seams. In a console, document.fonts.check('12px Arial') should behave — and measureText should return believable, stable metrics rather than zeros or noise.

If two of your account profiles show the same font fingerprint, assume the platform sees them as one machine, because it does. This checklist generalises: it's the same class of verification we recommend during an antidetect browser free trial, where the whole point is to catch leaks before real accounts are riding on the setup.

FAQ

Can a website really see all my installed fonts without permission?

Not by asking directly — the only true enumeration API, queryLocalFonts(), requires an explicit permission prompt. But sites can infer presence or absence for any font they name, using CSS fallback measurement or canvas measureText, with no prompt and no visible artefact. Since probe lists cover hundreds of common fonts, the inferred list captures nearly all of the identifying signal.

Does incognito or private browsing hide my fonts?

No. Private modes isolate cookies, history, and site storage. Fonts are read live from the operating system on every page load, so an incognito window reports exactly the same font list as a normal one — which is precisely why fingerprinting outlives cookie clearing.

Is font fingerprinting still effective in 2026?

Yes, with caveats. Safari and hardened Firefox restrict probes to a fixed allowlist, which collapses the signal for those users. But default Chrome and Edge — the overwhelming majority of traffic — still expose the full measurable surface, and the glyph-rendering layer leaks OS and font-version information even where lists are restricted. Commercial detection stacks still weight fonts heavily.

Why not just delete extra fonts to look generic?

You can get closer to a stock install, but you can't go below stock without breaking your own documents and apps, and the change applies machine-wide — every account you run then shares the same "cleaned" fingerprint, which is the linkage problem restated. Per-account separation needs per-profile fingerprints, not a single sanitised machine.

Do font-blocking extensions protect me?

Mostly they relocate the problem. Extensions patch JavaScript APIs, and patched APIs are detectable: wrong toString() output, impossible metrics, coverage gaps in Workers, and an untouched pixel-rendering layer that contradicts the patched numbers. To a good detection script, a broken measurement surface reads as "this user is masking" — often a worse outcome than an honest fingerprint.

How does Dual Login make font fingerprints different per profile?

The fingerprint is applied natively inside Dual Login's custom Chromium engine rather than through injected scripts, so every measurement path — DOM, canvas metrics, glyph rendering, Workers — reports the same internally consistent identity. Each profile gets its own plausible, OS-coherent font surface plus its own data directory and optional proxy, and that identity persists across sessions instead of reshuffling.

The takeaway

Font fingerprinting works because it reads something real: the slow accumulation of software, languages, and habits on your actual machine. The classic techniques — CSS fallback measurement, canvas metrics, font-availability checks — need no permission and survive every cookie purge, and the resulting signal is stable, cross-browser, and rich enough to contradict careless spoofing on its own. Blocking it makes you conspicuous; ignoring it links your accounts.

The working answer is neither blocking nor ignoring but substitution: each account gets a complete, coherent, persistent machine identity, with fonts that agree with the OS, the canvas, the time zone, and the proxy. That's the problem Dual Login was built around — native, engine-level fingerprints with per-profile isolation, no injected JavaScript to find. Spin up a couple of profiles, point a fingerprint checker at them, and verify the font lists diverge the way two genuinely different machines would. The test costs you ten minutes; a linked account costs considerably more.

Run every account like a separate device

Dual Login gives each profile a real fingerprint, its own proxy and sealed storage — free plan, no card required.