As developers, we often think about securing our applications, but how often do we check what our browsers are revealing about us? Browser fingerprinting is a powerful tracking technique that collects dozens of data points to create a unique identifier for each visitor. The scary part? It happens silently, without cookies, and most users have no idea it's occurring.
In this guide, I'll show you exactly how to test and understand your browser's fingerprint using both manual techniques and automated tools. By the end, you'll know what information you're leaking and how to protect yourself.
What Is Browser Fingerprinting?
Browser fingerprinting works by collecting various attributes about your browser and device, then combining them to create a unique "fingerprint." Unlike cookies, which can be deleted, your fingerprint travels with you across sites and is incredibly difficult to change.
Common Fingerprinting Data Points
Here are the most commonly collected attributes:
- Screen resolution and color depth
- Installed fonts
- Browser version and user agent
- Installed plugins
- Timezone and language settings
- Canvas and WebGL rendering
- Audio context fingerprint
- Hardware details (CPU cores, RAM)
Testing Your Browser Fingerprint
Method 1: Manual JavaScript Testing
Let's start by creating our own fingerprinting script to understand what data is accessible:
// Basic fingerprint data collection
function collectFingerprint() {
const fingerprint = {};
// Screen information
fingerprint.screen = {
width: screen.width,
height: screen.height,
colorDepth: screen.colorDepth,
pixelRatio: window.devicePixelRatio
};
// Navigator information
fingerprint.navigator = {
userAgent: navigator.userAgent,
language: navigator.language,
platform: navigator.platform,
hardwareConcurrency: navigator.hardwareConcurrency,
cookieEnabled: navigator.cookieEnabled
};
// Timezone
fingerprint.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
// Check for plugins (deprecated in modern browsers)
fingerprint.plugins = Array.from(navigator.plugins).map(p => p.name);
return fingerprint;
}
// Test it
console.log('Your browser fingerprint:', collectFingerprint());
Method 2: Canvas Fingerprinting
Canvas fingerprinting is particularly effective because slight differences in how graphics are rendered can uniquely identify devices:
function getCanvasFingerprint() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Draw some complex shapes and text
ctx.fillStyle = '#f60';
ctx.fillRect(125, 1, 62, 20);
ctx.fillStyle = '#069';
ctx.font = '11pt Arial';
ctx.fillText('Hello, fingerprinter!', 2, 15);
ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
ctx.font = '18pt Times';
ctx.fillText('Browser test 🎨', 4, 45);
// Return the canvas data as a hash
return canvas.toDataURL();
}
console.log('Canvas fingerprint:', getCanvasFingerprint());
Method 3: Font Detection
Checking installed fonts can reveal operating system and user preferences:
function detectFonts() {
const testFonts = [
'Arial', 'Helvetica', 'Times New Roman', 'Comic Sans MS',
'Courier New', 'Verdana', 'Georgia', 'Impact',
'Trebuchet MS', 'Arial Black', 'Tahoma'
];
const detectedFonts = [];
testFonts.forEach(font => {
const testElement = document.createElement('span');
testElement.style.font = `12px ${font}`;
testElement.textContent = 'mmmmmmmmmmlli';
testElement.style.visibility = 'hidden';
document.body.appendChild(testElement);
const width = testElement.offsetWidth;
document.body.removeChild(testElement);
// Compare with fallback font width
if (width !== 0) {
detectedFonts.push(font);
}
});
return detectedFonts;
}
console.log('Detected fonts:', detectFonts());
Method 4: WebGL Fingerprinting
WebGL provides detailed information about your graphics hardware:
function getWebGLFingerprint() {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) {
return null;
}
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
return {
vendor: gl.getParameter(gl.VENDOR),
renderer: gl.getParameter(gl.RENDERER),
version: gl.getParameter(gl.VERSION),
shadingLanguageVersion: gl.getParameter(gl.SHADING_LANGUAGE_VERSION),
unmaskedVendor: debugInfo ? gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) : null,
unmaskedRenderer: debugInfo ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : null
};
}
console.log('WebGL fingerprint:', getWebGLFingerprint());
Online Testing Tools
While coding your own tests is educational, several online tools can quickly show your fingerprint:
1. AmIUnique.org
Offers detailed analysis with uniqueness scores for each attribute.
2. Panopticlick (EFF)
The Electronic Frontier Foundation's tool focuses on privacy implications.
3. BrowserLeaks.com
Comprehensive testing suite covering all major fingerprinting vectors.
4. Device Info
Shows detailed device and browser information.
Interpreting Your Results
When you run these tests, pay attention to:
- Uniqueness score: How identifiable you are among other users
- Entropy bits: Mathematical measure of randomness/uniqueness
- Tracking protection effectiveness: What your current setup blocks
A high uniqueness score (like being 1 in 10,000 users) means you're easily trackable even without cookies.
Protection Strategies
Basic Protection
- Use privacy-focused browsers like Firefox with strict privacy settings
- Enable tracking protection in your browser settings
- Disable JavaScript when possible (though this breaks many sites)
- Use browser extensions like uBlock Origin or Privacy Badger
Advanced Protection
// Spoofing user agent (basic example - not foolproof)
Object.defineProperty(navigator, 'userAgent', {
value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
writable: false
});
// Blocking canvas fingerprinting
const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
HTMLCanvasElement.prototype.toDataURL = function() {
// Return consistent fake data
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';
};
Professional Solutions
For developers and power users who need reliable fingerprint protection, specialized tools offer more robust solutions. FireKey creates isolated browser environments with different fingerprint profiles for each session, making it impossible for sites to correlate your activities across different browsing contexts. This approach is particularly valuable for:
- Web developers testing sites without contaminating analytics
- Digital marketers managing multiple accounts
- Privacy-conscious users wanting compartmentalized browsing
- Security researchers conducting investigations
Creating a Complete Test Suite
Combine all techniques into a comprehensive test:
async function comprehensiveFingerprint() {
const results = {
basic: collectFingerprint(),
canvas: getCanvasFingerprint(),
fonts: detectFonts(),
webgl: getWebGLFingerprint(),
timestamp: new Date().toISOString()
};
// Calculate a simple hash for comparison
const fingerprint = JSON.stringify(results);
const hash = await crypto.subtle.digest('SHA-256',
new TextEncoder().encode(fingerprint)
);
results.hash = Array.from(new Uint8Array(hash))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
return results;
}
// Run the complete test
comprehensiveFingerprint().then(result => {
console.log('Complete fingerprint:', result);
});
Best Practices for Developers
If you're implementing analytics or user tracking:
- Be transparent about data collection
- Respect user privacy settings
- Implement proper consent mechanisms
- Use minimal necessary data
- Provide opt-out options
Conclusion
Browser fingerprinting is a powerful but invisible tracking technique. By understanding what data your browser exposes and testing it regularly, you can make informed decisions about your privacy settings and tools.
The key takeaways:
- Your browser reveals more than you might expect
- Fingerprints are unique and persistent across sites
- Basic protection helps, but advanced threats require specialized tools
- Regular testing helps you stay aware of your privacy posture
Start by running the tests in this guide, then evaluate whether your current privacy setup meets your needs. Remember: privacy is not about having something to hide – it's about having control over your digital footprint.
What did you discover when testing your browser fingerprint? Share your results and protection strategies in the comments below!
Top comments (0)