You think you're sneaky, but we have your fingerprints
December 12, 2024
Someone was asking how websites can tell that you're still YOU even when using a VPN and incognito mode. There's an artform to the idea of “fingerprinting” your browser, and I'm honestly surprised how much detail your can get just using Javascript to form a fingerprint of someone's system:
{
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10\_15\_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"language": "en-US",
"languages": [
"en-US",
"en",
"en-GB"
],
"vendor": "Google Inc.",
"platform": "MacIntel",
"screen": {
"width": 1440,
"height": 900,
"colorDepth": 24
},
"timezone": "America/Los\_Angeles",
"plugins": [
"PDF Viewer",
"Chrome PDF Viewer",
"Chromium PDF Viewer",
"Microsoft Edge PDF Viewer",
"WebKit built-in PDF"
],
"touchPoints": 0,
"hardwareConcurrency": 4,
"memory": 8,
"gl": "ANGLE (Intel Inc., Intel(R) HD Graphics 6000, OpenGL 4.1)",
"graphic": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAI..."
}
Most of this is just from the browser API, although the last two are digging a little deeper reading the graphics rendering properties and creating an image -- I truncated the 'graphic' element for this article, but assume memory, cpu, and other unique configs on your computer will render the same image just slightly differently. Add these all together and you can get a semi-reasonable fingerprint. Not perfect, but pretty unique.
Her's the actual javascript I ran to get that output:
async function getFingerprint() {
const fingerprint = {
userAgent: navigator.userAgent,
language: navigator.language,
languages: navigator.languages,
vendor: navigator.vendor,
platform: navigator.platform,
screen: {
width: screen.width,
height: screen.height,
colorDepth: screen.colorDepth,
},
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
plugins: Array.from(navigator.plugins).map(plugin => plugin.name),
touchPoints: navigator.maxTouchPoints,
hardwareConcurrency: navigator.hardwareConcurrency,
memory: navigator.deviceMemory \|\| 'unknown',
};
// WebGL Fingerprint
const canvas2 = document.createElement('canvas');
const gl = canvas2.getContext('webgl') \|\| canvas2.getContext('experimental-webgl');
if (gl) {
const debugInfo = gl.getExtension('WEBGL\_debug\_renderer\_info');
fingerprint.gl = debugInfo ? gl.getParameter(debugInfo.UNMASKED\_RENDERER\_WEBGL) : 'unknown';
} else {
fingerprint.gl = 'no-webgl';
}
// Graphics rendering fingerprint (Canvas)
const canvas1 = document.createElement('canvas');
const ctx = canvas1.getContext('2d');
ctx.textBaseline = 'top';
ctx.font = '16px Arial';
ctx.fillText('Browser fingerprinting!', 10, 50);
fingerprint.graphic = canvas1.toDataURL();
// Hash the fingerprint for uniqueness
const encoder = new TextEncoder();
const data = encoder.encode(JSON.stringify(fingerprint));
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
console.log(fingerprint); // Debugging purpose
return { hash: hashHex, fingerprint };
}
If you want to probe even more, which means edging closer to that ethical privacy line, you can include a user gesture (you know, like "I am a Human" checkbox). Once you click on somehting in a website, you imply consent for other things… oh and there are a number of navigator items I didn't include in this script because you need https to access them, and I'm working on my local today…
The point is, you THINK you're keeping private, but in reality, we leak details about ourselves and create footprints that can be followed even when we think we're being sneaky…
Your resume is your most valuable tool in your job search. But how do you know your resume is in top shape?
Our recruiters will review your resume line by line and give you detailed feedback on how you can improve it.
Visit mjlprojects.com to learn more!


