Font fingerprinting identifies you by the fonts installed on your device. Learn how font enumeration and measurement work — and how to reduce what you expose.
Font fingerprinting identifies your device by the set of fonts installed on it. The specific combination of fonts you have — shaped by your operating system, installed software, language packs, and design tools — is surprisingly distinctive, and a website can detect that combination from JavaScript without any special permission. This guide explains how font enumeration and measurement work, why the result is so identifying, and how to reduce what you give away.
Key Takeaways
- There is no permissionless API that lists your fonts; trackers infer them by rendering text and measuring how the browser substitutes a fallback font when a requested font is missing.
- A few hundred present/absent probes combine into a high-entropy profile because font sets reflect your OS, installed apps, and language packs.
- The technique needs no permission and survives clearing cookies or using private mode, because it derives from rendering behavior, not stored data.
- The newer
queryLocalFonts()API can list real fonts but is gated behind an explicit permission prompt, so it is not the silent vector trackers rely on. - The best defense is uniformity: browsers like Tor Browser standardize the visible font set so everyone looks alike, rather than adding custom fonts.
What is font fingerprinting?
Font fingerprinting is the practice of determining which fonts are installed on your system and using that list as part of a device identifier. Your font set is rarely something you think about, yet it carries real entropy: a default Windows install, a Mac with Adobe apps, and a Linux box with developer tools all carry visibly different font collections.
Websites can't simply ask "what fonts do you have?" — there's no direct API that returns the full list. Instead they infer it by testing specific fonts and watching how text renders. Like canvas and audio fingerprinting, it relies on measurable rendering differences rather than stored data, so it survives clearing cookies. Privacy-research tools such as the EFF's Cover Your Tracks demonstrate how distinctive these passive signals are when combined.
How font detection works
The classic technique is fallback measurement. When a browser is asked to render text in a font that isn't installed, it silently substitutes a default font — and the substitute almost always has different letter dimensions. By measuring those dimensions, a script can tell whether the requested font was actually present.
The method works like this:
- Measure a baseline. Render a test string in known generic fonts (
monospace,sans-serif,serif) and record the exact width and height. - Request a candidate font. Render the same string asking for a specific font (e.g. "Calibri") with a generic fallback.
- Compare. If the dimensions differ from the fallback baseline, the candidate font is installed; if they match the fallback, it isn't.
- Repeat. Run through a list of hundreds of common fonts to build a presence/absence profile.
// Detect whether a specific font is installed via fallback measurement
function isFontInstalled(font) {
const baseFont = 'monospace';
const text = 'mmmmmmmmmmlli';
const span = document.createElement('span');
span.style.fontSize = '72px';
span.style.position = 'absolute';
span.style.left = '-9999px';
span.textContent = text;
document.body.appendChild(span);
span.style.fontFamily = baseFont;
const baseWidth = span.offsetWidth;
// Request the candidate with the base as fallback
span.style.fontFamily = `'${font}', ${baseFont}`;
const testWidth = span.offsetWidth;
document.body.removeChild(span);
return testWidth !== baseWidth; // different width => font is present
}
Modern variants use the Canvas API to measure text more precisely. Instead of reading an element's box size, a script draws the test string onto a canvas with measureText() and inspects the returned glyph metrics — which can differ even when two fonts happen to share the same advance width, making detection more reliable and harder to fool with crude defenses.
Enumeration vs. the Local Font Access API
It helps to separate two distinct capabilities:
| Approach | Permission | What it reveals |
|---|---|---|
| Fallback / canvas measurement | None | Presence or absence of each font you specifically probe, one at a time |
queryLocalFonts() | Explicit prompt | The full list of installed font faces, including PostScript names and family names |
The first approach can only answer "is this font installed?" for fonts the script already thought to test, so trackers ship a curated list of a few hundred common families. The second — the Local Font Access API, available in Chromium-based browsers — returns the complete set of local fonts in one call, but only after the user grants a local-fonts permission. Because that prompt is conspicuous and easy to deny, covert trackers rarely use it; the silent fallback-measurement method remains the workhorse of font fingerprinting.
Why your font list is so identifying
Font sets accumulate from many sources, and that variety is exactly what makes them useful for tracking:
- Operating system and version ship different default fonts.
- Installed applications — Microsoft Office, Adobe Creative Cloud, and design tools — add distinctive font families.
- Language and region packs add scripts (CJK, Cyrillic, Arabic) that many systems lack.
- Manually installed fonts from designers and developers are highly individual.
Each installed-or-not answer is a bit of entropy, and a few hundred probes combine into a profile distinctive enough to single out many users — especially when joined with other signals.
How font fingerprinting fits the bigger picture
Font fingerprinting rarely works alone. It's one layer in a stack that includes canvas, WebGL, audio, screen metrics, and user-agent data. There's also overlap with browser add-ons: some extensions inject their own fonts or alter font behavior, which can make you more identifiable rather than less. Understanding the whole picture is the point of our browser fingerprinting guide.
How to reduce your font fingerprint
- Use a browser that limits font enumeration. The Tor Browser restricts sites to a standard set of fonts so everyone looks alike; Firefox's resist-fingerprinting mode does similar. Brave applies randomization.
- Avoid installing unusual fonts in the browser profile you use for privacy-sensitive browsing — the rarer your set, the more unique you are.
- Be wary of font-injecting extensions, which can expand your detectable font list.
- Know the limits. As with other techniques, private/incognito mode does not stop font fingerprinting; it only clears cookies and history.
The counterintuitive lesson is that uniformity protects you: the goal is to look like everyone else, not to add more custom fonts.
How the strongest defenses actually work
The most effective tools don't try to hide your fonts so much as flatten the differences between users:
- Standardization. The Tor Browser ships a fixed bundle of fonts and tells web pages that only those exist, regardless of what is actually installed. Every Tor user therefore reports the same font set, collapsing the entropy of this signal toward zero. Firefox's
privacy.resistFingerprintingmode applies the same philosophy. - Randomization. Brave perturbs the measured values slightly and per-session, so repeated probes don't return a stable answer. This breaks the cross-visit linkability that makes a fingerprint useful, even if a single snapshot still looks plausible.
- Reducing your surface. Outside hardened browsers, keep a clean profile for privacy-sensitive browsing: avoid installing exotic font families, and remove font-injecting extensions. A stock OS install is far less unique than one loaded with design software.
No single switch removes font fingerprinting, and combining a hardened browser with a minimal font set is the realistic goal. For the broader threat model — how fonts combine with other signals — the W3C documents fingerprinting as a recognized privacy concern in its web platform guidance.
Frequently Asked Questions
Can a website see all my installed fonts directly?
Not without permission. There's no permissionless API that lists every font. Sites infer your fonts by rendering text and measuring fallback substitution, which reveals presence or absence one font at a time. The newer queryLocalFonts() API can list fonts but requires an explicit permission prompt.
Does font fingerprinting need any permission?
No. The fallback-measurement method uses ordinary text rendering and element sizing, which require no permission and trigger no prompt. That's what makes it attractive to trackers and hard for users to notice.
Will clearing cookies remove my font fingerprint?
No. The fingerprint is derived from which fonts are installed, not from stored data, so clearing cookies or using private mode doesn't change it. Reducing it requires limiting font enumeration at the browser level.
How can I check what my browser exposes?
Run BrowserInsight's fingerprint check to see the signals your browser leaks, and the plugin and extension check to review add-ons that may affect your font profile.
Conclusion
Font fingerprinting reads the unique collection of fonts your system has accumulated and turns it into a stable identifier — no permission, no microphone, no stored data. Because font sets reflect your OS, apps, and habits, they carry real entropy, especially alongside canvas, WebGL, and audio signals. The effective defense isn't adding more fonts but blending in: use a browser that standardizes or randomizes font enumeration, and keep your privacy profile ordinary.
Recommended Reading: