Privacy Tools Guide

Browser fingerprinting has become one of the most sophisticated tracking techniques used across the web. Unlike cookies, which can be blocked or deleted, fingerprinting collects dozens of data points from your browser to create a unique identifier. Anti-fingerprinting tools aim to standardize or randomize this data, but how do you know if your setup actually works? This guide provides practical methods to test your anti-fingerprinting configuration.

Understanding Browser Fingerprinting

Browser fingerprinting works by collecting various browser properties and combining them into a unique hash. The technique relies on attributes such as user agent strings, screen resolution, installed fonts, WebGL renderer information, canvas fingerprinting, and hundreds of other signals. When you visit a website, the server can generate a fingerprint from these attributes and use it to track you across sessions, even without cookies.

Anti-fingerprinting tools like privacy browsers, browser extensions, or configuration changes attempt to either standardize these values across all users or introduce controlled randomness to make consistent tracking impossible. However, misconfigurations or incomplete coverage can leave gaps that fingerprinting scripts exploit.

Basic Testing with Online Tools

The quickest way to verify your setup is using established fingerprinting test sites. These services analyze your browser and report which identifying attributes are exposed.

Panopticlick (now Cover Your Tracks by EFF) remains a standard testing tool. Visit the site and examine the entropy score it assigns to your browser. A higher entropy score indicates more unique identification points, which means your anti-fingerprinting is less effective. Ideally, you want your browser to blend in with the crowd.

AmIUnique and AMIUnique.org provide detailed breakdowns of which attributes make your browser identifiable. These tools compare your fingerprint against their database of millions of collected fingerprints and show which specific attributes are unique to your setup.

FingerprintJS offers a commercial-grade fingerprinting library, and their demo page shows exactly what information their library can extract from your browser. This is particularly useful because it represents what tracking networks actually use.

Run these tests in your regular browser first to establish a baseline, then repeat them with your anti-fingerprinting measures enabled to compare results.

Testing with Command Line Tools

For developers who want more controlled testing, command-line tools provide deeper insights. The curl command with specific headers can reveal what your browser transmits.

Test your user agent string:

curl -s -D - -o /dev/null https://httpbin.org/headers | grep -i "user-agent"

This shows the user agent your system currently uses. If you use a browser with anti-fingerprinting, the user agent should appear common and unremarkable.

Check for WebRTC leaks, which can expose your real IP address even behind a VPN:

curl -s https://ipleak.net/json/

A properly configured setup should either block WebRTC or route it through your VPN.

Programmatic Fingerprinting Tests

For testing, write a simple script that extracts the same data fingerprinting libraries collect. Create an HTML file with JavaScript:

<!DOCTYPE html>
<html>
<head><title>Fingerprint Test</title></head>
<body>
<h1>Browser Fingerprint Data</h1>
<pre id="output"></pre>
<script>
const data = {
  userAgent: navigator.userAgent,
  language: navigator.language,
  languages: navigator.languages,
  platform: navigator.platform,
  hardwareConcurrency: navigator.hardwareConcurrency,
  deviceMemory: navigator.deviceMemory,
  screenResolution: `${screen.width}x${screen.height}`,
  colorDepth: screen.colorDepth,
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
  canvasFingerprint: createCanvasFingerprint(),
  webGLVendor: getWebGLVendor(),
  webGLRenderer: getWebGLRenderer(),
  fonts: detectFonts()
};

function createCanvasFingerprint() {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  ctx.textBaseline = "top";
  ctx.font = "14px 'Arial'";
  ctx.fillStyle = "#f60";
  ctx.fillRect(125, 1, 62, 20);
  ctx.fillStyle = "#069";
  ctx.fillText("Fingerprint Test", 2, 15);
  ctx.fillStyle = "rgba(102, 204, 0, 0.7)";
  ctx.fillText("Fingerprint Test", 4, 17);
  return canvas.toDataURL();
}

function getWebGLVendor() {
  const canvas = document.createElement('canvas');
  const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
  const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
  return debugInfo ? gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) : 'N/A';
}

function getWebGLRenderer() {
  const canvas = document.createElement('canvas');
  const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
  const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
  return debugInfo ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : 'N/A';
}

function detectFonts() {
  // Simplified font detection
  const baseFonts = ['monospace', 'sans-serif', 'serif'];
  const testFonts = ['Arial', 'Helvetica', 'Times New Roman', 'Courier New', 'Verdana', 'Georgia'];
  return testFonts.join(', ');
}

document.getElementById('output').textContent = JSON.stringify(data, null, 2);
</script>
</body>
</html>

Open this file in your browser and examine the output. Look for inconsistencies or identifying information. A working anti-fingerprinting setup should either block access to sensitive APIs, return generic values, or introduce controlled randomness that changes between sessions.

Testing Specific Protections

Canvas Fingerprinting

Canvas fingerprinting works by drawing invisible text and shapes to a canvas element, then converting the result to a hash. To test canvas protection, visit a site that generates canvas fingerprints or run the JavaScript code above. If your setup works, the canvas hash should either remain constant across different contexts or change unpredictably between page loads.

WebGL Fingerprinting

WebGL exposes detailed graphics card information. Check whether WEBGL_debug_renderer_info returns generic values or specific hardware identifiers. A proper setup should mask the actual GPU vendor and renderer.

Font Fingerprinting

Websites can detect installed fonts by measuring text width differences. Test this by comparing font lists between your protected and unprotected browsers. Effective anti-fingerprinting either limits available fonts to a standard set or randomizes which fonts are reported.

Audio Context Fingerprinting

AudioContext fingerprinting analyzes how your system processes audio signals. Check whether audio processing produces consistent or randomized results. Some privacy tools add noise to audio processing to prevent fingerprinting.

Automating Tests with Headless Browsers

For developers building privacy tools, automated testing is essential. Use headless browsers with anti-fingerprinting capabilities to verify protections programmatically:

const puppeteer = require('puppeteer-extra');
const pluginStealth = require('puppeteer-extra-plugin-stealth')();

puppeteer.use(pluginStealth);

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();

  // Enable anti-fingerprinting
  await page.evaluateOnNewDocument(() => {
    // Additional client-side protections can go here
  });

  await page.goto('https://amiunique.org/fingerprint');
  await page.waitForTimeout(3000);

  const fingerprint = await page.evaluate(() => {
    return {
      userAgent: navigator.userAgent,
      platform: navigator.platform
    };
  });

  console.log('Fingerprint:', fingerprint);
  await browser.close();
})();

This approach allows you to run consistent tests across different configurations and verify that protections remain active.

Verifying Consistency

A working anti-fingerprinting setup should produce consistent results when you want it to and different results when you expect variation. Test the following scenarios:

  1. Session consistency: Reload the same page multiple times. Your fingerprint should remain identical within a session unless you explicitly want randomization.

  2. Identity persistence: Close and reopen your browser. Depending on your threat model, your fingerprint should either remain consistent (for normalization) or change completely (for randomization).

  3. Context isolation: Test in normal and private/incognito windows. The best setups maintain consistent identities within each context type while keeping contexts separate from each other.

Common Pitfalls

Several issues often undermine anti-fingerprinting efforts:

Built by theluckystrike — More at zovo.one