jumpy-lion 0.0.42 → 0.0.44
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/fingerprinting/fingerprint-injector.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-injector.js +4 -1
- package/dist/fingerprinting/fingerprint-injector.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.js +283 -4
- package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js +107 -0
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts +1 -0
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/index.js +2 -0
- package/dist/fingerprinting/fingerprint-overrides/index.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js +99 -68
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/prototype-integrity.d.ts +13 -0
- package/dist/fingerprinting/fingerprint-overrides/prototype-integrity.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/prototype-integrity.js +355 -0
- package/dist/fingerprinting/fingerprint-overrides/prototype-integrity.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts +2 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js +155 -24
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js +339 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts +7 -1
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js +158 -58
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/utils.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/utils.js +214 -12
- package/dist/fingerprinting/fingerprint-overrides/utils.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js +39 -10
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,93 +1,193 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* navigator.userAgentData spoofing
|
|
2
|
+
* navigator.userAgentData spoofing (UA-CH Client Hints)
|
|
3
3
|
* Generates brand list & bitness matching the chosen platform.
|
|
4
|
+
*
|
|
5
|
+
* 2024-2025 Enhanced:
|
|
6
|
+
* - Consistent platform returns "Windows" for Win32
|
|
7
|
+
* - Proper getHighEntropyValues() with all Windows-specific fields
|
|
8
|
+
* - Realistic Chrome version numbers matching userAgent
|
|
9
|
+
* - Proper prototype chain and native-like appearance
|
|
4
10
|
*/
|
|
5
11
|
export const createUAClientHintsSpoofingScript = (platform = 'Win32') => {
|
|
6
12
|
let platformData;
|
|
7
13
|
let platformVersion;
|
|
8
|
-
|
|
14
|
+
let architecture;
|
|
15
|
+
let bitness;
|
|
16
|
+
let wow64;
|
|
17
|
+
if (platform.startsWith('Win') || platform === 'Win32') {
|
|
9
18
|
platformData = 'Windows';
|
|
10
|
-
platformVersion = '15.0.0';
|
|
19
|
+
platformVersion = '15.0.0'; // Windows 11
|
|
20
|
+
architecture = 'x86';
|
|
21
|
+
bitness = '64';
|
|
22
|
+
wow64 = false;
|
|
11
23
|
}
|
|
12
24
|
else if (platform.startsWith('Mac')) {
|
|
13
25
|
platformData = 'macOS';
|
|
14
|
-
platformVersion = '14.
|
|
26
|
+
platformVersion = '14.4.0'; // macOS Sonoma
|
|
27
|
+
architecture = 'arm';
|
|
28
|
+
bitness = '64';
|
|
29
|
+
wow64 = false;
|
|
15
30
|
}
|
|
16
31
|
else {
|
|
17
32
|
platformData = 'Linux';
|
|
18
|
-
platformVersion = '6.
|
|
33
|
+
platformVersion = '6.5.0';
|
|
34
|
+
architecture = 'x86';
|
|
35
|
+
bitness = '64';
|
|
36
|
+
wow64 = false;
|
|
19
37
|
}
|
|
38
|
+
// Use realistic Chrome version (should match userAgent)
|
|
39
|
+
const chromeVersion = '131';
|
|
40
|
+
const fullVersion = '131.0.6778.139';
|
|
20
41
|
return `
|
|
21
42
|
(() => {
|
|
22
43
|
'use strict';
|
|
23
44
|
|
|
24
|
-
// UA-CH (User-Agent Client Hints) spoofing for 2025
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
45
|
+
// UA-CH (User-Agent Client Hints) spoofing for 2024-2025
|
|
46
|
+
// CRITICAL: Must match the platform spoofing and userAgent
|
|
47
|
+
|
|
48
|
+
const DEBUG_PREFIX = '[CDP-FP-DEBUG]';
|
|
49
|
+
|
|
50
|
+
// Brand list in Chrome's format - order matters!
|
|
51
|
+
const brands = Object.freeze([
|
|
52
|
+
Object.freeze({ brand: "Google Chrome", version: "${chromeVersion}" }),
|
|
53
|
+
Object.freeze({ brand: "Chromium", version: "${chromeVersion}" }),
|
|
54
|
+
Object.freeze({ brand: "Not_A Brand", version: "24" })
|
|
55
|
+
]);
|
|
56
|
+
|
|
57
|
+
const fullVersionList = Object.freeze([
|
|
58
|
+
Object.freeze({ brand: "Google Chrome", version: "${fullVersion}" }),
|
|
59
|
+
Object.freeze({ brand: "Chromium", version: "${fullVersion}" }),
|
|
60
|
+
Object.freeze({ brand: "Not_A Brand", version: "24.0.0.0" })
|
|
61
|
+
]);
|
|
30
62
|
|
|
31
63
|
const mobile = false;
|
|
32
64
|
const platformData = "${platformData}";
|
|
65
|
+
const platformVersion = "${platformVersion}";
|
|
66
|
+
const architecture = "${architecture}";
|
|
67
|
+
const bitness = "${bitness}";
|
|
68
|
+
const wow64 = ${wow64};
|
|
33
69
|
|
|
34
|
-
|
|
70
|
+
// High entropy values for getHighEntropyValues()
|
|
71
|
+
const highEntropyValues = {
|
|
72
|
+
architecture: architecture,
|
|
73
|
+
bitness: bitness,
|
|
35
74
|
brands: brands,
|
|
75
|
+
fullVersionList: fullVersionList,
|
|
36
76
|
mobile: mobile,
|
|
77
|
+
model: "",
|
|
37
78
|
platform: platformData,
|
|
79
|
+
platformVersion: platformVersion,
|
|
80
|
+
uaFullVersion: "${fullVersion}",
|
|
81
|
+
wow64: wow64,
|
|
82
|
+
formFactor: []
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Create a proper NavigatorUAData-like object
|
|
86
|
+
const createUAData = () => {
|
|
87
|
+
const uaData = Object.create(null);
|
|
38
88
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
89
|
+
// Define properties to match NavigatorUAData interface
|
|
90
|
+
Object.defineProperties(uaData, {
|
|
91
|
+
brands: {
|
|
92
|
+
get: function() { return brands; },
|
|
93
|
+
enumerable: true,
|
|
94
|
+
configurable: false
|
|
95
|
+
},
|
|
96
|
+
mobile: {
|
|
97
|
+
get: function() { return mobile; },
|
|
98
|
+
enumerable: true,
|
|
99
|
+
configurable: false
|
|
100
|
+
},
|
|
101
|
+
platform: {
|
|
102
|
+
get: function() { return platformData; },
|
|
103
|
+
enumerable: true,
|
|
104
|
+
configurable: false
|
|
105
|
+
},
|
|
106
|
+
getHighEntropyValues: {
|
|
107
|
+
value: function(hints) {
|
|
108
|
+
return new Promise((resolve) => {
|
|
109
|
+
// Simulate slight async delay like real browser
|
|
110
|
+
setTimeout(() => {
|
|
111
|
+
const result = {};
|
|
112
|
+
|
|
113
|
+
if (!hints || !Array.isArray(hints)) {
|
|
114
|
+
resolve(result);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Return requested hints
|
|
119
|
+
for (const hint of hints) {
|
|
120
|
+
if (hint in highEntropyValues) {
|
|
121
|
+
result[hint] = highEntropyValues[hint];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
resolve(result);
|
|
126
|
+
}, 1 + Math.random() * 2);
|
|
127
|
+
});
|
|
128
|
+
},
|
|
129
|
+
writable: false,
|
|
130
|
+
enumerable: true,
|
|
131
|
+
configurable: false
|
|
132
|
+
},
|
|
133
|
+
toJSON: {
|
|
134
|
+
value: function() {
|
|
135
|
+
return {
|
|
136
|
+
brands: brands,
|
|
137
|
+
mobile: mobile,
|
|
138
|
+
platform: platformData
|
|
139
|
+
};
|
|
140
|
+
},
|
|
141
|
+
writable: false,
|
|
142
|
+
enumerable: true,
|
|
143
|
+
configurable: false
|
|
144
|
+
}
|
|
145
|
+
});
|
|
64
146
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
147
|
+
// Make it look like a real NavigatorUAData object
|
|
148
|
+
Object.defineProperty(uaData, Symbol.toStringTag, {
|
|
149
|
+
value: 'NavigatorUAData',
|
|
150
|
+
writable: false,
|
|
151
|
+
enumerable: false,
|
|
152
|
+
configurable: true
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Freeze to prevent modification
|
|
156
|
+
return Object.freeze(uaData);
|
|
72
157
|
};
|
|
73
158
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
159
|
+
const uaData = createUAData();
|
|
160
|
+
|
|
161
|
+
// Register with stealth utils if available
|
|
162
|
+
if (window.__stealthUtils__) {
|
|
163
|
+
window.__stealthUtils__.registerNativeFunction(uaData.getHighEntropyValues, 'getHighEntropyValues');
|
|
164
|
+
window.__stealthUtils__.registerNativeFunction(uaData.toJSON, 'toJSON');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Override navigator.userAgentData with prototype integrity
|
|
168
|
+
const overrideUserAgentData = () => {
|
|
169
|
+
// Use prototype integrity if available
|
|
170
|
+
if (window.__prototypeIntegrity__) {
|
|
171
|
+
window.__prototypeIntegrity__.overridePropertyNative(navigator, 'userAgentData', {
|
|
172
|
+
get: function() { return uaData; },
|
|
173
|
+
enumerable: true,
|
|
174
|
+
configurable: false
|
|
175
|
+
});
|
|
176
|
+
} else {
|
|
177
|
+
// Fallback to standard override
|
|
178
|
+
Object.defineProperty(navigator, 'userAgentData', {
|
|
179
|
+
get: function() { return uaData; },
|
|
180
|
+
enumerable: true,
|
|
181
|
+
configurable: false
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
};
|
|
80
185
|
|
|
81
|
-
// Also ensure the property exists and is not writable
|
|
82
186
|
try {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
writable: false,
|
|
86
|
-
configurable: false,
|
|
87
|
-
enumerable: true
|
|
88
|
-
});
|
|
187
|
+
overrideUserAgentData();
|
|
188
|
+
console.log(DEBUG_PREFIX, '✓ UA-CH spoofing applied - platform:', platformData);
|
|
89
189
|
} catch (e) {
|
|
90
|
-
|
|
190
|
+
console.error('[CDP-FP-ERROR]', 'Failed to apply UA-CH spoofing:', e);
|
|
91
191
|
}
|
|
92
192
|
})();
|
|
93
193
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ua-ch.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/ua-ch.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ua-ch.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/ua-ch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC,QAAQ,GAAG,OAAO,EAAU,EAAE;IAC5E,IAAI,YAAoB,CAAC;IACzB,IAAI,eAAuB,CAAC;IAC5B,IAAI,YAAoB,CAAC;IACzB,IAAI,OAAe,CAAC;IACpB,IAAI,KAAc,CAAC;IAEnB,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACrD,YAAY,GAAG,SAAS,CAAC;QACzB,eAAe,GAAG,QAAQ,CAAC,CAAC,aAAa;QACzC,YAAY,GAAG,KAAK,CAAC;QACrB,OAAO,GAAG,IAAI,CAAC;QACf,KAAK,GAAG,KAAK,CAAC;IAClB,CAAC;SAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,YAAY,GAAG,OAAO,CAAC;QACvB,eAAe,GAAG,QAAQ,CAAC,CAAC,eAAe;QAC3C,YAAY,GAAG,KAAK,CAAC;QACrB,OAAO,GAAG,IAAI,CAAC;QACf,KAAK,GAAG,KAAK,CAAC;IAClB,CAAC;SAAM,CAAC;QACJ,YAAY,GAAG,OAAO,CAAC;QACvB,eAAe,GAAG,OAAO,CAAC;QAC1B,YAAY,GAAG,KAAK,CAAC;QACrB,OAAO,GAAG,IAAI,CAAC;QACf,KAAK,GAAG,KAAK,CAAC;IAClB,CAAC;IAED,wDAAwD;IACxD,MAAM,aAAa,GAAG,KAAK,CAAC;IAC5B,MAAM,WAAW,GAAG,gBAAgB,CAAC;IAErC,OAAO;;;;;;;;;;;4DAWiD,aAAa;uDAClB,aAAa;;;;;4DAKR,WAAW;uDAChB,WAAW;;;;;4BAKtC,YAAY;+BACT,eAAe;4BAClB,YAAY;uBACjB,OAAO;oBACV,KAAK;;;;;;;;;;;;0BAYC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiHpC,CAAC;AACF,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,eAAO,MAAM,wBAAwB,QAAO,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,eAAO,MAAM,wBAAwB,QAAO,MAyf3C,CAAC"}
|
|
@@ -24,49 +24,246 @@ export const createStealthUtilsScript = () => {
|
|
|
24
24
|
// Cache original toString BEFORE any modifications
|
|
25
25
|
const nativeToStringFunctionString = Function.prototype.toString.call(Function.prototype.toString);
|
|
26
26
|
const nativeToStringFunc = Function.prototype.toString;
|
|
27
|
+
const nativeCall = Function.prototype.call;
|
|
28
|
+
const nativeApply = Function.prototype.apply;
|
|
29
|
+
const nativeBind = Function.prototype.bind;
|
|
27
30
|
|
|
28
31
|
// WeakMap to track which functions should appear native
|
|
29
32
|
const nativeFunctionOverrides = new WeakMap();
|
|
30
33
|
|
|
34
|
+
// Track bound functions to their originals
|
|
35
|
+
const boundFunctionMap = new WeakMap();
|
|
36
|
+
|
|
37
|
+
// Track proxy targets
|
|
38
|
+
const proxyTargetMap = new WeakMap();
|
|
39
|
+
|
|
31
40
|
/**
|
|
32
41
|
* Generate a native-looking function string
|
|
42
|
+
* Handles various function types for maximum authenticity
|
|
33
43
|
*/
|
|
34
|
-
const makeNativeString = (name = '') => {
|
|
35
|
-
|
|
44
|
+
const makeNativeString = (name = '', type = 'function') => {
|
|
45
|
+
// Clean the name - remove "bound " prefix if present
|
|
46
|
+
const cleanName = name.replace(/^bound /, '');
|
|
47
|
+
|
|
48
|
+
// Different native string formats
|
|
49
|
+
if (type === 'getter') {
|
|
50
|
+
return \`function get \${cleanName}() { [native code] }\`;
|
|
51
|
+
}
|
|
52
|
+
if (type === 'setter') {
|
|
53
|
+
return \`function set \${cleanName}() { [native code] }\`;
|
|
54
|
+
}
|
|
55
|
+
if (type === 'async') {
|
|
56
|
+
return \`async function \${cleanName}() { [native code] }\`;
|
|
57
|
+
}
|
|
58
|
+
if (type === 'generator') {
|
|
59
|
+
return \`function* \${cleanName}() { [native code] }\`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return \`function \${cleanName}() { [native code] }\`;
|
|
36
63
|
};
|
|
37
64
|
|
|
38
65
|
/**
|
|
39
66
|
* Register a function to appear native when toString is called
|
|
67
|
+
* Enhanced to handle bound functions and proxies
|
|
40
68
|
*/
|
|
41
|
-
const registerNativeFunction = (fn, name = '') => {
|
|
42
|
-
|
|
69
|
+
const registerNativeFunction = (fn, name = '', type = 'function') => {
|
|
70
|
+
if (typeof fn !== 'function') return;
|
|
71
|
+
|
|
72
|
+
nativeFunctionOverrides.set(fn, { name, type });
|
|
73
|
+
|
|
74
|
+
// Also register any bound versions
|
|
75
|
+
try {
|
|
76
|
+
const boundVersion = fn.bind(null);
|
|
77
|
+
if (boundVersion !== fn) {
|
|
78
|
+
boundFunctionMap.set(boundVersion, fn);
|
|
79
|
+
}
|
|
80
|
+
} catch (e) {
|
|
81
|
+
// Some functions can't be bound, ignore
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Check if a function is a Proxy
|
|
87
|
+
*/
|
|
88
|
+
const isProxy = (fn) => {
|
|
89
|
+
try {
|
|
90
|
+
// Proxies throw when you try to get their prototype in certain ways
|
|
91
|
+
return proxyTargetMap.has(fn);
|
|
92
|
+
} catch (e) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Register a Proxy and its target for toString lookup
|
|
99
|
+
*/
|
|
100
|
+
const registerProxyTarget = (proxy, target, name = '') => {
|
|
101
|
+
proxyTargetMap.set(proxy, { target, name });
|
|
102
|
+
registerNativeFunction(proxy, name);
|
|
43
103
|
};
|
|
44
104
|
|
|
45
105
|
/**
|
|
46
106
|
* Patch Function.prototype.toString to hide overridden functions
|
|
107
|
+
* Enhanced with multiple levels of protection
|
|
47
108
|
*/
|
|
48
109
|
const patchToString = () => {
|
|
49
110
|
const patchedToString = function() {
|
|
50
|
-
//
|
|
111
|
+
// Handle registered native functions
|
|
51
112
|
if (nativeFunctionOverrides.has(this)) {
|
|
52
|
-
const
|
|
53
|
-
return makeNativeString(name);
|
|
113
|
+
const info = nativeFunctionOverrides.get(this);
|
|
114
|
+
return makeNativeString(info.name, info.type);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Handle bound functions - look up original
|
|
118
|
+
if (boundFunctionMap.has(this)) {
|
|
119
|
+
const original = boundFunctionMap.get(this);
|
|
120
|
+
if (nativeFunctionOverrides.has(original)) {
|
|
121
|
+
const info = nativeFunctionOverrides.get(original);
|
|
122
|
+
return makeNativeString(info.name, info.type);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Handle proxies
|
|
127
|
+
if (proxyTargetMap.has(this)) {
|
|
128
|
+
const { target, name } = proxyTargetMap.get(this);
|
|
129
|
+
if (name) {
|
|
130
|
+
return makeNativeString(name);
|
|
131
|
+
}
|
|
132
|
+
if (target && nativeFunctionOverrides.has(target)) {
|
|
133
|
+
const info = nativeFunctionOverrides.get(target);
|
|
134
|
+
return makeNativeString(info.name, info.type);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Check if this is an anonymous arrow function that should look native
|
|
139
|
+
// Arrow functions have no prototype property
|
|
140
|
+
const result = nativeCall.call(nativeToStringFunc, this);
|
|
141
|
+
|
|
142
|
+
// Clean result to remove CDP/automation markers
|
|
143
|
+
if (typeof result === 'string') {
|
|
144
|
+
// Remove sourceURL comments
|
|
145
|
+
let cleaned = result
|
|
146
|
+
.replace(/\\/\\/# sourceURL=[^\\n]*/g, '')
|
|
147
|
+
.replace(/\\/\\/# sourceMappingURL=[^\\n]*/g, '')
|
|
148
|
+
.replace(/__puppeteer_evaluation_script__/g, '')
|
|
149
|
+
.replace(/__playwright_evaluation_script__/g, '')
|
|
150
|
+
.replace(/pptr:[^\\n]*/g, '');
|
|
151
|
+
|
|
152
|
+
return cleaned;
|
|
54
153
|
}
|
|
55
|
-
|
|
56
|
-
return
|
|
154
|
+
|
|
155
|
+
return result;
|
|
57
156
|
};
|
|
58
157
|
|
|
59
158
|
// Make patchedToString itself appear native
|
|
60
|
-
nativeFunctionOverrides.set(patchedToString, 'toString');
|
|
159
|
+
nativeFunctionOverrides.set(patchedToString, { name: 'toString', type: 'function' });
|
|
61
160
|
|
|
62
161
|
// Replace Function.prototype.toString
|
|
63
162
|
Function.prototype.toString = patchedToString;
|
|
64
163
|
|
|
65
|
-
//
|
|
164
|
+
// Patch toString.call and toString.apply to use our version
|
|
165
|
+
// CRITICAL: Bypass patchedToString completely - call nativeToStringFunc directly
|
|
166
|
+
// to prevent infinite recursion when scripts call toString.call.call() etc.
|
|
167
|
+
const patchedCall = function(thisArg, ...args) {
|
|
168
|
+
// Handle our registered overrides first
|
|
169
|
+
if (thisArg && nativeFunctionOverrides.has(thisArg)) {
|
|
170
|
+
const info = nativeFunctionOverrides.get(thisArg);
|
|
171
|
+
return makeNativeString(info.name, info.type);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Handle bound functions
|
|
175
|
+
if (thisArg && boundFunctionMap.has(thisArg)) {
|
|
176
|
+
const original = boundFunctionMap.get(thisArg);
|
|
177
|
+
if (nativeFunctionOverrides.has(original)) {
|
|
178
|
+
const info = nativeFunctionOverrides.get(original);
|
|
179
|
+
return makeNativeString(info.name, info.type);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Handle proxies
|
|
184
|
+
if (thisArg && proxyTargetMap.has(thisArg)) {
|
|
185
|
+
const { target, name } = proxyTargetMap.get(thisArg);
|
|
186
|
+
if (name) return makeNativeString(name);
|
|
187
|
+
if (target && nativeFunctionOverrides.has(target)) {
|
|
188
|
+
const info = nativeFunctionOverrides.get(target);
|
|
189
|
+
return makeNativeString(info.name, info.type);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// CRITICAL: Call native toString directly to avoid any recursion
|
|
194
|
+
// Never go through patchedToString from here
|
|
195
|
+
return nativeCall.call(nativeToStringFunc, thisArg);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const patchedApply = function(thisArg, argsArray) {
|
|
199
|
+
// Handle our registered overrides first
|
|
200
|
+
if (thisArg && nativeFunctionOverrides.has(thisArg)) {
|
|
201
|
+
const info = nativeFunctionOverrides.get(thisArg);
|
|
202
|
+
return makeNativeString(info.name, info.type);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Handle bound functions
|
|
206
|
+
if (thisArg && boundFunctionMap.has(thisArg)) {
|
|
207
|
+
const original = boundFunctionMap.get(thisArg);
|
|
208
|
+
if (nativeFunctionOverrides.has(original)) {
|
|
209
|
+
const info = nativeFunctionOverrides.get(original);
|
|
210
|
+
return makeNativeString(info.name, info.type);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Handle proxies
|
|
215
|
+
if (thisArg && proxyTargetMap.has(thisArg)) {
|
|
216
|
+
const { target, name } = proxyTargetMap.get(thisArg);
|
|
217
|
+
if (name) return makeNativeString(name);
|
|
218
|
+
if (target && nativeFunctionOverrides.has(target)) {
|
|
219
|
+
const info = nativeFunctionOverrides.get(target);
|
|
220
|
+
return makeNativeString(info.name, info.type);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// CRITICAL: Call native toString directly to avoid any recursion
|
|
225
|
+
return nativeCall.call(nativeToStringFunc, thisArg);
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
// Register call/apply as native
|
|
229
|
+
nativeFunctionOverrides.set(patchedCall, { name: 'call', type: 'function' });
|
|
230
|
+
nativeFunctionOverrides.set(patchedApply, { name: 'apply', type: 'function' });
|
|
231
|
+
|
|
232
|
+
// Make toString.toString return the native string
|
|
66
233
|
Object.defineProperty(Function.prototype.toString, 'toString', {
|
|
67
234
|
value: patchedToString,
|
|
68
235
|
writable: false,
|
|
69
|
-
configurable: false
|
|
236
|
+
configurable: false,
|
|
237
|
+
enumerable: false
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Patch call and apply on our toString
|
|
241
|
+
Object.defineProperty(Function.prototype.toString, 'call', {
|
|
242
|
+
value: patchedCall,
|
|
243
|
+
writable: false,
|
|
244
|
+
configurable: false,
|
|
245
|
+
enumerable: false
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
Object.defineProperty(Function.prototype.toString, 'apply', {
|
|
249
|
+
value: patchedApply,
|
|
250
|
+
writable: false,
|
|
251
|
+
configurable: false,
|
|
252
|
+
enumerable: false
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// Also protect against Function.prototype.toString.bind()
|
|
256
|
+
const originalBind = Function.prototype.toString.bind;
|
|
257
|
+
Object.defineProperty(Function.prototype.toString, 'bind', {
|
|
258
|
+
value: function(...args) {
|
|
259
|
+
const bound = nativeBind.apply(patchedToString, args);
|
|
260
|
+
nativeFunctionOverrides.set(bound, { name: 'toString', type: 'function' });
|
|
261
|
+
boundFunctionMap.set(bound, patchedToString);
|
|
262
|
+
return bound;
|
|
263
|
+
},
|
|
264
|
+
writable: false,
|
|
265
|
+
configurable: false,
|
|
266
|
+
enumerable: false
|
|
70
267
|
});
|
|
71
268
|
};
|
|
72
269
|
|
|
@@ -296,12 +493,15 @@ export const createStealthUtilsScript = () => {
|
|
|
296
493
|
window.__stealthUtils__ = {
|
|
297
494
|
makeNativeString,
|
|
298
495
|
registerNativeFunction,
|
|
496
|
+
registerProxyTarget,
|
|
299
497
|
canRedefineProperty,
|
|
300
498
|
overridePropertyWithGuard,
|
|
301
499
|
overrideGetterWithNative,
|
|
302
500
|
createNativeProxyHandler,
|
|
303
501
|
cacheAndOverride,
|
|
304
502
|
nativeFunctionOverrides,
|
|
503
|
+
boundFunctionMap,
|
|
504
|
+
proxyTargetMap,
|
|
305
505
|
// New logging and safety utilities
|
|
306
506
|
logPropertyOverride,
|
|
307
507
|
verifyOverride,
|
|
@@ -309,6 +509,8 @@ export const createStealthUtilsScript = () => {
|
|
|
309
509
|
withErrorBoundary,
|
|
310
510
|
overridePropertySafe
|
|
311
511
|
};
|
|
512
|
+
|
|
513
|
+
console.log('[CDP-FP-DEBUG] ✓ Stealth utilities initialized with enhanced toString masking');
|
|
312
514
|
})();
|
|
313
515
|
`;
|
|
314
516
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAW,EAAE;IACjD,OAAO
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAW,EAAE;IACjD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAufV,CAAC;AACF,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webgl-spoofing.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/webgl-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,eAAO,MAAM,yBAAyB,sBAAuB,WAAW,KAAG,
|
|
1
|
+
{"version":3,"file":"webgl-spoofing.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/webgl-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,eAAO,MAAM,yBAAyB,sBAAuB,WAAW,KAAG,MA2M1E,CAAC"}
|
|
@@ -23,43 +23,72 @@ export const createWebGLSpoofingScript = (fingerprintWebGL) => {
|
|
|
23
23
|
console.log('[CDP-FP-DEBUG] WebGL using fingerprint data - Vendor:', selectedVendor, 'Renderer:', selectedRenderer.substring(0, 50));
|
|
24
24
|
` : `
|
|
25
25
|
// Detect platform from navigator
|
|
26
|
-
const platform = navigator.platform || '
|
|
26
|
+
const platform = navigator.platform || 'Win32';
|
|
27
27
|
|
|
28
|
-
// Platform-specific GPU configurations
|
|
28
|
+
// Platform-specific GPU configurations - 2024-2025 updated
|
|
29
|
+
// IMPORTANT: Windows GPU strings must follow the exact Chrome ANGLE format
|
|
29
30
|
const gpuConfigs = {
|
|
30
31
|
'Win32': {
|
|
31
|
-
|
|
32
|
+
// Windows uses "Google Inc. (VENDOR)" format for vendor
|
|
33
|
+
vendors: [
|
|
34
|
+
'Google Inc. (NVIDIA)',
|
|
35
|
+
'Google Inc. (AMD)',
|
|
36
|
+
'Google Inc. (Intel)'
|
|
37
|
+
],
|
|
38
|
+
// Windows renderers use Direct3D11 format - authentic Chrome strings
|
|
32
39
|
renderers: [
|
|
33
40
|
'ANGLE (NVIDIA, NVIDIA GeForce GTX 1660 Ti Direct3D11 vs_5_0 ps_5_0, D3D11)',
|
|
34
41
|
'ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11 vs_5_0 ps_5_0, D3D11)',
|
|
42
|
+
'ANGLE (NVIDIA, NVIDIA GeForce RTX 4070 Direct3D11 vs_5_0 ps_5_0, D3D11)',
|
|
43
|
+
'ANGLE (AMD, AMD Radeon RX 6700 XT Direct3D11 vs_5_0 ps_5_0, D3D11)',
|
|
35
44
|
'ANGLE (AMD, AMD Radeon RX 6600 Direct3D11 vs_5_0 ps_5_0, D3D11)',
|
|
36
45
|
'ANGLE (Intel, Intel(R) UHD Graphics 630 Direct3D11 vs_5_0 ps_5_0, D3D11)',
|
|
46
|
+
'ANGLE (Intel, Intel(R) Iris(R) Xe Graphics Direct3D11 vs_5_0 ps_5_0, D3D11)',
|
|
47
|
+
],
|
|
48
|
+
vendorPairs: [
|
|
49
|
+
{ vendor: 'Google Inc. (NVIDIA)', renderer: 'ANGLE (NVIDIA, NVIDIA GeForce GTX 1660 Ti Direct3D11 vs_5_0 ps_5_0, D3D11)' },
|
|
50
|
+
{ vendor: 'Google Inc. (NVIDIA)', renderer: 'ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11 vs_5_0 ps_5_0, D3D11)' },
|
|
51
|
+
{ vendor: 'Google Inc. (AMD)', renderer: 'ANGLE (AMD, AMD Radeon RX 6700 XT Direct3D11 vs_5_0 ps_5_0, D3D11)' },
|
|
52
|
+
{ vendor: 'Google Inc. (Intel)', renderer: 'ANGLE (Intel, Intel(R) UHD Graphics 630 Direct3D11 vs_5_0 ps_5_0, D3D11)' },
|
|
37
53
|
],
|
|
38
54
|
},
|
|
39
55
|
'MacIntel': {
|
|
40
|
-
vendors: ['
|
|
56
|
+
vendors: ['Google Inc. (Apple)', 'Google Inc. (Intel)', 'Google Inc. (AMD)'],
|
|
41
57
|
renderers: [
|
|
42
58
|
'ANGLE (Apple, Apple M1 Pro, OpenGL 4.1)',
|
|
43
59
|
'ANGLE (Apple, Apple M2, OpenGL 4.1)',
|
|
44
60
|
'ANGLE (Intel Inc., Intel(R) Iris(TM) Plus Graphics OpenGL Engine, OpenGL 4.1)',
|
|
45
61
|
'ANGLE (AMD, AMD Radeon Pro 5500M OpenGL Engine, OpenGL 4.1)',
|
|
46
62
|
],
|
|
63
|
+
vendorPairs: [
|
|
64
|
+
{ vendor: 'Google Inc. (Apple)', renderer: 'ANGLE (Apple, Apple M1 Pro, OpenGL 4.1)' },
|
|
65
|
+
{ vendor: 'Google Inc. (Intel)', renderer: 'ANGLE (Intel Inc., Intel(R) Iris(TM) Plus Graphics OpenGL Engine, OpenGL 4.1)' },
|
|
66
|
+
],
|
|
47
67
|
},
|
|
48
68
|
'Linux x86_64': {
|
|
49
|
-
vendors: ['Intel', 'NVIDIA
|
|
69
|
+
vendors: ['Google Inc. (Intel)', 'Google Inc. (NVIDIA)', 'Google Inc. (AMD)'],
|
|
50
70
|
renderers: [
|
|
51
71
|
'ANGLE (Intel, Mesa Intel(R) UHD Graphics 630 (CFL GT2), OpenGL 4.6)',
|
|
52
72
|
'ANGLE (NVIDIA, NVIDIA GeForce GTX 1660 Ti/PCIe/SSE2, OpenGL 4.6)',
|
|
53
73
|
'ANGLE (AMD, AMD Radeon RX 6600 (NAVY_FLOUNDER, DRM 3.42.0, 5.15.0-56-generic, LLVM 12.0.0), OpenGL 4.6)',
|
|
54
|
-
|
|
74
|
+
],
|
|
75
|
+
vendorPairs: [
|
|
76
|
+
{ vendor: 'Google Inc. (Intel)', renderer: 'ANGLE (Intel, Mesa Intel(R) UHD Graphics 630 (CFL GT2), OpenGL 4.6)' },
|
|
77
|
+
{ vendor: 'Google Inc. (NVIDIA)', renderer: 'ANGLE (NVIDIA, NVIDIA GeForce GTX 1660 Ti/PCIe/SSE2, OpenGL 4.6)' },
|
|
55
78
|
],
|
|
56
79
|
},
|
|
57
80
|
};
|
|
58
81
|
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
82
|
+
// Default to Windows for better anti-bot evasion (most common platform)
|
|
83
|
+
const config = gpuConfigs[platform] || gpuConfigs['Win32'];
|
|
84
|
+
|
|
85
|
+
// Select a consistent vendor/renderer pair
|
|
86
|
+
const pairIndex = Math.floor(Math.random() * config.vendorPairs.length);
|
|
87
|
+
const selectedPair = config.vendorPairs[pairIndex];
|
|
88
|
+
const selectedVendor = selectedPair.vendor;
|
|
89
|
+
const selectedRenderer = selectedPair.renderer;
|
|
90
|
+
|
|
91
|
+
console.log('[CDP-FP-DEBUG] WebGL using platform:', platform, '- Vendor:', selectedVendor, 'Renderer:', selectedRenderer.substring(0, 60) + '...');
|
|
63
92
|
`}
|
|
64
93
|
|
|
65
94
|
// Override getParameter
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webgl-spoofing.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/webgl-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,gBAA8B,EAAU,EAAE;IAChF,iFAAiF;IACjF,MAAM,cAAc,GAAG,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,cAAc,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IAElH,OAAO;;;;;;;;;;UAUD,cAAc,CAAC,CAAC,CAAC;;oCAES,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;;;;SAI3D,CAAC,CAAC,CAAC
|
|
1
|
+
{"version":3,"file":"webgl-spoofing.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/webgl-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,gBAA8B,EAAU,EAAE;IAChF,iFAAiF;IACjF,MAAM,cAAc,GAAG,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,cAAc,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IAElH,OAAO;;;;;;;;;;UAUD,cAAc,CAAC,CAAC,CAAC;;oCAES,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;;;;SAI3D,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAoEH;;;;;;;;;;;;;;yBAcgB,cAAc,IAAI,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,UAAU;;;yBAGxF,cAAc,IAAI,gBAAgB,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA2CjH,CAAC,cAAc,CAAC,CAAC,CAAC;;;;;;;;;SASnB,CAAC,CAAC,CAAC;;SAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA2CH,CAAC;AACP,CAAC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import CDPCrawler from "./crawler.js";
|
|
|
2
2
|
import CdpPage from "./page.js";
|
|
3
3
|
export default CDPCrawler;
|
|
4
4
|
export { createCDPRouter } from "./crawler.js";
|
|
5
|
-
export type { CDPRouter } from "./crawler.js";
|
|
5
|
+
export type { CDPRouter, CDPCrawlingContext, CDPCrawlerOptions, CDPLaunchContext, CDPRequestHandler } from "./crawler.js";
|
|
6
6
|
export type { GotoOptions, SelectOptionOptions } from "./page.js";
|
|
7
7
|
export { CdpPage };
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|