Created
May 20, 2019 09:04
-
-
Save mooyoul/f07b6ec6919eba357dc702afa710e6e6 to your computer and use it in GitHub Desktop.
Fingerprint2 with Puppeteer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const debug = require('debug'); | |
const puppeteer = require('puppeteer'); | |
const log = debug('script'); | |
log.enabled = true; | |
const ALLOWED_COMPONENT_KEYS = ['canvas', 'webgl', 'audio'].reduce((hash, v) => { | |
hash[v] = true; | |
return hash; | |
}, Object.create(null)); | |
const getFingerprint = async (options) => { | |
const browser = await puppeteer.launch({ | |
defaultViewport: options.viewport, | |
args: [`--user-agent=${options.userAgent}`], | |
}); | |
const page = await browser.newPage(); | |
await page.evaluateOnNewDocument((platform) => { | |
Object.defineProperties(navigator, { | |
platform: { | |
get() { return platform; } | |
}, | |
}); | |
}, options.platform); | |
await page.goto('https://google.com'); | |
await new Promise((resolve) => setTimeout(resolve, 1000)); | |
const fingerprint = await page.evaluate((allowedKeys) => { | |
return new Promise((resolve, reject) => { | |
const s = document.createElement('script'); | |
s.src = 'https://cdnjs.cloudflare.com/ajax/libs/fingerprintjs2/2.1.0/fingerprint2.min.js'; | |
s.type = 'text/javascript'; | |
s.onload = () => { | |
s.onload = s.onerror = null; | |
Fingerprint2.get((components) => { | |
const hash = Fingerprint2.x64hash128(components.map((c) => c.value).join(''), 31); | |
const safeHash = Fingerprint2.x64hash128(components.filter((c) => allowedKeys[c.key]).map((c) => c.value).join(''), 31); | |
resolve({ components, hash, safeHash }); | |
}); | |
}; | |
s.onerror = (e) => { | |
s.onload = s.onerror = null; | |
reject(e); | |
}; | |
document.body.appendChild(s); | |
}); | |
}, ALLOWED_COMPONENT_KEYS); | |
await browser.close(); | |
return fingerprint; | |
}; | |
(async () => { | |
const MAX_SAMPLES = 5; | |
const options = [{ | |
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36', | |
platform: 'MacIntel', | |
viewport: { width: 1280, height: 720, deviceScaleFactor: 2, isMobile: false, hasTouch: false }, | |
}, { | |
userAgent: 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36', | |
platform: 'Win32', | |
viewport: { width: 1920, height: 1080, deviceScaleFactor: 1, isMobile: false, hasTouch: true }, | |
}]; | |
for (let i = 1 ; i <= MAX_SAMPLES ; i++) { | |
log('testing %d of %d', i, MAX_SAMPLES); | |
for (const option of options) { | |
log('using option: %O', option); | |
const fingerprint = await getFingerprint(option); | |
log('Hash (all possible components): %s', fingerprint.hash); | |
log('Hash (selected components): %s', fingerprint.safeHash); | |
} | |
} | |
})().catch(log); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment