@@ -288,159 +288,6 @@ let sync_metrics = {
288288 return rp ;
289289 } ) ( ) ,
290290
291- fingerprinting : ( ( ) => {
292- // The APIs are determined by looking at the tests in https://github.com/fingerprintjs/fingerprintjs and https://amiunique.org/fingerprint
293- // Grouped by unique API to improve diversity metric reliability
294- const fingerprintingAPIs = {
295- // Payment APIs
296- 'payment' : 'ApplePaySession\.canMakePayments' ,
297-
298- // User Agent and Platform fingerprinting
299- 'navigator_userAgent' : 'navigator\.userAgent' ,
300- 'navigator_platform' : 'navigator\.platform' ,
301- 'navigator_oscpu' : 'navigator\.oscpu' ,
302- 'navigator_vendor' : 'navigator\.(vendor|vendorSub)' ,
303- 'navigator_product' : 'navigator\.(product|productSub)' ,
304- 'navigator_buildID' : 'navigator\.buildID' ,
305-
306- // Audio fingerprinting
307- 'audio_context' : '(AudioContext|webkitAudioContext)' ,
308- 'audio_analysis' : '(createAnalyser|AnalyserNode|getFloatFrequencyData|getByteFrequencyData|fftSize|frequencyBinCount|maxDecibels|minDecibels|smoothingTimeConstant)' ,
309- 'audio_processing' : '(createOscillator|OscillatorNode|createScriptProcessor|createDynamicsCompressor)' ,
310- 'audio_data' : '(getChannelData|channelCount|channelCountMode|channelInterpretation|sampleRate)' ,
311-
312- // Canvas fingerprinting
313- 'canvas_context' : 'canvas\.getContext|getContext\(.*(2d|webgl).*\)' ,
314- 'canvas_rendering' : '(canvasRenderingContext2D\.(fillText|strokeText|getImageData)|canvas\.toDataURL|HTMLCanvasElement\.toBlob)' ,
315-
316- // CSS media queries for fingerprinting
317- 'css_media_queries' : '@media.*(color-gamut|prefers-contrast|forced-colors|dynamic-range|inverted-colors|min-monochrome|max-monochrome|prefers-reduced-motion|prefers-reduced-transparency)' ,
318-
319- // Hardware fingerprinting
320- 'hardware_info' : '(cpuClass|deviceMemory|hardwareConcurrency|maxTouchPoints)' ,
321-
322- // Touch capabilities
323- 'touch_capabilities' : '(ontouchstart|TouchEvent|createTouch|createTouchList)' ,
324-
325- // Storage APIs (potential fingerprinting)
326- 'storage_apis' : '(indexedDB|localStorage|sessionStorage|openDatabase)' ,
327-
328- // PDF and plugins
329- 'plugins' : '(pdfViewerEnabled|navigator\.(plugins|mimeTypes)|Plugin\s|MimeType)' ,
330-
331- // Attribution and tracking
332- 'attribution' : 'attributionSourceId' ,
333-
334- // Time zone and language fingerprinting
335- 'timezone' : '(resolvedOptions\(\)\.timeZone|getTimezoneOffset)' ,
336- 'language' : '(navigator\.(language|languages)|Intl\.(DateTimeFormat|Collator))' ,
337-
338- // WebGL fingerprinting
339- 'webgl_info' : '(vendorUnmasked|rendererUnmasked|shadingLanguageVersion|WEBGL_debug_renderer_info|WebGLRenderingContext)' ,
340- 'webgl_params' : '(getShaderPrecisionFormat|getParameter|getSupportedExtensions|getExtension|VENDOR|RENDERER|VERSION|SHADING_LANGUAGE_VERSION)' ,
341-
342- // Screen properties
343- 'screen_properties' : '(availWidth|availHeight)|screen\.(width|height|colorDepth|pixelDepth|availTop|availLeft)|(outerWidth|outerHeight|innerWidth|innerHeight)|devicePixelRatio' ,
344-
345- // Window and browser chrome fingerprinting
346- 'browser_chrome' : '(locationbar|menubar|personalbar|scrollbars|statusbar|toolbar|history\.length)' ,
347-
348- // Geolocation API
349- 'geolocation' : '(getCurrentPosition|watchPosition|navigator\.geolocation)' ,
350-
351- // Media devices and capabilities
352- 'media_devices' : '(enumerateDevices|getUserMedia|getDisplayMedia|navigator\.mediaDevices)' ,
353- 'media_capabilities' : '(canPlayType|HTMLVideoElement\.canPlayType|HTMLAudioElement\.canPlayType)' ,
354-
355- // Permissions API
356- 'permissions' : '(navigator\.permissions|permissions\.query)' ,
357-
358- // Battery API
359- 'battery' : '(navigator\.(battery|getBattery)|charging|chargingTime|dischargingTime)' ,
360-
361- // Connection API
362- 'connection' : '(navigator\.(connection|mozConnection|webkitConnection)|downlink|effectiveType)' ,
363-
364- // Sensors APIs
365- 'sensors' : '(Accelerometer|Gyroscope|LinearAccelerationSensor|AbsoluteOrientationSensor|RelativeOrientationSensor|AmbientLightSensor|ProximitySensor)' ,
366-
367- // Font detection
368- 'fonts' : '(document\.fonts|FontFace)' ,
369-
370- // Do Not Track
371- 'do_not_track' : '(navigator\.doNotTrack|window\.doNotTrack)' ,
372-
373- // Cookie detection
374- 'cookies' : 'navigator\.cookieEnabled' ,
375-
376- // Java detection
377- 'java' : 'navigator\.javaEnabled' ,
378-
379- // WebRTC
380- 'webrtc_peer' : '(RTCPeerConnection|webkitRTCPeerConnection|mozRTCPeerConnection)' ,
381- 'webrtc_data' : '(RTCDataChannel|createDataChannel)' ,
382-
383- // Performance APIs
384- 'performance' : '(performance\.(memory|timing))' ,
385-
386- // Notifications
387- 'notifications' : 'Notification\.permission' ,
388-
389- // Keyboard layout detection
390- 'keyboard' : '(KeyboardLayoutMap|navigator\.keyboard|getLayoutMap)' ,
391-
392- // Gamepad API
393- 'gamepad' : '(navigator\.getGamepads|GamepadEvent)' ,
394-
395- // Storage quota
396- 'storage_quota' : '(navigator\.(storage|webkitTemporaryStorage|webkitPersistentStorage)|estimate)' ,
397-
398- // Speech APIs
399- 'speech' : '(SpeechSynthesis|SpeechRecognition)' ,
400-
401- // Crypto subtle fingerprinting
402- 'crypto' : '(crypto\.subtle|SubtleCrypto)' ,
403-
404- // Worker capabilities
405- 'workers' : '(Worker|SharedWorker|ServiceWorker)'
406- } ;
407-
408- // Pre-compile regexes - handle already escaped patterns
409- const compiledRegexes = Object . entries ( fingerprintingAPIs ) . map ( ( [ apiName , pattern ] ) => ( {
410- api : apiName ,
411- regex : new RegExp ( pattern , 'gi' )
412- } ) ) ;
413- let likelyFingerprintingScripts = [ ] ;
414-
415- response_bodies . forEach ( req => {
416- try {
417- let detectedApis = [ ] ;
418-
419- compiledRegexes . forEach ( ( { api, regex } ) => {
420- try {
421- if ( regex . test ( req . response_body ) ) {
422- detectedApis . push ( api ) ;
423- }
424- } catch ( regexError ) {
425- // Skip this API on regex error - avoid console.warn in WebPageTest
426- }
427- } ) ;
428-
429- // Track scripts with significant fingerprinting API usage
430- if ( detectedApis . length >= 5 ) {
431- likelyFingerprintingScripts . push ( {
432- url : req . url ,
433- detectedApis
434- } ) ;
435- }
436- } catch ( error ) {
437- // Skip this request on error - avoid console.warn in WebPageTest
438- }
439- } ) ;
440-
441- return likelyFingerprintingScripts ;
442- } ) ( ) ,
443-
444291 /**
445292 * List of hostnames with CNAME record
446293 */
0 commit comments