UNPKG

browser-canvas-fingerprinting

Version:

A simple canvas fingerprinting implementation in browser with specific information used to generate fingerprint

52 lines (51 loc) 4.24 kB
import getFonts from './font.js'; import { getWebGLInfo, createWebGLFingerprint } from './webgl.js'; import { keyCount } from './util.js'; import { isExtensionFuckingCanvas } from './detection.js'; export default async function data() { function getErrorMessage(f, useStack = false) { try { return f() } catch (e) { return (useStack ? e.stack : String(e)) } } async function getErrorMessageAsync(f, useStack = false) { try { return await f() } catch (e) { return (useStack ? e.stack : String(e)) } } function causeRefError() { const rand = Math.random().toString().substring(2); return getErrorMessage(() => (new Function('a' + rand))()).replace(rand, '<R>'); } function causeTypeError() { const rand = Math.random().toString().substring(2); return getErrorMessage(() => globalThis[rand]["//"].b).replace(rand, '<R>'); } function purifyConcurrency() { const value = globalThis.navigator.hardwareConcurrency; if (!value || (value % 2)) return 'N/A'; return value; // but still useless when fighting with JShelter... } const isExt = await isExtensionFuckingCanvas(); const { vendor, renderer } = getWebGLInfo(); return [ `Emojis: \u{1F601}\u{1F602}\u{1F603}\u{1F604}\u{1F60C}\u{1F60F}\u{1F612}\u{1F621}\u{1F631}\u{1F628}`, `Special chars (Unicode): \u2060\u200B\u25CF\u25CB\u25D0\u25D1\u25D2\u25D3\u2605\u2606\u2724\u2726\u2736\u2737\u272A\u272B\u272F\u2730\u2742\u25C6\u25C8\u25B6\u25C0\u25B2\u25BC\u25BA\u25C4\u27A4\u27A5\u27A1\u27A2\u2740\u273F\u2741\u273E\u2668\u266A\u266B\u2669\u2704\u2702\u2701\u2706\u2709\u2756\u2726\u2727\u221E\u2763\u2765\u2719\u271A\u271C\u271B\u2020\u2021`, `Zalgo: \u0334\u0322\u031B\u031B\u0317\u0318Z\u0337\u034C\u035D\u030B\u0310\u0344\u030C\u0344\u035D\u0313\u0346\u0344\u035D\u033F\u030F\u035D\u033F\u035D\u035D\u030F\u033F\u030F\u035D\u033F\u035D\u030F\u033F\u035Da\u0335\u031B\u030C\u0344\u035D\u033F\u030F\u035D\u033F\u035D\u030F\u033F\u035Dl\u0336\u034C\u035D\u030B\u0310\u0344\u030C\u0344\u035D\u0313\u0346\u0344\u035D\u033F\u030F\u035D\u033Fg\u0337\u034C\u035D\u030B\u0310\u0344\u030C\u0344\u035D\u0313\u0346\u0344\u035D\u033F\u030F\u035D\u033Fo\u0334\u0322\u031B\u031B\u0317\u0318 \u0334\u0322\u031B\u031B\u0317\u0318T\u0337\u034C\u035D\u030B\u0310\u0344\u030C\u0344\u035D\u0313\u0346\u0344\u035D\u033F\u030F\u035D\u033Fe\u0335\u031B\u030C\u0344\u035D\u033F\u030F\u035D\u033F\u035D\u030F\u033F\u035Dx\u0336\u034C\u035D\u030B\u0310\u0344\u030C\u0344\u035D\u0313\u0346\u0344\u035D\u033F\u030F\u035D\u033Ft\u0337\u034C\u035D\u030B\u0310\u0344\u030C\u0344\u035D\u0313\u0346\u0344\u035D\u033F\u030F\u035D\u033F`, `User-Agent: ${globalThis.navigator.userAgent}`, `Platform: ${globalThis.navigator.platform}`, `Languages: ${globalThis.navigator.languages}`, `Cookies enabled: ${globalThis.navigator.cookieEnabled}`, `Navigator properties count: ${keyCount(globalThis.navigator)}`, `Timezone: ${getErrorMessage(() => globalThis.Intl.DateTimeFormat().resolvedOptions().timeZone)}`, `Fonts: ${getFonts()}`, `Hardware Concurrency: ${isExt ? 'Ignored due to extension activity' : purifyConcurrency()}`, `Plugins: ${navigator.plugins ? (Array.from(navigator.plugins).map(p => p.name).join(', ')) : 'unknown'}`, `Screen: ${screen.width}x${screen.height}, Depth: ${screen.colorDepth}bit`, `Available Screen: ${screen.availWidth}x${screen.availHeight}`, `Max Touch Points: ${isExt ? 'Ignored due to extension activity' : globalThis.navigator.maxTouchPoints}`, `WebGL Vendor: ${vendor}`, `WebGL Renderer: ${renderer}`, `WebGL Fingerprint: ${await createWebGLFingerprint()}`, `Support navigation API: ${globalThis.navigation}`, `Support WebXR API: ${globalThis.navigator.xr}`, `Support WebGPU API: ${globalThis.navigator.gpu}`, `Browser error message: ${causeTypeError()};${causeRefError()};${getErrorMessage(() => customElements.define())};${getErrorMessage(() => new Function("';|+_<"))};${await getErrorMessageAsync(() => crypto.subtle.encrypt())};${getErrorMessage(() => structuredClone(globalThis))}`, ]; }