Every time you visit a website, your browser hands over a surprising amount of information. Beyond basic details like your IP address and user agent, websites can extract screen resolution, installed fonts, GPU renderer, timezone, language preferences, and hundreds of other signals. Combined, these create a fingerprint that can identify you across sessions without cookies.
For developers and power users, understanding what your browser reveals is the first step toward hardening your privacy posture. This guide covers practical methods to audit your browser’s digital footprint with working code examples.
Prerequisites
Before you begin, make sure you have the following ready:
- A computer running macOS, Linux, or Windows
- Terminal or command-line access
- Administrator or sudo privileges (for system-level changes)
- A stable internet connection for downloading tools
Step 1 - What Your Browser Exposes by Default
Modern browsers expose numerous APIs for legitimate functionality, but these same APIs enable fingerprinting. The key categories include:
Basic Navigator Properties
- User Agent string
- Platform and OS version
- Language and languages accepted
- Hardware concurrency (CPU cores)
- Device memory (if available)
Screen and Display
- Screen resolution and color depth
- Available screen space
- Pixel ratio
Hardware Features
- GPU renderer and vendor
- Audio context fingerprint
- WebGL renderer info
Browser State
- Cookies enabled
- Do Not Track setting
- Timezone
- Connection type
Step 2 - Use the Navigator API
The simplest way to see what your browser reveals is directly querying the Navigator API. Create a test HTML file:
<!DOCTYPE html>
<html>
<head><title>Browser Fingerprint Audit</title></head>
<body>
<h1>Navigator Properties</h1>
<pre id="output"></pre>
<script>
const nav = navigator;
const properties = [
'userAgent', 'platform', 'language', 'languages',
'hardwareConcurrency', 'deviceMemory', 'cookieEnabled',
'doNotTrack', 'timezone'
];
let output = properties.map(prop => {
const value = nav[prop] !== undefined ? nav[prop] : 'Not available';
return `${prop}: ${JSON.stringify(value)}`;
}).join('\n');
document.getElementById('output').textContent = output;
</script>
</body>
</html>
Open this file in your browser and examine the output. You’ll likely see your exact browser version, operating system, and language preferences exposed.
Step 3 - Querying Screen Properties
Screen information adds another fingerprinting vector. Query the Screen API:
const screenInfo = {
width: screen.width,
height: screen.height,
availWidth: screen.availWidth,
availHeight: screen.availHeight,
colorDepth: screen.colorDepth,
pixelRatio: window.devicePixelRatio
};
console.table(screenInfo);
These values reveal your monitor resolution, whether taskbars are visible, and your display configuration. Multiple monitors or unusual resolutions make you more identifiable.
Step 4 - Extracting GPU Information
Graphics card details are particularly valuable for fingerprinting. Use WebGL:
function getGpuInfo() {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) return { error: 'WebGL not supported' };
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
if (!debugInfo) return { error: 'Debug info not available' };
return {
vendor: gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL),
renderer: gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)
};
}
console.log(getGpuInfo());
This exposes your exact graphics card model. Combined with your CPU and screen resolution, this creates a highly unique fingerprint.
Step 5 - Canvas Fingerprinting Test
Canvas fingerprinting works by drawing a hidden image and extracting its hash. Different browsers and GPUs render slightly differently, creating a unique signature:
function getCanvasFingerprint() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 200;
canvas.height = 50;
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();
}
const fingerprint = getCanvasFingerprint();
console.log('Canvas hash:', fingerprint.slice(0, 50) + '...');
The resulting data URL differs between browsers and devices, even when running the same code.
Step 6 - Font Detection
Installed fonts provide another fingerprinting vector. This technique works by measuring text width with different font families:
function detectFonts(baseFonts, testFonts) {
const span = document.createElement('span');
span.innerHTML = 'mmmmmmmmmmlli';
span.style.fontSize = '72px';
span.style.position = 'absolute';
span.style.left = '-9999px';
document.body.appendChild(span);
const detected = [];
baseFonts.forEach(font => {
span.style.fontFamily = font;
const baseWidth = span.offsetWidth;
testFonts.forEach(testFont => {
span.style.fontFamily = `'${testFont}', ${font}`;
if (span.offsetWidth !== baseWidth) {
detected.push(testFont);
}
});
});
document.body.removeChild(span);
return detected;
}
const baseFonts = ['monospace', 'sans-serif', 'serif'];
const testFonts = ['Arial', 'Helvetica', 'Times New Roman', 'Courier New', 'Verdana', 'Georgia'];
console.log('Detected fonts:', detectFonts(baseFonts, testFonts));
This reveals which fonts you have installed, and the specific combination is highly identifying.
Step 7 - WebRTC Leak Detection
WebRTC can expose your real IP address even behind a VPN:
async function checkWebRTC() {
const rtc = new RTCPeerConnection({ iceServers: [] });
return new Promise((resolve) => {
rtc.createDataChannel('');
rtc.onicecandidate = (e) => {
if (e.candidate) {
const candidate = e.candidate.candidate;
const ipMatch = candidate.match(/(\d{1,3}\.){3}\d{1,3}/);
if (ipMatch) {
resolve({ ip: ipMatch[0], full: candidate });
rtc.close();
}
}
};
rtc.createOffer().then(o => rtc.setLocalDescription(o));
setTimeout(() => {
resolve({ error: 'No WebRTC leak detected within timeout' });
rtc.close();
}, 2000);
});
}
checkWebRTC().then(result => console.log('WebRTC result:', result));
If this returns an IP address that differs from your VPN’s IP, you have a WebRTC leak.
Step 8 - Use Existing Fingerprinting Test Sites
While building your own tests provides the deepest understanding, several established tools audit browser fingerprinting:
Panopticlick (EFF Cover Your Tracks) tests how unique your browser is based on exposed attributes, higher uniqueness means easier tracking. AmIUnique is an European project that analyzes fingerprint data and provides a detailed breakdown of identifying attributes. BrowserLeaks covers canvas, WebGL, audio, and WebRTC fingerprinting vectors.
These tools compare your fingerprint against a database to calculate your uniqueness score.
Step 9 - Reducing Your Digital Footprint
After auditing what your browser reveals, consider these hardening steps:
Privacy-focused browsers, Firefox with the arkenfox configuration, Brave, or Tor Browser, block many fingerprinting vectors by default. Tor Browser can disable JavaScript entirely, though many sites will break; use the NoScript extension for granular control.
Firefox 128+ includes resistFingerprinting, which normalizes many exposed values. Enable it in about:config:
privacy.resistFingerprinting = true
Disable WebRTC in browser settings or use an extension that blocks the leak.
Troubleshooting
Configuration changes not taking effect
Restart the relevant service or application after making changes. Some settings require a full system reboot. Verify the configuration file path is correct and the syntax is valid.
Permission denied errors
Run the command with sudo for system-level operations, or check that your user account has the necessary permissions. On macOS, you may need to grant terminal access in System Settings > Privacy & Security.
Connection or network-related failures
Check your internet connection and firewall settings. If using a VPN, try disconnecting temporarily to isolate the issue. Verify that the target server or service is accessible from your network.
Frequently Asked Questions
How long does it take to check what your browser reveals: a developer guide?
For a straightforward setup, expect 30 minutes to 2 hours depending on your familiarity with the tools involved. Complex configurations with custom requirements may take longer. Having your credentials and environment ready before starting saves significant time.
What are the most common mistakes to avoid?
The most frequent issues are skipping prerequisite steps, using outdated package versions, and not reading error messages carefully. Follow the steps in order, verify each one works before moving on, and check the official documentation if something behaves unexpectedly.
Do I need prior experience to follow this guide?
Basic familiarity with the relevant tools and command line is helpful but not strictly required. Each step is explained with context. If you get stuck, the official documentation for each tool covers fundamentals that may fill in knowledge gaps.
Can I adapt this for a different tech stack?
Yes, the underlying concepts transfer to other stacks, though the specific implementation details will differ. Look for equivalent libraries and patterns in your target stack. The architecture and workflow design remain similar even when the syntax changes.
Where can I get help if I run into issues?
Start with the official documentation for each tool mentioned. Stack Overflow and GitHub Issues are good next steps for specific error messages. Community forums and Discord servers for the relevant tools often have active members who can help with setup problems.
Related Articles
- How To Check Your Browser Fingerprint Uniqueness Score Onlin
- Best Browser for Avoiding Google Tracking: A Developer Guide
- Best Browser for iOS Privacy 2026: A Developer Guide
- Best Browser for Streaming Privacy 2026: A Developer Guide
- Best Lightweight Private Browser 2026: A Developer Guide
- AI Coding Assistant Session Data Lifecycle
Built by theluckystrike. More at zovo.one