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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locale-spoofing.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/locale-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,0BAA0B,QAAO,
|
|
1
|
+
{"version":3,"file":"locale-spoofing.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/locale-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,0BAA0B,QAAO,MA+T7C,CAAC"}
|
|
@@ -39,71 +39,70 @@ export const createLocaleSpoofingScript = () => {
|
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
// Override Intl.DateTimeFormat to use Windows-consistent formatting
|
|
42
|
+
// CRITICAL: Store reference BEFORE override and use recursion guard
|
|
42
43
|
const OriginalDateTimeFormat = Intl.DateTimeFormat;
|
|
44
|
+
let isCreatingDateTimeFormat = false; // Recursion guard
|
|
45
|
+
let cachedTimeZone = 'UTC';
|
|
46
|
+
try {
|
|
47
|
+
cachedTimeZone = new OriginalDateTimeFormat().resolvedOptions().timeZone;
|
|
48
|
+
} catch (e) {
|
|
49
|
+
// Fallback to UTC if timezone detection fails
|
|
50
|
+
}
|
|
51
|
+
|
|
43
52
|
Intl.DateTimeFormat = function(locales, options) {
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
// Force specific Windows locale patterns
|
|
48
|
-
if (platform === 'Win32' || !platform.includes('Linux')) {
|
|
49
|
-
if (!options || !options.timeZone) {
|
|
50
|
-
// Use common Windows timezone handling
|
|
51
|
-
windowsOptions.timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
52
|
-
}
|
|
53
|
+
// CRITICAL: Recursion guard - if we're already inside this function, use original directly
|
|
54
|
+
if (isCreatingDateTimeFormat) {
|
|
55
|
+
return Reflect.construct(OriginalDateTimeFormat, [locales, options], OriginalDateTimeFormat);
|
|
53
56
|
}
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
formatter.format = function(date) {
|
|
60
|
-
let result = originalFormat.call(this, date);
|
|
58
|
+
isCreatingDateTimeFormat = true;
|
|
59
|
+
try {
|
|
60
|
+
// Ensure Windows-like date formatting regardless of actual locale
|
|
61
|
+
const windowsOptions = Object.assign({}, windowsLocaleConfig.dateFormat, options);
|
|
61
62
|
|
|
62
|
-
//
|
|
63
|
-
if (platform === 'Win32') {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
// Force specific Windows locale patterns
|
|
64
|
+
if (platform === 'Win32' || !platform.includes('Linux')) {
|
|
65
|
+
if (!options || !options.timeZone) {
|
|
66
|
+
windowsOptions.timeZone = cachedTimeZone;
|
|
67
|
+
}
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
// Use Reflect.construct to properly create instance with original constructor
|
|
71
|
+
const formatter = Reflect.construct(OriginalDateTimeFormat, [locales, windowsOptions], OriginalDateTimeFormat);
|
|
72
|
+
|
|
73
|
+
return formatter;
|
|
74
|
+
} finally {
|
|
75
|
+
isCreatingDateTimeFormat = false;
|
|
76
|
+
}
|
|
73
77
|
};
|
|
74
78
|
|
|
75
79
|
// Override Intl.NumberFormat for Windows-consistent number formatting
|
|
76
80
|
const OriginalNumberFormat = Intl.NumberFormat;
|
|
81
|
+
let isCreatingNumberFormat = false; // Recursion guard
|
|
82
|
+
|
|
77
83
|
Intl.NumberFormat = function(locales, options) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (platform === 'Win32') {
|
|
82
|
-
windowsOptions.useGrouping = true;
|
|
83
|
-
if (options && options.style === 'currency') {
|
|
84
|
-
Object.assign(windowsOptions, windowsLocaleConfig.currencyFormat, options);
|
|
85
|
-
}
|
|
84
|
+
// CRITICAL: Recursion guard
|
|
85
|
+
if (isCreatingNumberFormat) {
|
|
86
|
+
return Reflect.construct(OriginalNumberFormat, [locales, options], OriginalNumberFormat);
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const originalFormat = formatter.format;
|
|
92
|
-
formatter.format = function(number) {
|
|
93
|
-
let result = originalFormat.call(this, number);
|
|
89
|
+
isCreatingNumberFormat = true;
|
|
90
|
+
try {
|
|
91
|
+
const windowsOptions = Object.assign({}, windowsLocaleConfig.numberFormat, options);
|
|
94
92
|
|
|
95
|
-
// Windows-specific formatting
|
|
93
|
+
// Windows-specific number formatting
|
|
96
94
|
if (platform === 'Win32') {
|
|
97
|
-
|
|
98
|
-
if (
|
|
99
|
-
|
|
95
|
+
windowsOptions.useGrouping = true;
|
|
96
|
+
if (options && options.style === 'currency') {
|
|
97
|
+
Object.assign(windowsOptions, windowsLocaleConfig.currencyFormat, options);
|
|
100
98
|
}
|
|
101
99
|
}
|
|
102
100
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
101
|
+
// Use Reflect.construct to properly create instance with original constructor
|
|
102
|
+
return Reflect.construct(OriginalNumberFormat, [locales, windowsOptions], OriginalNumberFormat);
|
|
103
|
+
} finally {
|
|
104
|
+
isCreatingNumberFormat = false;
|
|
105
|
+
}
|
|
107
106
|
};
|
|
108
107
|
|
|
109
108
|
// Override Date.prototype methods for consistent formatting
|
|
@@ -140,20 +139,27 @@ export const createLocaleSpoofingScript = () => {
|
|
|
140
139
|
|
|
141
140
|
// Spoof timezone-related methods for consistency
|
|
142
141
|
const originalGetTimezoneOffset = Date.prototype.getTimezoneOffset;
|
|
142
|
+
// Cache winter/summer offsets at init time to prevent recursion
|
|
143
|
+
let cachedWinterOffset = null;
|
|
144
|
+
let cachedSummerOffset = null;
|
|
145
|
+
try {
|
|
146
|
+
const now = new Date();
|
|
147
|
+
cachedWinterOffset = originalGetTimezoneOffset.call(new Date(now.getFullYear(), 0, 1));
|
|
148
|
+
cachedSummerOffset = originalGetTimezoneOffset.call(new Date(now.getFullYear(), 6, 1));
|
|
149
|
+
} catch (e) {
|
|
150
|
+
// Fallback - no DST adjustment
|
|
151
|
+
}
|
|
152
|
+
|
|
143
153
|
Date.prototype.getTimezoneOffset = function() {
|
|
144
154
|
const offset = originalGetTimezoneOffset.call(this);
|
|
145
155
|
|
|
146
156
|
// Ensure timezone offset is reported consistently
|
|
147
157
|
// Windows tends to handle DST slightly differently
|
|
148
|
-
if (platform === 'Win32') {
|
|
149
|
-
const now = new Date();
|
|
150
|
-
const winterOffset = new Date(now.getFullYear(), 0, 1).getTimezoneOffset();
|
|
151
|
-
const summerOffset = new Date(now.getFullYear(), 6, 1).getTimezoneOffset();
|
|
152
|
-
|
|
158
|
+
if (platform === 'Win32' && cachedWinterOffset !== null && cachedSummerOffset !== null) {
|
|
153
159
|
// Apply Windows-style DST calculation if needed
|
|
154
|
-
if (
|
|
155
|
-
const isDST = offset === Math.min(
|
|
156
|
-
return isDST ?
|
|
160
|
+
if (cachedWinterOffset !== cachedSummerOffset) {
|
|
161
|
+
const isDST = offset === Math.min(cachedWinterOffset, cachedSummerOffset);
|
|
162
|
+
return isDST ? cachedSummerOffset : cachedWinterOffset;
|
|
157
163
|
}
|
|
158
164
|
}
|
|
159
165
|
|
|
@@ -163,35 +169,60 @@ export const createLocaleSpoofingScript = () => {
|
|
|
163
169
|
// Override Intl.Collator for Windows-consistent string comparison
|
|
164
170
|
if (typeof Intl.Collator !== 'undefined') {
|
|
165
171
|
const OriginalCollator = Intl.Collator;
|
|
172
|
+
let isCreatingCollator = false;
|
|
166
173
|
Intl.Collator = function(locales, options) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
+
if (isCreatingCollator) {
|
|
175
|
+
return Reflect.construct(OriginalCollator, [locales, options], OriginalCollator);
|
|
176
|
+
}
|
|
177
|
+
isCreatingCollator = true;
|
|
178
|
+
try {
|
|
179
|
+
const windowsOptions = Object.assign({
|
|
180
|
+
sensitivity: 'base',
|
|
181
|
+
usage: 'sort',
|
|
182
|
+
caseFirst: 'upper'
|
|
183
|
+
}, options);
|
|
184
|
+
return Reflect.construct(OriginalCollator, [locales, windowsOptions], OriginalCollator);
|
|
185
|
+
} finally {
|
|
186
|
+
isCreatingCollator = false;
|
|
187
|
+
}
|
|
174
188
|
};
|
|
175
189
|
}
|
|
176
190
|
|
|
177
191
|
// Override Intl.PluralRules for consistency
|
|
178
192
|
if (typeof Intl.PluralRules !== 'undefined') {
|
|
179
193
|
const OriginalPluralRules = Intl.PluralRules;
|
|
194
|
+
let isCreatingPluralRules = false;
|
|
180
195
|
Intl.PluralRules = function(locales, options) {
|
|
181
|
-
|
|
196
|
+
if (isCreatingPluralRules) {
|
|
197
|
+
return Reflect.construct(OriginalPluralRules, [locales, options], OriginalPluralRules);
|
|
198
|
+
}
|
|
199
|
+
isCreatingPluralRules = true;
|
|
200
|
+
try {
|
|
201
|
+
return Reflect.construct(OriginalPluralRules, [locales || 'en-US', options], OriginalPluralRules);
|
|
202
|
+
} finally {
|
|
203
|
+
isCreatingPluralRules = false;
|
|
204
|
+
}
|
|
182
205
|
};
|
|
183
206
|
}
|
|
184
207
|
|
|
185
208
|
// Override Intl.RelativeTimeFormat if available
|
|
186
209
|
if (typeof Intl.RelativeTimeFormat !== 'undefined') {
|
|
187
210
|
const OriginalRelativeTimeFormat = Intl.RelativeTimeFormat;
|
|
211
|
+
let isCreatingRelativeTimeFormat = false;
|
|
188
212
|
Intl.RelativeTimeFormat = function(locales, options) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
213
|
+
if (isCreatingRelativeTimeFormat) {
|
|
214
|
+
return Reflect.construct(OriginalRelativeTimeFormat, [locales, options], OriginalRelativeTimeFormat);
|
|
215
|
+
}
|
|
216
|
+
isCreatingRelativeTimeFormat = true;
|
|
217
|
+
try {
|
|
218
|
+
const windowsOptions = Object.assign({
|
|
219
|
+
style: 'long',
|
|
220
|
+
numeric: 'auto'
|
|
221
|
+
}, options);
|
|
222
|
+
return Reflect.construct(OriginalRelativeTimeFormat, [locales || 'en-US', windowsOptions], OriginalRelativeTimeFormat);
|
|
223
|
+
} finally {
|
|
224
|
+
isCreatingRelativeTimeFormat = false;
|
|
225
|
+
}
|
|
195
226
|
};
|
|
196
227
|
}
|
|
197
228
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locale-spoofing.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/locale-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAW,EAAE;IACnD,OAAO
|
|
1
|
+
{"version":3,"file":"locale-spoofing.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/locale-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAW,EAAE;IACnD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6TV,CAAC;AACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prototype Integrity Module
|
|
3
|
+
*
|
|
4
|
+
* Ensures all property overrides are undetectable by:
|
|
5
|
+
* - Making overridden properties appear native (configurable: false)
|
|
6
|
+
* - Hiding modified property descriptors from Object.getOwnPropertyDescriptor
|
|
7
|
+
* - Protecting prototype chains from Object.getPrototypeOf inspection
|
|
8
|
+
* - Masking shadow properties from enumeration
|
|
9
|
+
*
|
|
10
|
+
* This module MUST be injected FIRST, before any other fingerprint overrides.
|
|
11
|
+
*/
|
|
12
|
+
export declare const createPrototypeIntegrityScript: () => string;
|
|
13
|
+
//# sourceMappingURL=prototype-integrity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prototype-integrity.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/prototype-integrity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,8BAA8B,QAAO,MAsVjD,CAAC"}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prototype Integrity Module
|
|
3
|
+
*
|
|
4
|
+
* Ensures all property overrides are undetectable by:
|
|
5
|
+
* - Making overridden properties appear native (configurable: false)
|
|
6
|
+
* - Hiding modified property descriptors from Object.getOwnPropertyDescriptor
|
|
7
|
+
* - Protecting prototype chains from Object.getPrototypeOf inspection
|
|
8
|
+
* - Masking shadow properties from enumeration
|
|
9
|
+
*
|
|
10
|
+
* This module MUST be injected FIRST, before any other fingerprint overrides.
|
|
11
|
+
*/
|
|
12
|
+
export const createPrototypeIntegrityScript = () => {
|
|
13
|
+
return `
|
|
14
|
+
(() => {
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
// Skip if already initialized
|
|
18
|
+
if (window.__PROTOTYPE_INTEGRITY_INITIALIZED__) return;
|
|
19
|
+
window.__PROTOTYPE_INTEGRITY_INITIALIZED__ = true;
|
|
20
|
+
|
|
21
|
+
// ============================================
|
|
22
|
+
// PROTOTYPE INTEGRITY - Hide All Overrides
|
|
23
|
+
// ============================================
|
|
24
|
+
|
|
25
|
+
// Shadow maps to track original descriptors and overrides
|
|
26
|
+
const originalDescriptors = new WeakMap(); // obj -> Map<prop, originalDescriptor>
|
|
27
|
+
const overriddenProperties = new WeakMap(); // obj -> Set<prop>
|
|
28
|
+
const fakeDescriptors = new WeakMap(); // obj -> Map<prop, fakeDescriptor>
|
|
29
|
+
|
|
30
|
+
// Cache original functions BEFORE any modifications
|
|
31
|
+
const _Object = Object;
|
|
32
|
+
const _Reflect = Reflect;
|
|
33
|
+
const _getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
|
34
|
+
const _getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors;
|
|
35
|
+
const _getPrototypeOf = Object.getPrototypeOf;
|
|
36
|
+
const _defineProperty = Object.defineProperty;
|
|
37
|
+
const _getOwnPropertyNames = Object.getOwnPropertyNames;
|
|
38
|
+
const _keys = Object.keys;
|
|
39
|
+
const _hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
40
|
+
const _ReflectGetOwnPropertyDescriptor = Reflect.getOwnPropertyDescriptor;
|
|
41
|
+
const _ReflectDefineProperty = Reflect.defineProperty;
|
|
42
|
+
const _ReflectOwnKeys = Reflect.ownKeys;
|
|
43
|
+
const _ReflectGet = Reflect.get;
|
|
44
|
+
const _ReflectHas = Reflect.has;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Register a property as overridden and cache its original descriptor
|
|
48
|
+
*/
|
|
49
|
+
const registerOverride = (obj, prop, originalDescriptor) => {
|
|
50
|
+
if (!originalDescriptors.has(obj)) {
|
|
51
|
+
originalDescriptors.set(obj, new Map());
|
|
52
|
+
}
|
|
53
|
+
if (!overriddenProperties.has(obj)) {
|
|
54
|
+
overriddenProperties.set(obj, new Set());
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const objDescriptors = originalDescriptors.get(obj);
|
|
58
|
+
const objOverrides = overriddenProperties.get(obj);
|
|
59
|
+
|
|
60
|
+
// Only cache original if not already cached
|
|
61
|
+
if (!objDescriptors.has(prop) && originalDescriptor) {
|
|
62
|
+
objDescriptors.set(prop, originalDescriptor);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
objOverrides.add(prop);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Check if a property has been overridden
|
|
70
|
+
*/
|
|
71
|
+
const isOverridden = (obj, prop) => {
|
|
72
|
+
const objOverrides = overriddenProperties.get(obj);
|
|
73
|
+
return objOverrides ? objOverrides.has(prop) : false;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Get the original descriptor for an overridden property
|
|
78
|
+
*/
|
|
79
|
+
const getOriginalDescriptor = (obj, prop) => {
|
|
80
|
+
const objDescriptors = originalDescriptors.get(obj);
|
|
81
|
+
return objDescriptors ? objDescriptors.get(prop) : undefined;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Create a native-like descriptor that hides the override
|
|
86
|
+
*/
|
|
87
|
+
const createNativeDescriptor = (obj, prop, actualDescriptor) => {
|
|
88
|
+
const original = getOriginalDescriptor(obj, prop);
|
|
89
|
+
|
|
90
|
+
if (original) {
|
|
91
|
+
// Return a descriptor that looks like the original
|
|
92
|
+
// but actually uses our getter/setter
|
|
93
|
+
return {
|
|
94
|
+
configurable: original.configurable !== undefined ? original.configurable : false,
|
|
95
|
+
enumerable: original.enumerable !== undefined ? original.enumerable : true,
|
|
96
|
+
get: actualDescriptor?.get,
|
|
97
|
+
set: actualDescriptor?.set,
|
|
98
|
+
value: actualDescriptor?.value,
|
|
99
|
+
writable: original.writable
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Default: make it look like a native property
|
|
104
|
+
if (actualDescriptor?.get || actualDescriptor?.set) {
|
|
105
|
+
return {
|
|
106
|
+
configurable: false,
|
|
107
|
+
enumerable: true,
|
|
108
|
+
get: actualDescriptor.get,
|
|
109
|
+
set: actualDescriptor.set
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
configurable: false,
|
|
115
|
+
enumerable: true,
|
|
116
|
+
writable: false,
|
|
117
|
+
value: actualDescriptor?.value
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Set a fake descriptor to return for getOwnPropertyDescriptor
|
|
123
|
+
*/
|
|
124
|
+
const setFakeDescriptor = (obj, prop, descriptor) => {
|
|
125
|
+
if (!fakeDescriptors.has(obj)) {
|
|
126
|
+
fakeDescriptors.set(obj, new Map());
|
|
127
|
+
}
|
|
128
|
+
fakeDescriptors.get(obj).set(prop, descriptor);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Override a property with native-like appearance
|
|
133
|
+
* This is the main function other modules should use
|
|
134
|
+
*/
|
|
135
|
+
const overridePropertyNative = (obj, prop, descriptor) => {
|
|
136
|
+
// Cache original descriptor first
|
|
137
|
+
const originalDescriptor = _getOwnPropertyDescriptor.call(_Object, obj, prop);
|
|
138
|
+
registerOverride(obj, prop, originalDescriptor);
|
|
139
|
+
|
|
140
|
+
// Apply the actual override
|
|
141
|
+
try {
|
|
142
|
+
_defineProperty.call(_Object, obj, prop, {
|
|
143
|
+
...descriptor,
|
|
144
|
+
configurable: true // We need this to work, but will fake it
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Set up the fake descriptor to return
|
|
148
|
+
const fakeDesc = createNativeDescriptor(obj, prop, descriptor);
|
|
149
|
+
setFakeDescriptor(obj, prop, fakeDesc);
|
|
150
|
+
|
|
151
|
+
return true;
|
|
152
|
+
} catch (e) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Override Object.getOwnPropertyDescriptor to hide our modifications
|
|
159
|
+
*/
|
|
160
|
+
const patchGetOwnPropertyDescriptor = () => {
|
|
161
|
+
_defineProperty.call(_Object, _Object, 'getOwnPropertyDescriptor', {
|
|
162
|
+
value: function(obj, prop) {
|
|
163
|
+
// Check if we have a fake descriptor for this property
|
|
164
|
+
const objFakes = fakeDescriptors.get(obj);
|
|
165
|
+
if (objFakes && objFakes.has(prop)) {
|
|
166
|
+
const fake = objFakes.get(prop);
|
|
167
|
+
// Return a copy to prevent modification
|
|
168
|
+
return { ...fake };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Otherwise return the real descriptor
|
|
172
|
+
return _getOwnPropertyDescriptor.call(_Object, obj, prop);
|
|
173
|
+
},
|
|
174
|
+
writable: true,
|
|
175
|
+
configurable: true
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Also patch Reflect.getOwnPropertyDescriptor
|
|
179
|
+
if (_Reflect && _ReflectGetOwnPropertyDescriptor) {
|
|
180
|
+
_defineProperty.call(_Object, _Reflect, 'getOwnPropertyDescriptor', {
|
|
181
|
+
value: function(obj, prop) {
|
|
182
|
+
const objFakes = fakeDescriptors.get(obj);
|
|
183
|
+
if (objFakes && objFakes.has(prop)) {
|
|
184
|
+
return { ...objFakes.get(prop) };
|
|
185
|
+
}
|
|
186
|
+
return _ReflectGetOwnPropertyDescriptor.call(_Reflect, obj, prop);
|
|
187
|
+
},
|
|
188
|
+
writable: true,
|
|
189
|
+
configurable: true
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Override Object.getOwnPropertyDescriptors to use our patched version
|
|
196
|
+
*/
|
|
197
|
+
const patchGetOwnPropertyDescriptors = () => {
|
|
198
|
+
_defineProperty.call(_Object, _Object, 'getOwnPropertyDescriptors', {
|
|
199
|
+
value: function(obj) {
|
|
200
|
+
const result = {};
|
|
201
|
+
const props = _getOwnPropertyNames.call(_Object, obj);
|
|
202
|
+
|
|
203
|
+
for (const prop of props) {
|
|
204
|
+
// Use our patched getOwnPropertyDescriptor
|
|
205
|
+
const desc = _Object.getOwnPropertyDescriptor(obj, prop);
|
|
206
|
+
if (desc) {
|
|
207
|
+
result[prop] = desc;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Also include symbol properties
|
|
212
|
+
const symbols = _Object.getOwnPropertySymbols ? _Object.getOwnPropertySymbols(obj) : [];
|
|
213
|
+
for (const sym of symbols) {
|
|
214
|
+
const desc = _Object.getOwnPropertyDescriptor(obj, sym);
|
|
215
|
+
if (desc) {
|
|
216
|
+
result[sym] = desc;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return result;
|
|
221
|
+
},
|
|
222
|
+
writable: true,
|
|
223
|
+
configurable: true
|
|
224
|
+
});
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Protect prototype chain inspection
|
|
229
|
+
*/
|
|
230
|
+
const patchGetPrototypeOf = () => {
|
|
231
|
+
// Store original prototypes before any modification
|
|
232
|
+
const originalPrototypes = new WeakMap();
|
|
233
|
+
|
|
234
|
+
// We don't modify Object.getPrototypeOf because we want prototypes to look normal
|
|
235
|
+
// But we can use this to verify prototype chains are intact
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Patch Object.keys to filter automation properties
|
|
240
|
+
*/
|
|
241
|
+
const patchObjectKeys = () => {
|
|
242
|
+
const automationProps = new Set([
|
|
243
|
+
'webdriver', '__webdriver_evaluate', '__selenium_evaluate',
|
|
244
|
+
'__driver_evaluate', '__webdriver_script_function',
|
|
245
|
+
'__webdriver_script_fn', '__fxdriver_evaluate',
|
|
246
|
+
'__webdriver_unwrapped', '$cdc_', 'cdc_'
|
|
247
|
+
]);
|
|
248
|
+
|
|
249
|
+
_defineProperty.call(_Object, _Object, 'keys', {
|
|
250
|
+
value: function(obj) {
|
|
251
|
+
const keys = _keys.call(_Object, obj);
|
|
252
|
+
return keys.filter(key => {
|
|
253
|
+
const keyStr = String(key).toLowerCase();
|
|
254
|
+
for (const autoProp of automationProps) {
|
|
255
|
+
if (keyStr.includes(autoProp.toLowerCase())) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return true;
|
|
260
|
+
});
|
|
261
|
+
},
|
|
262
|
+
writable: true,
|
|
263
|
+
configurable: true
|
|
264
|
+
});
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Patch Object.getOwnPropertyNames to filter automation properties
|
|
269
|
+
*/
|
|
270
|
+
const patchGetOwnPropertyNames = () => {
|
|
271
|
+
const automationProps = new Set([
|
|
272
|
+
'webdriver', '__webdriver_evaluate', '__selenium_evaluate',
|
|
273
|
+
'__driver_evaluate', '__webdriver_script_function',
|
|
274
|
+
'__webdriver_script_fn', '__fxdriver_evaluate',
|
|
275
|
+
'__webdriver_unwrapped', '$cdc_', 'cdc_', '__puppeteer',
|
|
276
|
+
'__playwright'
|
|
277
|
+
]);
|
|
278
|
+
|
|
279
|
+
_defineProperty.call(_Object, _Object, 'getOwnPropertyNames', {
|
|
280
|
+
value: function(obj) {
|
|
281
|
+
const names = _getOwnPropertyNames.call(_Object, obj);
|
|
282
|
+
return names.filter(name => {
|
|
283
|
+
const nameStr = String(name).toLowerCase();
|
|
284
|
+
for (const autoProp of automationProps) {
|
|
285
|
+
if (nameStr.includes(autoProp.toLowerCase())) {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return true;
|
|
290
|
+
});
|
|
291
|
+
},
|
|
292
|
+
writable: true,
|
|
293
|
+
configurable: true
|
|
294
|
+
});
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Patch Reflect.ownKeys to filter automation properties
|
|
299
|
+
*/
|
|
300
|
+
const patchReflectOwnKeys = () => {
|
|
301
|
+
if (!_Reflect || !_ReflectOwnKeys) return;
|
|
302
|
+
|
|
303
|
+
const automationProps = new Set([
|
|
304
|
+
'webdriver', '__webdriver', '__selenium', '__driver',
|
|
305
|
+
'__puppeteer', '__playwright', '$cdc_', 'cdc_'
|
|
306
|
+
]);
|
|
307
|
+
|
|
308
|
+
_defineProperty.call(_Object, _Reflect, 'ownKeys', {
|
|
309
|
+
value: function(obj) {
|
|
310
|
+
const keys = _ReflectOwnKeys.call(_Reflect, obj);
|
|
311
|
+
return keys.filter(key => {
|
|
312
|
+
const keyStr = String(key).toLowerCase();
|
|
313
|
+
for (const autoProp of automationProps) {
|
|
314
|
+
if (keyStr.includes(autoProp.toLowerCase())) {
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return true;
|
|
319
|
+
});
|
|
320
|
+
},
|
|
321
|
+
writable: true,
|
|
322
|
+
configurable: true
|
|
323
|
+
});
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Initialize all prototype integrity patches
|
|
328
|
+
*/
|
|
329
|
+
const initialize = () => {
|
|
330
|
+
patchGetOwnPropertyDescriptor();
|
|
331
|
+
patchGetOwnPropertyDescriptors();
|
|
332
|
+
patchGetPrototypeOf();
|
|
333
|
+
patchObjectKeys();
|
|
334
|
+
patchGetOwnPropertyNames();
|
|
335
|
+
patchReflectOwnKeys();
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
// Initialize immediately
|
|
339
|
+
initialize();
|
|
340
|
+
|
|
341
|
+
// Export utilities for use by other modules
|
|
342
|
+
window.__prototypeIntegrity__ = {
|
|
343
|
+
registerOverride,
|
|
344
|
+
isOverridden,
|
|
345
|
+
getOriginalDescriptor,
|
|
346
|
+
setFakeDescriptor,
|
|
347
|
+
overridePropertyNative,
|
|
348
|
+
createNativeDescriptor
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
console.log('[CDP-FP-DEBUG] ✓ Prototype integrity initialized');
|
|
352
|
+
})();
|
|
353
|
+
`;
|
|
354
|
+
};
|
|
355
|
+
//# sourceMappingURL=prototype-integrity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prototype-integrity.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/prototype-integrity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAAW,EAAE;IACvD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoVV,CAAC;AACF,CAAC,CAAC"}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* IMPORTANT: This is now a SCRIPT to be injected via addScriptToEvaluateOnNewDocument,
|
|
6
6
|
* NOT via Runtime.evaluate (which would defeat the purpose since Runtime.evaluate IS detectable!)
|
|
7
|
+
*
|
|
8
|
+
* Enhanced 2024-2025: Comprehensive stack trace sanitization that removes ALL CDP markers
|
|
7
9
|
*/
|
|
8
10
|
/**
|
|
9
11
|
* Creates the runtime enable bypass script that should be bundled with other stealth scripts.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-enable-bypass.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/runtime-enable-bypass.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"runtime-enable-bypass.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/runtime-enable-bypass.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;GAGG;AACH,eAAO,MAAM,+BAA+B,QAAO,MAmQlD,CAAC"}
|