Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Privacy 2024: fingerprinting test #121

94 changes: 88 additions & 6 deletions dist/privacy.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,22 +321,104 @@ return JSON.stringify({
'geolocation.+watchPosition'
),
},

fingerprinting: (() => {
//These are determined by looking at the tests in https://github.com/fingerprintjs/fingerprintjs
const fingerprintingAPIs = [
'ApplePaySession.canMakePayments',
'getChannelData', //audioContext
'toDataURL', //canvas
'getImageData', //canvas, not actually used by fingerprintJS
'screen.colorDepth',
'color-gamut',
'prefers-contrast',
'cpuClass',
'deviceMemory',
'forced-colors',
'hardwareConcurrency',
'dynamic-range',
'indexedDB',
'inverted-colors',
'navigator.language', //"language" would be too generic here
'navigator.userLanguage', //TODO exists?
'localStorage',
'min-monochrome',
'max-monochrome',
'openDatabase',
'navigator.oscpu',
'pdfViewerEnabled',
'navigator.platform', //"platform" would be too generic
'navigator.plugins',
'attributionSourceId',
'prefers-reduced-motion',
'prefers-reduced-transparency',
'availWidth',
'availHeight',
'screen.width',
'screen.height',
'sessionStorage',
'resolvedOptions().timeZone',
'getTimezoneOffset',
'maxTouchPoints',
'ontouchstart',
'navigator.vendor',
'vendorUnmasked',
'rendererUnmasked',
'shadingLanguageVersion',
'WEBGL_debug_renderer_info',
'getShaderPrecisionFormat'
].map(api => api.toLowerCase())

const response_bodies = $WPT_BODIES.filter(body => (body.response_body && (body.type === 'Document' || body.type === 'Script')))

let fingerprintingUsageCounts = {}
let likelyFingerprintingScripts = []

response_bodies.forEach(req => {
let total_occurrences = 0

let body = req.response_body.toLowerCase()

fingerprintingAPIs.forEach(api => {
let api_occurrences = 0
let index = body.indexOf(api)
while (index !== -1) {
api_occurrences++
index = body.indexOf(api, index + 1)
}

if (api_occurrences > 0) {
fingerprintingUsageCounts[api] = (fingerprintingUsageCounts[api] || 0) + api_occurrences
}
total_occurrences += api_occurrences
})

if (total_occurrences >= 5) { //TODO what should this threshold be?
likelyFingerprintingScripts.push(req.url)
}
})

return {counts: fingerprintingUsageCounts, likelyFingerprintingScripts}
})(),

/**
* List of hostnames with CNAME record
*/
request_hostnames_with_cname: (() => {
let results = {};

for (const request of $WPT_REQUESTS) {
request_hostname = (new URL(request.url)).hostname;
try {
tunetheweb marked this conversation as resolved.
Show resolved Hide resolved
request_hostname = (new URL(request.url)).hostname;

for (const [origin, dns_info] of Object.entries($WPT_DNS)) {
dns_hostname = (new URL(origin)).hostname;
for (const [origin, dns_info] of Object.entries($WPT_DNS)) {
dns_hostname = (new URL(origin)).hostname;

if (request_hostname == dns_hostname && request_hostname !== dns_info.results.canonical_names[0]) {
results[dns_hostname] = dns_info.results.canonical_names;
if (request_hostname == dns_hostname && request_hostname !== dns_info.results.canonical_names[0]) {
results[dns_hostname] = dns_info.results.canonical_names;
}
}
}
} catch {}
}

return results;
Expand Down