jumpy-lion 0.0.33 → 0.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-controller.d.ts +2 -2
- package/dist/browser-controller.d.ts.map +1 -1
- package/dist/browser-controller.js +34 -5
- package/dist/browser-controller.js.map +1 -1
- package/dist/browser-plugin.d.ts +21 -0
- package/dist/browser-plugin.d.ts.map +1 -1
- package/dist/browser-plugin.js +10 -4
- package/dist/browser-plugin.js.map +1 -1
- package/dist/browser-process/browser.d.ts +15 -0
- package/dist/browser-process/browser.d.ts.map +1 -1
- package/dist/browser-process/browser.js +6 -3
- package/dist/browser-process/browser.js.map +1 -1
- package/dist/crawler.d.ts +15 -0
- package/dist/crawler.d.ts.map +1 -1
- package/dist/crawler.js.map +1 -1
- package/dist/fingerprinting/anti-webgpu/background.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/background.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/background.js +6 -0
- package/dist/fingerprinting/anti-webgpu/background.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/inject.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/inject.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/inject.js +50 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/inject.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/page_context/inject.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/page_context/inject.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/page_context/inject.js +179 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/page_context/inject.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/popup/popup.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/data/popup/popup.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/popup/popup.js +95 -0
- package/dist/fingerprinting/anti-webgpu/data/popup/popup.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/chrome.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/lib/chrome.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/chrome.js +255 -0
- package/dist/fingerprinting/anti-webgpu/lib/chrome.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/common.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/lib/common.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/common.js +87 -0
- package/dist/fingerprinting/anti-webgpu/lib/common.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/config.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/lib/config.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/config.js +13 -0
- package/dist/fingerprinting/anti-webgpu/lib/config.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/runtime.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/lib/runtime.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/runtime.js +109 -0
- package/dist/fingerprinting/anti-webgpu/lib/runtime.js.map +1 -0
- package/dist/fingerprinting/fingerprint-injector.d.ts +85 -1
- package/dist/fingerprinting/fingerprint-injector.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-injector.js +188 -90
- package/dist/fingerprinting/fingerprint-injector.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.js +87 -0
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.js +95 -0
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.js +96 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.d.ts +7 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.js +219 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts +19 -0
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/index.js +19 -0
- package/dist/fingerprinting/fingerprint-overrides/index.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js +262 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.d.ts +7 -0
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.js +103 -0
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.js +228 -0
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts +20 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js +227 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js +84 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js +440 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js +95 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts +12 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js +167 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.js +205 -0
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js +96 -0
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/page.d.ts +1 -0
- package/dist/page.d.ts.map +1 -1
- package/dist/page.js +42 -1
- package/dist/page.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -3
|
@@ -1,6 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced CDP Fingerprint Injector for 2025
|
|
3
|
+
*
|
|
4
|
+
* This module provides advanced fingerprint spoofing and anti-detection capabilities
|
|
5
|
+
* specifically designed to bypass hardcore fingerprinting techniques used in 2025.
|
|
6
|
+
*
|
|
7
|
+
* Key Features:
|
|
8
|
+
*
|
|
9
|
+
* 1. **WebGPU Fingerprinting Protection**:
|
|
10
|
+
* - Spoofs GPU adapter information and capabilities
|
|
11
|
+
* - Fakes GPU uptime to appear as if the GPU has been running for 24-72 hours
|
|
12
|
+
* - Intercepts timestamp queries to prevent timing-based detection
|
|
13
|
+
*
|
|
14
|
+
* 2. **Platform Consistency (1:1 Fingerprinting)**:
|
|
15
|
+
* - Ensures all browser properties match the specified platform (Win32, MacIntel, Linux)
|
|
16
|
+
* - Synchronizes navigator properties, screen metrics, and WebGL/WebGPU values
|
|
17
|
+
* - Platform-specific GPU configurations for realistic fingerprints
|
|
18
|
+
*
|
|
19
|
+
* 3. **Runtime.enable Bypass**:
|
|
20
|
+
* - Prevents CDP detection through console.log(Error) technique
|
|
21
|
+
* - Intercepts and blocks Runtime.enable calls
|
|
22
|
+
* - Modifies Error stack traces to hide automation
|
|
23
|
+
*
|
|
24
|
+
* 4. **Advanced Canvas Protection**:
|
|
25
|
+
* - Adds controlled noise to canvas operations
|
|
26
|
+
* - Protects against both 2D and WebGL canvas fingerprinting
|
|
27
|
+
* - Includes font measurement variations
|
|
28
|
+
*
|
|
29
|
+
* 5. **WebRTC IP Leak Prevention**:
|
|
30
|
+
* - Filters STUN servers to prevent IP leaks
|
|
31
|
+
* - Provides fake but consistent device IDs
|
|
32
|
+
* - Modifies ICE candidates and statistics
|
|
33
|
+
*
|
|
34
|
+
* 6. **Audio Context Spoofing**:
|
|
35
|
+
* - Adds noise to audio processing to prevent fingerprinting
|
|
36
|
+
* - Works with both AudioContext and OfflineAudioContext
|
|
37
|
+
*
|
|
38
|
+
* 7. **Client Rect Variations**:
|
|
39
|
+
* - Adds small variations to getBoundingClientRect results
|
|
40
|
+
* - Makes automation harder to detect through DOM measurements
|
|
41
|
+
*
|
|
42
|
+
* 8. **Mouse Movement Humanization**:
|
|
43
|
+
* - Generates bezier curve movements instead of straight lines
|
|
44
|
+
* - Adds random variations to mouse paths
|
|
45
|
+
*
|
|
46
|
+
* Usage:
|
|
47
|
+
* ```typescript
|
|
48
|
+
* await CdpFingerprintInjector.injectFingerprint(page, fingerprint, {
|
|
49
|
+
* enableAdvancedStealth: true,
|
|
50
|
+
* bypassRuntimeEnable: true,
|
|
51
|
+
* platform: 'Win32', // Spoof as Windows for better evasion on Apify Linux
|
|
52
|
+
* spoofWebGL: true,
|
|
53
|
+
* spoofAudioContext: true,
|
|
54
|
+
* spoofClientRects: true,
|
|
55
|
+
* humanizeInteractions: true,
|
|
56
|
+
* spoofFonts: true, // New: Hide Linux-specific fonts
|
|
57
|
+
* spoofPerformance: true, // New: Windows-like timing characteristics
|
|
58
|
+
* spoofLocale: true, // New: Consistent Windows locale formatting
|
|
59
|
+
* useFingerprintDefaults: true // Use fingerprint-generator Windows values
|
|
60
|
+
* });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
1
63
|
import { log } from 'crawlee';
|
|
2
64
|
import { FingerprintInjector } from 'fingerprint-injector';
|
|
3
65
|
import { gotScraping } from 'got-scraping';
|
|
66
|
+
import { createStealthScript, createWebGLSpoofingScript, createAudioFingerprintSpoofingScript, createAdvancedCanvasProtectionScript, createClientRectSpoofingScript, createWebRTCSpoofingScript, createWebGPUSpoofingScript, createPlatformConsistencyScript, setupMouseMovementHumanization, setupRuntimeEnableBypass, createFontSpoofingScript, createPerformanceSpoofingScript, createLocaleSpoofingScript, createUAClientHintsSpoofingScript, } from './fingerprint-overrides/index.js';
|
|
4
67
|
export class CdpFingerprintInjector {
|
|
5
68
|
constructor(page) {
|
|
6
69
|
Object.defineProperty(this, "injector", {
|
|
@@ -18,6 +81,34 @@ export class CdpFingerprintInjector {
|
|
|
18
81
|
this.injector = new FingerprintInjector();
|
|
19
82
|
this.page = page;
|
|
20
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Get recommended settings for Apify platform
|
|
86
|
+
* These settings are optimized for running headful Chrome on Apify (Linux)
|
|
87
|
+
* but spoofed to appear as Windows for better anti-bot evasion
|
|
88
|
+
*/
|
|
89
|
+
static getApifyRecommendedSettings() {
|
|
90
|
+
return {
|
|
91
|
+
enableAdvancedStealth: true,
|
|
92
|
+
bypassRuntimeEnable: true,
|
|
93
|
+
platform: 'Win32', // Spoof as Windows instead of Linux for better evasion
|
|
94
|
+
spoofWebGL: true,
|
|
95
|
+
spoofAudioContext: true,
|
|
96
|
+
spoofClientRects: true,
|
|
97
|
+
humanizeInteractions: true,
|
|
98
|
+
detectTimezone: true, // Auto-detect timezone from proxy
|
|
99
|
+
// New advanced spoofing options for 2025
|
|
100
|
+
spoofFonts: true,
|
|
101
|
+
spoofPerformance: true,
|
|
102
|
+
spoofLocale: true,
|
|
103
|
+
useFingerprintDefaults: true, // Use fingerprint-generator Windows values
|
|
104
|
+
viewport: {
|
|
105
|
+
width: 1920,
|
|
106
|
+
height: 1080,
|
|
107
|
+
deviceScaleFactor: 1,
|
|
108
|
+
mobile: false,
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
21
112
|
static async injectFingerprint(page, fingerprint, options) {
|
|
22
113
|
const handler = new CdpFingerprintInjector(page);
|
|
23
114
|
return handler.attachToPage(fingerprint, options);
|
|
@@ -55,96 +146,42 @@ export class CdpFingerprintInjector {
|
|
|
55
146
|
timezoneId: timezone,
|
|
56
147
|
});
|
|
57
148
|
}
|
|
58
|
-
createStealthScript() {
|
|
59
|
-
return `
|
|
60
|
-
(() => {
|
|
61
|
-
'use strict';
|
|
62
|
-
|
|
63
|
-
// Helper functions
|
|
64
|
-
const wrapNative = (fnName) => {
|
|
65
|
-
return function() {
|
|
66
|
-
return \`function \${fnName}() { [native code] }\`;
|
|
67
|
-
};
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const hideErrorStack = () => {
|
|
71
|
-
const originalStackDescriptor = Object.getOwnPropertyDescriptor(Error.prototype, 'stack');
|
|
72
|
-
if (originalStackDescriptor?.configurable) {
|
|
73
|
-
Object.defineProperty(Error.prototype, 'stack', {
|
|
74
|
-
get() {
|
|
75
|
-
return 'Error\\n <anonymous>:1:1';
|
|
76
|
-
},
|
|
77
|
-
set() {},
|
|
78
|
-
configurable: false,
|
|
79
|
-
enumerable: false
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
const maskedStackGetter = Object.getOwnPropertyDescriptor(Error.prototype, 'stack').get;
|
|
83
|
-
if (maskedStackGetter) {
|
|
84
|
-
maskedStackGetter.toString = wrapNative('get stack');
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const patchConsole = () => {
|
|
90
|
-
const _console = window.console;
|
|
91
|
-
if (!_console || typeof _console !== 'object') return;
|
|
92
|
-
|
|
93
|
-
const transformArg = (arg) => {
|
|
94
|
-
try {
|
|
95
|
-
return arg && typeof arg === 'object' ? JSON.stringify(arg) : String(arg);
|
|
96
|
-
} catch {
|
|
97
|
-
return String(arg);
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
const createPatchedMethod = (originalFn, methodName) => {
|
|
102
|
-
const newFn = function(...args) {
|
|
103
|
-
const transformedArgs = args.map(transformArg);
|
|
104
|
-
return Function.prototype.apply.call(originalFn, _console, transformedArgs);
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
Object.defineProperty(newFn, 'toString', {
|
|
108
|
-
value: wrapNative(methodName),
|
|
109
|
-
writable: false,
|
|
110
|
-
enumerable: false,
|
|
111
|
-
configurable: true
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
return newFn;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
['log', 'warn', 'error', 'info', 'debug'].forEach(method => {
|
|
118
|
-
try {
|
|
119
|
-
const originalFn = _console[method];
|
|
120
|
-
if (originalFn && typeof originalFn === 'function') {
|
|
121
|
-
Object.defineProperty(_console, method, {
|
|
122
|
-
value: createPatchedMethod(originalFn, method),
|
|
123
|
-
writable: true,
|
|
124
|
-
enumerable: false,
|
|
125
|
-
configurable: true
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
} catch {}
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
Object.defineProperty(window, 'console', {
|
|
132
|
-
value: _console,
|
|
133
|
-
configurable: true,
|
|
134
|
-
writable: false,
|
|
135
|
-
enumerable: false
|
|
136
|
-
});
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
// Initialize protections
|
|
140
|
-
hideErrorStack();
|
|
141
|
-
patchConsole();
|
|
142
|
-
})();`;
|
|
143
|
-
}
|
|
144
149
|
async injectStealthProtections() {
|
|
145
|
-
const stealthScript =
|
|
150
|
+
const stealthScript = createStealthScript();
|
|
146
151
|
await this.page.client.Page.addScriptToEvaluateOnNewDocument({ source: stealthScript });
|
|
147
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Extract relevant data from fingerprint for overrides
|
|
155
|
+
*/
|
|
156
|
+
extractFingerprintData(fingerprint) {
|
|
157
|
+
const webglConfig = {};
|
|
158
|
+
const platformConfig = {};
|
|
159
|
+
// Extract WebGL data if available
|
|
160
|
+
if (fingerprint.webgl) {
|
|
161
|
+
webglConfig.vendor = fingerprint.webgl.vendor;
|
|
162
|
+
webglConfig.renderer = fingerprint.webgl.renderer;
|
|
163
|
+
webglConfig.vendorUnmasked = fingerprint.webgl.vendorUnmasked;
|
|
164
|
+
webglConfig.rendererUnmasked = fingerprint.webgl.rendererUnmasked;
|
|
165
|
+
}
|
|
166
|
+
// Extract platform data if available
|
|
167
|
+
if (fingerprint.navigator) {
|
|
168
|
+
platformConfig.platform = fingerprint.navigator.platform;
|
|
169
|
+
platformConfig.vendor = fingerprint.navigator.vendor;
|
|
170
|
+
platformConfig.vendorSub = fingerprint.navigator.vendorSub;
|
|
171
|
+
platformConfig.productSub = fingerprint.navigator.productSub;
|
|
172
|
+
platformConfig.hardwareConcurrency = fingerprint.navigator.hardwareConcurrency;
|
|
173
|
+
platformConfig.maxTouchPoints = fingerprint.navigator.maxTouchPoints;
|
|
174
|
+
platformConfig.language = fingerprint.navigator.language;
|
|
175
|
+
platformConfig.languages = fingerprint.navigator.languages;
|
|
176
|
+
platformConfig.oscpu = fingerprint.navigator.oscpu;
|
|
177
|
+
}
|
|
178
|
+
if (fingerprint.screen) {
|
|
179
|
+
platformConfig.devicePixelRatio = fingerprint.screen.devicePixelRatio;
|
|
180
|
+
platformConfig.screenDepth = fingerprint.screen.pixelDepth;
|
|
181
|
+
platformConfig.colorDepth = fingerprint.screen.colorDepth;
|
|
182
|
+
}
|
|
183
|
+
return { webglConfig, platformConfig };
|
|
184
|
+
}
|
|
148
185
|
async attachToPage(browserFingerprintWithHeaders, options) {
|
|
149
186
|
const { fingerprint, headers } = browserFingerprintWithHeaders;
|
|
150
187
|
const shouldFetchTimezone = options?.timezone || options?.detectTimezone;
|
|
@@ -163,15 +200,76 @@ export class CdpFingerprintInjector {
|
|
|
163
200
|
// Main script from fingerprint-injector
|
|
164
201
|
// @ts-expect-error Using private
|
|
165
202
|
const fingerprintScript = this.injector.getInjectableFingerprintFunction(enhancedFingerprint);
|
|
203
|
+
// Prepare all scripts to inject
|
|
204
|
+
const scriptsToInject = [fingerprintScript];
|
|
205
|
+
// Always inject base stealth protections
|
|
206
|
+
await this.injectStealthProtections();
|
|
207
|
+
// Extract fingerprint data if we should use it
|
|
208
|
+
const shouldUseFingerprintData = options?.useFingerprintDefaults !== false;
|
|
209
|
+
const { webglConfig, platformConfig } = shouldUseFingerprintData
|
|
210
|
+
? this.extractFingerprintData(fingerprint)
|
|
211
|
+
: { webglConfig: undefined, platformConfig: undefined };
|
|
212
|
+
// Add advanced features based on options
|
|
213
|
+
if (options?.enableAdvancedStealth !== false) {
|
|
214
|
+
// UA Client Hints spoofing (NEW - 2025)
|
|
215
|
+
scriptsToInject.push(createUAClientHintsSpoofingScript(options?.platform));
|
|
216
|
+
// WebGL spoofing
|
|
217
|
+
if (options?.spoofWebGL !== false) {
|
|
218
|
+
scriptsToInject.push(createWebGLSpoofingScript(shouldUseFingerprintData ? webglConfig : undefined));
|
|
219
|
+
}
|
|
220
|
+
// Audio fingerprint spoofing
|
|
221
|
+
if (options?.spoofAudioContext !== false) {
|
|
222
|
+
scriptsToInject.push(createAudioFingerprintSpoofingScript());
|
|
223
|
+
}
|
|
224
|
+
// Canvas protection
|
|
225
|
+
scriptsToInject.push(createAdvancedCanvasProtectionScript());
|
|
226
|
+
// Client rect spoofing
|
|
227
|
+
if (options?.spoofClientRects !== false) {
|
|
228
|
+
scriptsToInject.push(createClientRectSpoofingScript());
|
|
229
|
+
}
|
|
230
|
+
// WebRTC spoofing
|
|
231
|
+
scriptsToInject.push(createWebRTCSpoofingScript());
|
|
232
|
+
// WebGPU spoofing (more aggressive when experimental fingerprints enabled)
|
|
233
|
+
scriptsToInject.push(createWebGPUSpoofingScript(options?.useExperimentalFingerprints));
|
|
234
|
+
// Font spoofing (2025)
|
|
235
|
+
if (options?.spoofFonts !== false) {
|
|
236
|
+
scriptsToInject.push(createFontSpoofingScript());
|
|
237
|
+
}
|
|
238
|
+
// Performance spoofing (2025)
|
|
239
|
+
if (options?.spoofPerformance !== false) {
|
|
240
|
+
scriptsToInject.push(createPerformanceSpoofingScript());
|
|
241
|
+
}
|
|
242
|
+
// Locale spoofing (2025)
|
|
243
|
+
if (options?.spoofLocale !== false) {
|
|
244
|
+
scriptsToInject.push(createLocaleSpoofingScript());
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// Apply platform consistency script
|
|
248
|
+
if (options?.platform) {
|
|
249
|
+
scriptsToInject.push(createPlatformConsistencyScript(options.platform, shouldUseFingerprintData ? platformConfig : undefined));
|
|
250
|
+
}
|
|
251
|
+
// Inject all scripts
|
|
166
252
|
await Promise.all([
|
|
167
253
|
this.setViewport(options?.viewport),
|
|
168
254
|
this.setExtraHTTPHeaders(filteredHeaders),
|
|
169
|
-
this.page.client.Page.addScriptToEvaluateOnNewDocument({ source:
|
|
170
|
-
this.injectStealthProtections(),
|
|
255
|
+
...scriptsToInject.map(async (script) => this.page.client.Page.addScriptToEvaluateOnNewDocument({ source: script })),
|
|
171
256
|
]);
|
|
172
|
-
|
|
257
|
+
// Setup mouse movement humanization if requested
|
|
258
|
+
if (options?.humanizeInteractions) {
|
|
259
|
+
await setupMouseMovementHumanization(this.page.client);
|
|
260
|
+
}
|
|
261
|
+
// Additional CDP-level protections
|
|
262
|
+
if (options?.bypassRuntimeEnable) {
|
|
263
|
+
await setupRuntimeEnableBypass(this.page.client);
|
|
264
|
+
}
|
|
265
|
+
log.info('Enhanced fingerprint attached with settings:', {
|
|
173
266
|
proxy: options?.proxyUrl,
|
|
174
267
|
timezone,
|
|
268
|
+
advancedStealth: options?.enableAdvancedStealth !== false,
|
|
269
|
+
humanizeInteractions: options?.humanizeInteractions,
|
|
270
|
+
bypassRuntimeEnable: options?.bypassRuntimeEnable,
|
|
271
|
+
platform: options?.platform,
|
|
272
|
+
useFingerprintDefaults: options?.useFingerprintDefaults,
|
|
175
273
|
});
|
|
176
274
|
}
|
|
177
275
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fingerprint-injector.js","sourceRoot":"","sources":["../../src/fingerprinting/fingerprint-injector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"fingerprint-injector.js","sourceRoot":"","sources":["../../src/fingerprinting/fingerprint-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAG3C,OAAO,EACH,mBAAmB,EACnB,yBAAyB,EACzB,oCAAoC,EACpC,oCAAoC,EACpC,8BAA8B,EAC9B,0BAA0B,EAC1B,0BAA0B,EAC1B,+BAA+B,EAC/B,8BAA8B,EAC9B,wBAAwB,EACxB,wBAAwB,EACxB,+BAA+B,EAC/B,0BAA0B,EAC1B,iCAAiC,GAGpC,MAAM,kCAAkC,CAAC;AAsC1C,MAAM,OAAO,sBAAsB;IAI/B,YAAY,IAAa;QAHjB;;;;;WAA8B;QAC9B;;;;;WAAc;QAGlB,IAAI,CAAC,QAAQ,GAAG,IAAI,mBAAmB,EAAE,CAAC;QAC1C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,2BAA2B;QAC9B,OAAO;YACH,qBAAqB,EAAE,IAAI;YAC3B,mBAAmB,EAAE,IAAI;YACzB,QAAQ,EAAE,OAAO,EAAE,uDAAuD;YAC1E,UAAU,EAAE,IAAI;YAChB,iBAAiB,EAAE,IAAI;YACvB,gBAAgB,EAAE,IAAI;YACtB,oBAAoB,EAAE,IAAI;YAC1B,cAAc,EAAE,IAAI,EAAE,kCAAkC;YACxD,yCAAyC;YACzC,UAAU,EAAE,IAAI;YAChB,gBAAgB,EAAE,IAAI;YACtB,WAAW,EAAE,IAAI;YACjB,sBAAsB,EAAE,IAAI,EAAE,2CAA2C;YACzE,QAAQ,EAAE;gBACN,KAAK,EAAE,IAAI;gBACX,MAAM,EAAE,IAAI;gBACZ,iBAAiB,EAAE,CAAC;gBACpB,MAAM,EAAE,KAAK;aAChB;SACJ,CAAC;IACN,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAC1B,IAAa,EACb,WAA0C,EAC1C,OAAuB;QAEvB,MAAM,OAAO,GAAG,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,QAAmB;QACzC,MAAM,eAAe,GAAa;YAC9B,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,IAAI;YACZ,iBAAiB,EAAE,CAAC;YACpB,MAAM,EAAE,KAAK;SAChB,CAAC;QAEF,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;QAC/D,sCAAsC;QACtC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,wBAAwB,CAAC,aAAoB,CAAC,CAAC;IACpF,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,OAA+B;QAC7D,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IACpE,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,QAAiB;QAC7C,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC;gBAC/B,GAAG,EAAE,wBAAwB;gBAC7B,QAAQ;gBACR,YAAY,EAAE,MAAM;aACvB,CAAC,CAAC;YACH,OAAQ,QAAQ,CAAC,IAAuB,CAAC,QAAQ,CAAC;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,CAAC,iCAAiC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YACxD,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,QAAgB;QAC9C,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,mBAAmB,CAAC;YACjD,UAAU,EAAE,QAAQ;SACvB,CAAC,CAAC;IACP,CAAC;IAEO,KAAK,CAAC,wBAAwB;QAClC,MAAM,aAAa,GAAG,mBAAmB,EAAE,CAAC;QAC5C,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED;;OAEG;IACK,sBAAsB,CAAC,WAAgB;QAI3C,MAAM,WAAW,GAAgB,EAAE,CAAC;QACpC,MAAM,cAAc,GAAmB,EAAE,CAAC;QAE1C,kCAAkC;QAClC,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;YACpB,WAAW,CAAC,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;YAC9C,WAAW,CAAC,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC;YAClD,WAAW,CAAC,cAAc,GAAG,WAAW,CAAC,KAAK,CAAC,cAAc,CAAC;YAC9D,WAAW,CAAC,gBAAgB,GAAG,WAAW,CAAC,KAAK,CAAC,gBAAgB,CAAC;QACtE,CAAC;QAED,qCAAqC;QACrC,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;YACxB,cAAc,CAAC,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC;YACzD,cAAc,CAAC,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC;YACrD,cAAc,CAAC,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC;YAC3D,cAAc,CAAC,UAAU,GAAG,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC;YAC7D,cAAc,CAAC,mBAAmB,GAAG,WAAW,CAAC,SAAS,CAAC,mBAAmB,CAAC;YAC/E,cAAc,CAAC,cAAc,GAAG,WAAW,CAAC,SAAS,CAAC,cAAc,CAAC;YACrE,cAAc,CAAC,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC;YACzD,cAAc,CAAC,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC,SAAS,CAAC;YAC3D,cAAc,CAAC,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC;QACvD,CAAC;QAED,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACrB,cAAc,CAAC,gBAAgB,GAAG,WAAW,CAAC,MAAM,CAAC,gBAAgB,CAAC;YACtE,cAAc,CAAC,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC;YAC3D,cAAc,CAAC,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC;QAC9D,CAAC;QAED,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;IAC3C,CAAC;IAEM,KAAK,CAAC,YAAY,CACrB,6BAA4D,EAC5D,OAAuB;QAEvB,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,6BAA6B,CAAC;QAE/D,MAAM,mBAAmB,GAAG,OAAO,EAAE,QAAQ,IAAI,OAAO,EAAE,cAAc,CAAC;QACzE,MAAM,QAAQ,GAAG,mBAAmB;YAChC,CAAC,CAAC,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC;YACjD,CAAC,CAAC,SAAS,CAAC;QAEhB,IAAI,QAAQ,EAAE,CAAC;YACX,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC7C,CAAC;QAED,kDAAkD;QAClD,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAErC,gDAAgD;QAChD,MAAM,mBAAmB,GAAI,IAAI,CAAC,QAAgB,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;QAEpF,iDAAiD;QACjD,MAAM,eAAe,GAAI,IAAI,CAAC,QAAgB,CAAC,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAExF,wCAAwC;QACxC,iCAAiC;QACjC,MAAM,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC,gCAAgC,CAAC,mBAAmB,CAAC,CAAC;QAE9F,gCAAgC;QAChC,MAAM,eAAe,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAE5C,yCAAyC;QACzC,MAAM,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEtC,+CAA+C;QAC/C,MAAM,wBAAwB,GAAG,OAAO,EAAE,sBAAsB,KAAK,KAAK,CAAC;QAC3E,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,wBAAwB;YAC5D,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,WAAW,CAAC;YAC1C,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC;QAE5D,yCAAyC;QACzC,IAAI,OAAO,EAAE,qBAAqB,KAAK,KAAK,EAAE,CAAC;YAC3C,wCAAwC;YACxC,eAAe,CAAC,IAAI,CAAC,iCAAiC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;YAE3E,iBAAiB;YACjB,IAAI,OAAO,EAAE,UAAU,KAAK,KAAK,EAAE,CAAC;gBAChC,eAAe,CAAC,IAAI,CAAC,yBAAyB,CAC1C,wBAAwB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CACrD,CAAC,CAAC;YACP,CAAC;YAED,6BAA6B;YAC7B,IAAI,OAAO,EAAE,iBAAiB,KAAK,KAAK,EAAE,CAAC;gBACvC,eAAe,CAAC,IAAI,CAAC,oCAAoC,EAAE,CAAC,CAAC;YACjE,CAAC;YAED,oBAAoB;YACpB,eAAe,CAAC,IAAI,CAAC,oCAAoC,EAAE,CAAC,CAAC;YAE7D,uBAAuB;YACvB,IAAI,OAAO,EAAE,gBAAgB,KAAK,KAAK,EAAE,CAAC;gBACtC,eAAe,CAAC,IAAI,CAAC,8BAA8B,EAAE,CAAC,CAAC;YAC3D,CAAC;YAED,kBAAkB;YAClB,eAAe,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC,CAAC;YAEnD,2EAA2E;YAC3E,eAAe,CAAC,IAAI,CAAC,0BAA0B,CAAC,OAAO,EAAE,2BAA2B,CAAC,CAAC,CAAC;YAEvF,uBAAuB;YACvB,IAAI,OAAO,EAAE,UAAU,KAAK,KAAK,EAAE,CAAC;gBAChC,eAAe,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,CAAC;YACrD,CAAC;YAED,8BAA8B;YAC9B,IAAI,OAAO,EAAE,gBAAgB,KAAK,KAAK,EAAE,CAAC;gBACtC,eAAe,CAAC,IAAI,CAAC,+BAA+B,EAAE,CAAC,CAAC;YAC5D,CAAC;YAED,yBAAyB;YACzB,IAAI,OAAO,EAAE,WAAW,KAAK,KAAK,EAAE,CAAC;gBACjC,eAAe,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC,CAAC;YACvD,CAAC;QACL,CAAC;QAED,oCAAoC;QACpC,IAAI,OAAO,EAAE,QAAQ,EAAE,CAAC;YACpB,eAAe,CAAC,IAAI,CAAC,+BAA+B,CAChD,OAAO,CAAC,QAAQ,EAChB,wBAAwB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CACxD,CAAC,CAAC;QACP,CAAC;QAED,qBAAqB;QACrB,MAAM,OAAO,CAAC,GAAG,CAAC;YACd,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC;YACnC,IAAI,CAAC,mBAAmB,CAAC,eAAe,CAAC;YACzC,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,EAAC,MAAM,EAAC,EAAE,CAClC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAC7E;SACJ,CAAC,CAAC;QAEH,iDAAiD;QACjD,IAAI,OAAO,EAAE,oBAAoB,EAAE,CAAC;YAChC,MAAM,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3D,CAAC;QAED,mCAAmC;QACnC,IAAI,OAAO,EAAE,mBAAmB,EAAE,CAAC;YAC/B,MAAM,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,8CAA8C,EAAE;YACrD,KAAK,EAAE,OAAO,EAAE,QAAQ;YACxB,QAAQ;YACR,eAAe,EAAE,OAAO,EAAE,qBAAqB,KAAK,KAAK;YACzD,oBAAoB,EAAE,OAAO,EAAE,oBAAoB;YACnD,mBAAmB,EAAE,OAAO,EAAE,mBAAmB;YACjD,QAAQ,EAAE,OAAO,EAAE,QAAQ;YAC3B,sBAAsB,EAAE,OAAO,EAAE,sBAAsB;SAC1D,CAAC,CAAC;IACP,CAAC;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-spoofing.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/audio-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,oCAAoC,QAAO,MAiFvD,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audio Fingerprint Spoofing
|
|
3
|
+
* Adds controlled noise to audio processing to prevent fingerprinting
|
|
4
|
+
*/
|
|
5
|
+
export const createAudioFingerprintSpoofingScript = () => {
|
|
6
|
+
return `
|
|
7
|
+
(() => {
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
// Audio Fingerprint Spoofing for 2025
|
|
11
|
+
const spoofAudioContext = () => {
|
|
12
|
+
const AudioContext = window.AudioContext || window.webkitAudioContext;
|
|
13
|
+
if (!AudioContext) return;
|
|
14
|
+
|
|
15
|
+
const OriginalAudioContext = AudioContext;
|
|
16
|
+
const OriginalOfflineAudioContext = window.OfflineAudioContext || window.webkitOfflineAudioContext;
|
|
17
|
+
|
|
18
|
+
// Add controlled noise to audio processing
|
|
19
|
+
const addNoise = (array) => {
|
|
20
|
+
if (!array || !array.length) return array;
|
|
21
|
+
|
|
22
|
+
const noise = 0.00001 * (Math.random() - 0.5);
|
|
23
|
+
for (let i = 0; i < array.length; i++) {
|
|
24
|
+
array[i] = array[i] + noise;
|
|
25
|
+
}
|
|
26
|
+
return array;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// Override AudioContext
|
|
30
|
+
window.AudioContext = window.webkitAudioContext = new Proxy(OriginalAudioContext, {
|
|
31
|
+
construct(target, args) {
|
|
32
|
+
const context = Reflect.construct(target, args);
|
|
33
|
+
|
|
34
|
+
// Override createAnalyser
|
|
35
|
+
const originalCreateAnalyser = context.createAnalyser;
|
|
36
|
+
context.createAnalyser = function() {
|
|
37
|
+
const analyser = originalCreateAnalyser.apply(this, arguments);
|
|
38
|
+
|
|
39
|
+
const originalGetFloatFrequencyData = analyser.getFloatFrequencyData;
|
|
40
|
+
analyser.getFloatFrequencyData = function(array) {
|
|
41
|
+
originalGetFloatFrequencyData.apply(this, arguments);
|
|
42
|
+
addNoise(array);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const originalGetByteFrequencyData = analyser.getByteFrequencyData;
|
|
46
|
+
analyser.getByteFrequencyData = function(array) {
|
|
47
|
+
originalGetByteFrequencyData.apply(this, arguments);
|
|
48
|
+
for (let i = 0; i < array.length; i++) {
|
|
49
|
+
array[i] = Math.min(255, Math.max(0, array[i] + Math.floor(Math.random() * 3 - 1)));
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return analyser;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return context;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Override OfflineAudioContext
|
|
61
|
+
if (OriginalOfflineAudioContext) {
|
|
62
|
+
window.OfflineAudioContext = window.webkitOfflineAudioContext = new Proxy(OriginalOfflineAudioContext, {
|
|
63
|
+
construct(target, args) {
|
|
64
|
+
const context = Reflect.construct(target, args);
|
|
65
|
+
|
|
66
|
+
const originalStartRendering = context.startRendering;
|
|
67
|
+
context.startRendering = function() {
|
|
68
|
+
return originalStartRendering.apply(this, arguments).then(buffer => {
|
|
69
|
+
// Add noise to the rendered buffer
|
|
70
|
+
for (let channel = 0; channel < buffer.numberOfChannels; channel++) {
|
|
71
|
+
const channelData = buffer.getChannelData(channel);
|
|
72
|
+
addNoise(channelData);
|
|
73
|
+
}
|
|
74
|
+
return buffer;
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return context;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
spoofAudioContext();
|
|
85
|
+
})();`;
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=audio-spoofing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-spoofing.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/audio-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,oCAAoC,GAAG,GAAW,EAAE;IAC7D,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA+EL,CAAC;AACP,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-protection.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/canvas-protection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,oCAAoC,QAAO,MAyFvD,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advanced Canvas Protection
|
|
3
|
+
* Adds noise to canvas operations to prevent fingerprinting
|
|
4
|
+
*/
|
|
5
|
+
export const createAdvancedCanvasProtectionScript = () => {
|
|
6
|
+
return `
|
|
7
|
+
(() => {
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
// Advanced Canvas Protection for 2025
|
|
11
|
+
const protectCanvas = () => {
|
|
12
|
+
const noiseFactor = 0.0001;
|
|
13
|
+
|
|
14
|
+
// Helper to add noise to image data
|
|
15
|
+
const addNoiseToImageData = (imageData) => {
|
|
16
|
+
const data = imageData.data;
|
|
17
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
18
|
+
// Add small noise to RGB channels, skip alpha
|
|
19
|
+
const noise = Math.floor((Math.random() - 0.5) * 3);
|
|
20
|
+
data[i] = Math.min(255, Math.max(0, data[i] + noise)); // R
|
|
21
|
+
data[i+1] = Math.min(255, Math.max(0, data[i+1] + noise)); // G
|
|
22
|
+
data[i+2] = Math.min(255, Math.max(0, data[i+2] + noise)); // B
|
|
23
|
+
}
|
|
24
|
+
return imageData;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Override toDataURL
|
|
28
|
+
const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
|
|
29
|
+
HTMLCanvasElement.prototype.toDataURL = function(...args) {
|
|
30
|
+
const context = this.getContext('2d');
|
|
31
|
+
if (context) {
|
|
32
|
+
const imageData = context.getImageData(0, 0, this.width, this.height);
|
|
33
|
+
context.putImageData(addNoiseToImageData(imageData), 0, 0);
|
|
34
|
+
}
|
|
35
|
+
return originalToDataURL.apply(this, args);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Override toBlob
|
|
39
|
+
const originalToBlob = HTMLCanvasElement.prototype.toBlob;
|
|
40
|
+
HTMLCanvasElement.prototype.toBlob = function(callback, ...args) {
|
|
41
|
+
const context = this.getContext('2d');
|
|
42
|
+
if (context) {
|
|
43
|
+
const imageData = context.getImageData(0, 0, this.width, this.height);
|
|
44
|
+
context.putImageData(addNoiseToImageData(imageData), 0, 0);
|
|
45
|
+
}
|
|
46
|
+
return originalToBlob.call(this, callback, ...args);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Override getImageData
|
|
50
|
+
const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
|
|
51
|
+
CanvasRenderingContext2D.prototype.getImageData = function(...args) {
|
|
52
|
+
const imageData = originalGetImageData.apply(this, args);
|
|
53
|
+
return addNoiseToImageData(imageData);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// Override readPixels for WebGL
|
|
57
|
+
if (typeof WebGLRenderingContext !== 'undefined') {
|
|
58
|
+
const originalReadPixels = WebGLRenderingContext.prototype.readPixels;
|
|
59
|
+
WebGLRenderingContext.prototype.readPixels = function(x, y, width, height, format, type, pixels) {
|
|
60
|
+
originalReadPixels.apply(this, arguments);
|
|
61
|
+
if (pixels && pixels.length) {
|
|
62
|
+
for (let i = 0; i < pixels.length; i++) {
|
|
63
|
+
pixels[i] = Math.min(255, Math.max(0, pixels[i] + Math.floor(Math.random() * 3 - 1)));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
if (typeof WebGL2RenderingContext !== 'undefined') {
|
|
69
|
+
WebGL2RenderingContext.prototype.readPixels = WebGLRenderingContext.prototype.readPixels;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Override font measurements to add slight variations
|
|
74
|
+
const originalMeasureText = CanvasRenderingContext2D.prototype.measureText;
|
|
75
|
+
CanvasRenderingContext2D.prototype.measureText = function(text) {
|
|
76
|
+
const metrics = originalMeasureText.apply(this, arguments);
|
|
77
|
+
|
|
78
|
+
// Add tiny variations to measurements
|
|
79
|
+
const variation = 1 + (Math.random() - 0.5) * 0.001;
|
|
80
|
+
|
|
81
|
+
return new Proxy(metrics, {
|
|
82
|
+
get(target, prop) {
|
|
83
|
+
if (typeof target[prop] === 'number') {
|
|
84
|
+
return target[prop] * variation;
|
|
85
|
+
}
|
|
86
|
+
return target[prop];
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
protectCanvas();
|
|
93
|
+
})();`;
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=canvas-protection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas-protection.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/canvas-protection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,oCAAoC,GAAG,GAAW,EAAE;IAC7D,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAuFL,CAAC;AACP,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-rect-spoofing.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/client-rect-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,8BAA8B,QAAO,MA0FjD,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client Rect Spoofing
|
|
3
|
+
* Adds small variations to DOM measurements to prevent fingerprinting
|
|
4
|
+
*/
|
|
5
|
+
export const createClientRectSpoofingScript = () => {
|
|
6
|
+
return `
|
|
7
|
+
(() => {
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
// Client Rect Spoofing for 2025
|
|
11
|
+
const spoofClientRects = () => {
|
|
12
|
+
// Add small random variations to rect values
|
|
13
|
+
const addVariation = (value) => {
|
|
14
|
+
return value + (Math.random() - 0.5) * 0.1;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Override getBoundingClientRect
|
|
18
|
+
const originalGetBoundingClientRect = Element.prototype.getBoundingClientRect;
|
|
19
|
+
Element.prototype.getBoundingClientRect = function() {
|
|
20
|
+
const rect = originalGetBoundingClientRect.apply(this, arguments);
|
|
21
|
+
|
|
22
|
+
// Create a new DOMRect with slight variations
|
|
23
|
+
const newRect = {
|
|
24
|
+
x: addVariation(rect.x),
|
|
25
|
+
y: addVariation(rect.y),
|
|
26
|
+
width: addVariation(rect.width),
|
|
27
|
+
height: addVariation(rect.height),
|
|
28
|
+
top: addVariation(rect.top),
|
|
29
|
+
right: addVariation(rect.right),
|
|
30
|
+
bottom: addVariation(rect.bottom),
|
|
31
|
+
left: addVariation(rect.left),
|
|
32
|
+
toJSON: rect.toJSON
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Make it look like a real DOMRect
|
|
36
|
+
Object.setPrototypeOf(newRect, DOMRect.prototype);
|
|
37
|
+
|
|
38
|
+
return newRect;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Override getClientRects
|
|
42
|
+
const originalGetClientRects = Element.prototype.getClientRects;
|
|
43
|
+
Element.prototype.getClientRects = function() {
|
|
44
|
+
const rects = originalGetClientRects.apply(this, arguments);
|
|
45
|
+
const newRects = [];
|
|
46
|
+
|
|
47
|
+
for (let i = 0; i < rects.length; i++) {
|
|
48
|
+
const rect = rects[i];
|
|
49
|
+
const newRect = {
|
|
50
|
+
x: addVariation(rect.x),
|
|
51
|
+
y: addVariation(rect.y),
|
|
52
|
+
width: addVariation(rect.width),
|
|
53
|
+
height: addVariation(rect.height),
|
|
54
|
+
top: addVariation(rect.top),
|
|
55
|
+
right: addVariation(rect.right),
|
|
56
|
+
bottom: addVariation(rect.bottom),
|
|
57
|
+
left: addVariation(rect.left)
|
|
58
|
+
};
|
|
59
|
+
Object.setPrototypeOf(newRect, DOMRect.prototype);
|
|
60
|
+
newRects.push(newRect);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Create a DOMRectList-like object
|
|
64
|
+
const rectList = {
|
|
65
|
+
length: newRects.length,
|
|
66
|
+
item: (index) => newRects[index] || null,
|
|
67
|
+
[Symbol.iterator]: function*() {
|
|
68
|
+
for (let i = 0; i < this.length; i++) {
|
|
69
|
+
yield this.item(i);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Add indexed properties
|
|
75
|
+
for (let i = 0; i < newRects.length; i++) {
|
|
76
|
+
rectList[i] = newRects[i];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
Object.setPrototypeOf(rectList, DOMRectList.prototype);
|
|
80
|
+
return rectList;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// Override Range methods
|
|
84
|
+
if (typeof Range !== 'undefined') {
|
|
85
|
+
const originalGetBoundingClientRectRange = Range.prototype.getBoundingClientRect;
|
|
86
|
+
Range.prototype.getBoundingClientRect = Element.prototype.getBoundingClientRect;
|
|
87
|
+
|
|
88
|
+
const originalGetClientRectsRange = Range.prototype.getClientRects;
|
|
89
|
+
Range.prototype.getClientRects = Element.prototype.getClientRects;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
spoofClientRects();
|
|
94
|
+
})();`;
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=client-rect-spoofing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-rect-spoofing.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/client-rect-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAAW,EAAE;IACvD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAwFL,CAAC;AACP,CAAC,CAAC"}
|