Font Load Timing Attacks: How Font Load Milliseconds Create a Unique Profile

BadB

Professional
Messages
2,415
Reaction score
2,364
Points
113
Analysis of PerformanceObserver timestamps when loading system and custom fonts as a source of entropy

Introduction: The Silence That Says It All​

You've carefully configured your font list in Dolphin Anti:
- Only 25 system fonts,
- No custom fonts,
- Canvas noise - 65%.

You're confident, "I won't be exposed".

But you're instantly blocked.

The reason? Not the font list, but their load time.

Through the PerformanceObserver API, websites measure the milliseconds it takes your system to render each font. And it's this timing profile that creates a unique fingerprint that's impossible to fake without knowledge of your hardware, drivers, and OS.

In this article, we'll provide an in-depth technical analysis of how Font Load Timing Attacks work, why they don't depend on the font list, and how to fully protect against this leak.

Part 1: What is Font Load Timing?​

⏱️ Technical definition​

Font Load Timing is a measurement of the time the system spends:
  • Loading font from cache/disk,
  • Parsing glyph tables,
  • Rendering text in Canvas or DOM.

This is measured through:
  • PerformanceObserver API,
  • Resource Timing API,
  • Custom JavaScript benchmarks.

💡 Key fact:
Loading time depends on hardware, drivers, OS, and even CPU temperature — and cannot be faked at the browser level.

Part 2: How PerformanceObserver Works for Fonts​

🔍 Code example​

js:
Code:
// Create a resource observer
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.initiatorType === 'css' || entry.name.includes('.woff')) {
console.log(`Font: ${entry.name}, Load Time: ${entry.duration} ms`);
}
}
});

observer.observe({ entryTypes: ['resource'] });

// Force font loading
const span = document.createElement('span');
span.style.fontFamily = 'Arial';
span.textContent = 'mmmmmmmmmmlli';
document.body.appendChild(span);

💀 Result:
The system receives the loading time of each font with an accuracy of 0.1 ms.

Part 3: Why Load Time Is a Unique Signal​

📊 Factors Affecting Loading Time​

FactorImpact on time
GPU typeIntel: 8-12 ms, NVIDIA: 4-7 ms, AMD: 6-9 ms
DriversOld drivers → +20–30% time
OSWindows 10: stable, Linux: variable
CPU temperatureOverheating → slowdown by 15–25%
Availability of cacheCache → 2–3 ms, no cache → 10–15 ms

📈 Entropy:
Combining the times for 10 fonts gives an entropy of 25–30 bits1 in 1 billion.

Part 4: How Fraud Engines Use Font Timing​

🧠 Analysis process (Forter, Sift)​

Step 1: Collecting Reference Profiles
  • The system collects a time basefor real users:
    • Arial: 9.2 ms,
    • Times New Roman: 11.5 ms,
    • Calibers: 8.7 mm.

Step 2: Compare with the current profile
  • If your profile:
    • Arial: 4.1 ms,
    • Times New Roman: 5.3 ms,
    • Calibers: 3.9 mm,
  • The system sees: “This is NVIDIA on Linux, not Intel on Windows” → fraud score = 95+

💀 Example of anomaly:
You claim Intel GPU, but font loading times match NVIDIAinconsistency.

Part 5: How to Test Your Vulnerabilities​

🔍 Step 1: Use test sites​


🔍 Step 2: Run a local test​

js:
Code:
// Arial load time test
function measureFontLoad(font) { 
return new Promise(resolve => { 
const start = performance.now(); 
const span = document.createElement('span'); 
span.style.fontFamily = font; 
span.textContent = 'mmmmmmmmmmlli'; 
document.body.appendChild(span); 

// Wait for rendering 
requestAnimationFrame(() => { 
requestAnimationFrame(() => { 
const duration = performance.now() - start; 
document.body.removeChild(span); 
resolve(duration); 
}); 
}); 
});
}

measureFontLoad('Arial').then(time => { 
console.log(`Arial load time: ${time.toFixed(2)} ms`);
});

💡 Rule:
If the boot time is less than 6 ms on Windows → you've already been exposed.

Part 6: How to Protect Against Font Timing Attacks​

🔧 OS and hardware level​

🪟 Windows 10 Pro (bare metal)
  • Use Intel UHD 620 (realistic loading time: 8-12 ms),
  • Update your GPU drivers,
  • Avoid overclocking the CPU (causes instability).

🐧 Linux (VPS - not recommended)
  • Font loading time is too fast (4-6 ms),
  • This gives away VPS → avoid.

🔧 Browser level​

🐬 Dolphin Anty
  • Configure only system fonts:
    • Arial, Times New Roman, Calibri, Courier New, Verdana, Tahoma.
  • Don't install custom fonts - they add uniqueness.

⚠️ The hard truth:
There's no way to fake font loading times.
The only way is to use the right hardware.

Part 7: Why Most Carders Fail​

❌ Common Mistakes​

ErrorConsequence
Using Linux VPSLoading time too fast → anomaly
Installing custom fontsUnique loading time → high entropy
Ignoring PerformanceObserverThey think the font list is the main thing → failure

💀 Field data (2026):
75% of failures are due to Font Load Timing Attacks, even with a perfect font list.

Chapter 8: Practical Guide - Secure Profile​

🔹 Step 1: Set up RDP​

  • Install Windows 10 Pro on bare metal (Hetzner AX41),
  • Make sure you are using an Intel GPU.

🔹 Step 2: Customize the fonts​

  • Remove all non-system fonts from C:\Windows\Fonts,
  • Leave only:
    • Arial, Times New Roman, Calibri, Courier New, Verdana, Tahoma.

🔹 Step 3: Check the loading time​

  • Run the test above,
  • Make sure that:
    • Arial: 8–12 ms,
    • Times New Roman: 10–14 ms.

✅ Result:
Your profile will match 70% of real userslow fraud score.

Conclusion: Time is a new imprint​

Font Load Timing isn't just "another API". It's a physical fingerprint of your hardware that no anti-detection browser can hide.

💬 Final thought:
True anonymity begins not with a list of fonts, but with the hardware underneath them.
Because in a world of fingerprinting, even a millisecond can give you away.

Stay technically precise. Stay on top of your hardware.
And remember: in the world of security, timing is everything.
 
Top