jumpy-lion 0.0.42 → 0.0.43

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.
Files changed (39) hide show
  1. package/dist/fingerprinting/fingerprint-injector.d.ts.map +1 -1
  2. package/dist/fingerprinting/fingerprint-injector.js +4 -1
  3. package/dist/fingerprinting/fingerprint-injector.js.map +1 -1
  4. package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.d.ts.map +1 -1
  5. package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.js +283 -4
  6. package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.js.map +1 -1
  7. package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.d.ts.map +1 -1
  8. package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js +107 -0
  9. package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js.map +1 -1
  10. package/dist/fingerprinting/fingerprint-overrides/index.d.ts +1 -0
  11. package/dist/fingerprinting/fingerprint-overrides/index.d.ts.map +1 -1
  12. package/dist/fingerprinting/fingerprint-overrides/index.js +2 -0
  13. package/dist/fingerprinting/fingerprint-overrides/index.js.map +1 -1
  14. package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.d.ts.map +1 -1
  15. package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js +99 -68
  16. package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js.map +1 -1
  17. package/dist/fingerprinting/fingerprint-overrides/prototype-integrity.d.ts +13 -0
  18. package/dist/fingerprinting/fingerprint-overrides/prototype-integrity.d.ts.map +1 -0
  19. package/dist/fingerprinting/fingerprint-overrides/prototype-integrity.js +355 -0
  20. package/dist/fingerprinting/fingerprint-overrides/prototype-integrity.js.map +1 -0
  21. package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts +2 -0
  22. package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts.map +1 -1
  23. package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js +155 -24
  24. package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js.map +1 -1
  25. package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts.map +1 -1
  26. package/dist/fingerprinting/fingerprint-overrides/stealth-script.js +339 -0
  27. package/dist/fingerprinting/fingerprint-overrides/stealth-script.js.map +1 -1
  28. package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts +7 -1
  29. package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts.map +1 -1
  30. package/dist/fingerprinting/fingerprint-overrides/ua-ch.js +158 -58
  31. package/dist/fingerprinting/fingerprint-overrides/ua-ch.js.map +1 -1
  32. package/dist/fingerprinting/fingerprint-overrides/utils.d.ts.map +1 -1
  33. package/dist/fingerprinting/fingerprint-overrides/utils.js +214 -12
  34. package/dist/fingerprinting/fingerprint-overrides/utils.js.map +1 -1
  35. package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts.map +1 -1
  36. package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js +39 -10
  37. package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js.map +1 -1
  38. package/dist/tsconfig.build.tsbuildinfo +1 -1
  39. 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
- if (platform.startsWith('Win')) {
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.0.0';
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.2.0';
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
- const brands = [
26
- { brand: "Chromium", version: "125" },
27
- { brand: "Google Chrome", version: "125" },
28
- { brand: "Not A(Brand", version: "99" }
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
- const uaData = {
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
- getHighEntropyValues(hints) {
40
- return new Promise((resolve) => {
41
- const base = {
42
- architecture: "x86",
43
- bitness: "64",
44
- brands: brands,
45
- mobile: mobile,
46
- model: "",
47
- platform: platformData,
48
- platformVersion: "${platformVersion}",
49
- uaFullVersion: "125.0.6422.4",
50
- fullVersionList: brands.map(b => ({ brand: b.brand, version: "125.0.6422.4" })),
51
- wow64: false
52
- };
53
-
54
- const result = {};
55
- hints.forEach(hint => {
56
- if (hint in base) {
57
- result[hint] = base[hint];
58
- }
59
- });
60
-
61
- resolve(result);
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
- toJSON() {
66
- return {
67
- brands: brands,
68
- mobile: mobile,
69
- platform: platformData
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
- // Override navigator.userAgentData
75
- Object.defineProperty(navigator, "userAgentData", {
76
- get: () => uaData,
77
- configurable: false,
78
- enumerable: true
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
- Object.defineProperty(navigator, "userAgentData", {
84
- value: uaData,
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
- // Property might already be defined
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;;;GAGG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC,QAAQ,GAAG,OAAO,EAAU,EAAE;IAC5E,IAAI,YAAoB,CAAC;IACzB,IAAI,eAAuB,CAAC;IAE5B,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,YAAY,GAAG,SAAS,CAAC;QACzB,eAAe,GAAG,QAAQ,CAAC;IAC/B,CAAC;SAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,YAAY,GAAG,OAAO,CAAC;QACvB,eAAe,GAAG,QAAQ,CAAC;IAC/B,CAAC;SAAM,CAAC;QACJ,YAAY,GAAG,OAAO,CAAC;QACvB,eAAe,GAAG,OAAO,CAAC;IAC9B,CAAC;IAED,OAAO;;;;;;;;;;;;4BAYiB,YAAY;;;;;;;;;;;;;;;;wCAgBA,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CtD,CAAC;AACF,CAAC,CAAC"}
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,MA+S3C,CAAC"}
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
- return \`function \${name}() { [native code] }\`;
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
- nativeFunctionOverrides.set(fn, name);
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
- // Check if this function should appear native
111
+ // Handle registered native functions
51
112
  if (nativeFunctionOverrides.has(this)) {
52
- const name = nativeFunctionOverrides.get(this);
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
- // Otherwise return original toString
56
- return nativeToStringFunc.call(this);
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
- // Also patch Function.prototype.toString.toString to look native
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6SV,CAAC;AACF,CAAC,CAAC"}
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,MA8K1E,CAAC"}
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 || 'Linux x86_64';
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
- vendors: ['NVIDIA Corporation', 'AMD', 'Intel Inc.'],
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: ['Apple Inc.', 'Intel Inc.', 'AMD'],
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 Corporation', 'AMD'],
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
- 'ANGLE (Intel, Mesa Intel(R) Xe Graphics (TGL GT2), OpenGL 4.6)',
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
- const config = gpuConfigs[platform] || gpuConfigs['Linux x86_64'];
60
- const selectedVendor = config.vendors[Math.floor(Math.random() * config.vendors.length)];
61
- const selectedRenderer = config.renderers.find(r => r.includes(selectedVendor.split(' ')[0])) || config.renderers[0];
62
- console.log('[CDP-FP-DEBUG] WebGL using platform:', platform, '- Vendor:', selectedVendor, 'Renderer:', selectedRenderer.substring(0, 50));
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAuCH;;;;;;;;;;;;;;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"}
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"}