jumpy-lion 0.0.33 → 0.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-controller.d.ts +2 -2
- package/dist/browser-controller.d.ts.map +1 -1
- package/dist/browser-controller.js +34 -5
- package/dist/browser-controller.js.map +1 -1
- package/dist/browser-plugin.d.ts +21 -0
- package/dist/browser-plugin.d.ts.map +1 -1
- package/dist/browser-plugin.js +10 -4
- package/dist/browser-plugin.js.map +1 -1
- package/dist/browser-process/browser.d.ts +15 -0
- package/dist/browser-process/browser.d.ts.map +1 -1
- package/dist/browser-process/browser.js +6 -3
- package/dist/browser-process/browser.js.map +1 -1
- package/dist/crawler.d.ts +15 -0
- package/dist/crawler.d.ts.map +1 -1
- package/dist/crawler.js.map +1 -1
- package/dist/fingerprinting/anti-webgpu/background.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/background.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/background.js +6 -0
- package/dist/fingerprinting/anti-webgpu/background.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/inject.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/inject.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/inject.js +50 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/inject.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/page_context/inject.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/page_context/inject.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/page_context/inject.js +179 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/page_context/inject.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/popup/popup.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/data/popup/popup.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/popup/popup.js +95 -0
- package/dist/fingerprinting/anti-webgpu/data/popup/popup.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/chrome.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/lib/chrome.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/chrome.js +255 -0
- package/dist/fingerprinting/anti-webgpu/lib/chrome.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/common.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/lib/common.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/common.js +87 -0
- package/dist/fingerprinting/anti-webgpu/lib/common.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/config.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/lib/config.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/config.js +13 -0
- package/dist/fingerprinting/anti-webgpu/lib/config.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/runtime.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/lib/runtime.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/runtime.js +109 -0
- package/dist/fingerprinting/anti-webgpu/lib/runtime.js.map +1 -0
- package/dist/fingerprinting/fingerprint-injector.d.ts +85 -1
- package/dist/fingerprinting/fingerprint-injector.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-injector.js +188 -90
- package/dist/fingerprinting/fingerprint-injector.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.js +87 -0
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.js +95 -0
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.js +96 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.d.ts +7 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.js +219 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts +19 -0
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/index.js +19 -0
- package/dist/fingerprinting/fingerprint-overrides/index.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js +262 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.d.ts +7 -0
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.js +103 -0
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.js +228 -0
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts +20 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js +227 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js +84 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js +440 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js +95 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts +12 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js +167 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.js +205 -0
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js +96 -0
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/page.d.ts +1 -0
- package/dist/page.d.ts.map +1 -1
- package/dist/page.js +42 -1
- package/dist/page.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime.enable Bypass
|
|
3
|
+
* Prevents CDP detection through console.log(Error) technique
|
|
4
|
+
*/
|
|
5
|
+
export const setupRuntimeEnableBypass = async (client) => {
|
|
6
|
+
// Intercept Runtime.enable calls to prevent detection
|
|
7
|
+
await client.send('Runtime.evaluate', {
|
|
8
|
+
expression: `
|
|
9
|
+
(() => {
|
|
10
|
+
// Store the original CDP send method if accessible
|
|
11
|
+
if (window.__CDP_CLIENT__) {
|
|
12
|
+
const originalSend = window.__CDP_CLIENT__.send;
|
|
13
|
+
window.__CDP_CLIENT__.send = function(method, params) {
|
|
14
|
+
// Block or modify Runtime.enable calls
|
|
15
|
+
if (method === 'Runtime.enable') {
|
|
16
|
+
console.log('Runtime.enable blocked');
|
|
17
|
+
return Promise.resolve({});
|
|
18
|
+
}
|
|
19
|
+
return originalSend.apply(this, arguments);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Additional protection against CDP detection
|
|
24
|
+
const originalError = Error;
|
|
25
|
+
let errorCounter = 0;
|
|
26
|
+
|
|
27
|
+
window.Error = new Proxy(originalError, {
|
|
28
|
+
construct(target, args) {
|
|
29
|
+
const error = Reflect.construct(target, args);
|
|
30
|
+
|
|
31
|
+
// Detect CDP serialization attempts
|
|
32
|
+
const stack = new originalError().stack;
|
|
33
|
+
if (stack && stack.includes('__puppeteer_evaluation_script__')) {
|
|
34
|
+
// This is likely a CDP evaluation, modify behavior
|
|
35
|
+
Object.defineProperty(error, 'stack', {
|
|
36
|
+
get() {
|
|
37
|
+
return 'Error\\n at <anonymous>:1:1';
|
|
38
|
+
},
|
|
39
|
+
configurable: false
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return error;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Protect against console-based CDP detection
|
|
48
|
+
const protectedConsole = new Proxy(console, {
|
|
49
|
+
get(target, prop) {
|
|
50
|
+
const original = target[prop];
|
|
51
|
+
if (typeof original === 'function') {
|
|
52
|
+
return new Proxy(original, {
|
|
53
|
+
apply(fn, thisArg, args) {
|
|
54
|
+
// Filter out Error objects that might be used for CDP detection
|
|
55
|
+
const filteredArgs = args.map(arg => {
|
|
56
|
+
if (arg instanceof Error && arg.stack) {
|
|
57
|
+
// Check if this might be a CDP detection attempt
|
|
58
|
+
const stackString = arg.stack.toString();
|
|
59
|
+
if (stackString.includes('Error.captureStackTrace') ||
|
|
60
|
+
stackString.includes('__puppeteer_evaluation_script__')) {
|
|
61
|
+
return arg.toString();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return arg;
|
|
65
|
+
});
|
|
66
|
+
return Reflect.apply(fn, thisArg, filteredArgs);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return original;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
Object.defineProperty(window, 'console', {
|
|
76
|
+
value: protectedConsole,
|
|
77
|
+
writable: false,
|
|
78
|
+
configurable: false
|
|
79
|
+
});
|
|
80
|
+
} catch (e) {}
|
|
81
|
+
})();`,
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=runtime-enable-bypass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-enable-bypass.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/runtime-enable-bypass.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,EAAE,MAAW,EAAiB,EAAE;IACzE,sDAAsD;IACtD,MAAM,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE;QAClC,UAAU,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAyEd;KACD,CAAC,CAAC;AACP,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stealth-script.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/stealth-script.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,mBAAmB,QAAO,MAkbtC,CAAC"}
|
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base stealth script for hiding automation indicators
|
|
3
|
+
* Includes error stack hiding, console patching, and automation flags removal
|
|
4
|
+
*/
|
|
5
|
+
export const createStealthScript = () => {
|
|
6
|
+
return `
|
|
7
|
+
(() => {
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
// Enhanced stealth script for 2025 - July
|
|
11
|
+
|
|
12
|
+
// Helper functions
|
|
13
|
+
const wrapNative = (fnName) => {
|
|
14
|
+
const nativeCode = 'function ' + fnName + '() { [native code] }';
|
|
15
|
+
return new Proxy(function() {}, {
|
|
16
|
+
get(target, prop) {
|
|
17
|
+
if (prop === 'toString') {
|
|
18
|
+
return () => nativeCode;
|
|
19
|
+
}
|
|
20
|
+
return Reflect.get(target, prop);
|
|
21
|
+
},
|
|
22
|
+
apply(target, thisArg, args) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// 1. Enhanced Error Stack Hiding (2025)
|
|
29
|
+
const hideErrorStack = () => {
|
|
30
|
+
const originalStackDescriptor = Object.getOwnPropertyDescriptor(Error.prototype, 'stack');
|
|
31
|
+
if (originalStackDescriptor?.configurable) {
|
|
32
|
+
const originalPrepareStackTrace = Error.prepareStackTrace;
|
|
33
|
+
|
|
34
|
+
Object.defineProperty(Error.prototype, 'stack', {
|
|
35
|
+
get() {
|
|
36
|
+
// Return a Chrome-like stack trace instead of Node.js
|
|
37
|
+
const stack = \`Error
|
|
38
|
+
at Object.invoke (chrome-extension://invalid/0.js:1:23)
|
|
39
|
+
at Object.next (chrome-extension://invalid/0.js:1:53)
|
|
40
|
+
at async HTMLDocument.<anonymous> (https://g2.com/:1:107)\`;
|
|
41
|
+
return stack;
|
|
42
|
+
},
|
|
43
|
+
set() {},
|
|
44
|
+
configurable: false,
|
|
45
|
+
enumerable: false
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Override prepareStackTrace to prevent CDP detection
|
|
49
|
+
Error.prepareStackTrace = function(error, stack) {
|
|
50
|
+
if (originalPrepareStackTrace) {
|
|
51
|
+
return originalPrepareStackTrace(error, stack);
|
|
52
|
+
}
|
|
53
|
+
return error.toString();
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// 2. Advanced Console Patching (2025)
|
|
59
|
+
const patchConsole = () => {
|
|
60
|
+
const _console = window.console;
|
|
61
|
+
if (!_console || typeof _console !== 'object') return;
|
|
62
|
+
|
|
63
|
+
// Store original methods
|
|
64
|
+
const originalMethods = {};
|
|
65
|
+
['log', 'warn', 'error', 'info', 'debug', 'trace', 'dir', 'dirxml', 'group',
|
|
66
|
+
'groupCollapsed', 'groupEnd', 'time', 'timeEnd', 'timeLog', 'assert', 'count',
|
|
67
|
+
'countReset', 'profile', 'profileEnd', 'table'].forEach(method => {
|
|
68
|
+
if (_console[method]) {
|
|
69
|
+
originalMethods[method] = _console[method];
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Create a proxy for console to intercept CDP detection
|
|
74
|
+
const consoleProxy = new Proxy(_console, {
|
|
75
|
+
get(target, prop) {
|
|
76
|
+
if (prop in originalMethods) {
|
|
77
|
+
return new Proxy(originalMethods[prop], {
|
|
78
|
+
apply(fn, thisArg, args) {
|
|
79
|
+
// Filter out Error objects to prevent stack serialization
|
|
80
|
+
const filteredArgs = args.map(arg => {
|
|
81
|
+
if (arg instanceof Error) {
|
|
82
|
+
return arg.toString();
|
|
83
|
+
}
|
|
84
|
+
return arg;
|
|
85
|
+
});
|
|
86
|
+
return Reflect.apply(fn, _console, filteredArgs);
|
|
87
|
+
},
|
|
88
|
+
get(target, prop) {
|
|
89
|
+
if (prop === 'toString') {
|
|
90
|
+
return wrapNative(prop);
|
|
91
|
+
}
|
|
92
|
+
return Reflect.get(target, prop);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return Reflect.get(target, prop);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
Object.defineProperty(window, 'console', {
|
|
102
|
+
value: consoleProxy,
|
|
103
|
+
configurable: false,
|
|
104
|
+
writable: false,
|
|
105
|
+
enumerable: true
|
|
106
|
+
});
|
|
107
|
+
} catch (e) {
|
|
108
|
+
// Fallback if defineProperty fails
|
|
109
|
+
window.console = consoleProxy;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// 3. WebDriver and Automation Flags Removal (2025)
|
|
114
|
+
const removeAutomationFlags = () => {
|
|
115
|
+
// Remove webdriver
|
|
116
|
+
if (navigator.webdriver) {
|
|
117
|
+
Object.defineProperty(navigator, 'webdriver', {
|
|
118
|
+
get: () => undefined,
|
|
119
|
+
configurable: false
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Remove automation indicators
|
|
124
|
+
const automationProperties = [
|
|
125
|
+
'webdriver', '_Selenium_IDE_Recorder', '_selenium', 'callSelenium',
|
|
126
|
+
'_WEBDRIVER_ELEM_CACHE', '__webdriver_script_fn', '__driver_evaluate',
|
|
127
|
+
'__webdriver_evaluate', '__selenium_evaluate', '__fxdriver_evaluate',
|
|
128
|
+
'__driver_unwrapped', '__webdriver_unwrapped', '__selenium_unwrapped',
|
|
129
|
+
'__fxdriver_unwrapped', '__webdriver_scripts_executed',
|
|
130
|
+
'__webdriver_script_func', '__webdriver_script_function',
|
|
131
|
+
'$cdc_asdjflasutopfhvcZLmcfl_', '$chrome_asyncScriptInfo',
|
|
132
|
+
'__$webdriverAsyncExecutor', '__lastWatirAlert', '__lastWatirConfirm',
|
|
133
|
+
'__lastWatirPrompt', '_WEBDRIVER_ELEM_CACHE', 'ChromeDriverw',
|
|
134
|
+
'driver-evaluate', 'webdriver-evaluate', 'selenium-evaluate',
|
|
135
|
+
'webdriverCommand', 'webdriver-evaluate-response'
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
automationProperties.forEach(prop => {
|
|
139
|
+
try {
|
|
140
|
+
delete window[prop];
|
|
141
|
+
delete document[prop];
|
|
142
|
+
delete navigator[prop];
|
|
143
|
+
} catch (e) {}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Remove CDP specific properties
|
|
147
|
+
if (window.chrome) {
|
|
148
|
+
const originalChrome = window.chrome;
|
|
149
|
+
Object.defineProperty(window, 'chrome', {
|
|
150
|
+
get() {
|
|
151
|
+
if (new Error().stack.includes('evaluateOnNewDocument')) {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
return originalChrome;
|
|
155
|
+
},
|
|
156
|
+
configurable: false
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// 4. CDP Runtime.enable Detection Prevention (2025)
|
|
162
|
+
const preventRuntimeEnableDetection = () => {
|
|
163
|
+
// Override Object.defineProperty to prevent CDP detection
|
|
164
|
+
const originalDefineProperty = Object.defineProperty;
|
|
165
|
+
Object.defineProperty = new Proxy(originalDefineProperty, {
|
|
166
|
+
apply(target, thisArg, args) {
|
|
167
|
+
const [obj, prop, descriptor] = args;
|
|
168
|
+
|
|
169
|
+
// Prevent CDP from defining properties that expose automation
|
|
170
|
+
if (prop === 'stack' && descriptor && descriptor.get) {
|
|
171
|
+
// This is likely a CDP detection attempt
|
|
172
|
+
return obj;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return Reflect.apply(target, thisArg, args);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Patch Error constructor to prevent stack trace manipulation
|
|
180
|
+
const OriginalError = Error;
|
|
181
|
+
window.Error = new Proxy(OriginalError, {
|
|
182
|
+
construct(target, args) {
|
|
183
|
+
const error = Reflect.construct(target, args);
|
|
184
|
+
|
|
185
|
+
// Override the stack getter/setter with Chrome-like stack
|
|
186
|
+
Object.defineProperty(error, 'stack', {
|
|
187
|
+
get() {
|
|
188
|
+
return \`Error: \${error.message}
|
|
189
|
+
at Object.invoke (chrome-extension://invalid/0.js:1:23)
|
|
190
|
+
at Object.next (chrome-extension://invalid/0.js:1:53)\`;
|
|
191
|
+
},
|
|
192
|
+
set() {},
|
|
193
|
+
configurable: false
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
return error;
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
window.Error.prototype = OriginalError.prototype;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
// 5. Plugin and MimeType Spoofing (2025)
|
|
203
|
+
const spoofPlugins = () => {
|
|
204
|
+
const pluginData = [
|
|
205
|
+
{
|
|
206
|
+
name: 'Chrome PDF Plugin',
|
|
207
|
+
filename: 'internal-pdf-viewer',
|
|
208
|
+
description: 'Portable Document Format'
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: 'Chrome PDF Viewer',
|
|
212
|
+
filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai',
|
|
213
|
+
description: 'Portable Document Format'
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: 'Native Client',
|
|
217
|
+
filename: 'internal-nacl-plugin',
|
|
218
|
+
description: 'Native Client Executable'
|
|
219
|
+
}
|
|
220
|
+
];
|
|
221
|
+
|
|
222
|
+
const mimeData = [
|
|
223
|
+
{
|
|
224
|
+
type: 'application/pdf',
|
|
225
|
+
suffixes: 'pdf',
|
|
226
|
+
description: 'Portable Document Format'
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
type: 'application/x-nacl',
|
|
230
|
+
suffixes: '',
|
|
231
|
+
description: 'Native Client Executable'
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
type: 'application/x-pnacl',
|
|
235
|
+
suffixes: '',
|
|
236
|
+
description: 'Portable Native Client Executable'
|
|
237
|
+
}
|
|
238
|
+
];
|
|
239
|
+
|
|
240
|
+
// Create fake plugins
|
|
241
|
+
const fakePlugins = pluginData.map((p, index) => {
|
|
242
|
+
const plugin = Object.create(Plugin.prototype);
|
|
243
|
+
plugin.name = p.name;
|
|
244
|
+
plugin.filename = p.filename;
|
|
245
|
+
plugin.description = p.description;
|
|
246
|
+
plugin.length = 1;
|
|
247
|
+
plugin[0] = mimeData[index] || mimeData[0];
|
|
248
|
+
return plugin;
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// Create fake mimeTypes
|
|
252
|
+
const fakeMimeTypes = mimeData.map((m, index) => {
|
|
253
|
+
const mimeType = Object.create(MimeType.prototype);
|
|
254
|
+
mimeType.type = m.type;
|
|
255
|
+
mimeType.suffixes = m.suffixes;
|
|
256
|
+
mimeType.description = m.description;
|
|
257
|
+
mimeType.enabledPlugin = fakePlugins[0];
|
|
258
|
+
return mimeType;
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// Override navigator.plugins
|
|
262
|
+
try {
|
|
263
|
+
Object.defineProperty(navigator, 'plugins', {
|
|
264
|
+
get: () => {
|
|
265
|
+
const arr = Object.create(PluginArray.prototype);
|
|
266
|
+
fakePlugins.forEach((p, i) => {
|
|
267
|
+
arr[i] = p;
|
|
268
|
+
arr[p.name] = p;
|
|
269
|
+
});
|
|
270
|
+
arr.length = fakePlugins.length;
|
|
271
|
+
arr.item = (index) => arr[index] || null;
|
|
272
|
+
arr.namedItem = (name) => arr[name] || null;
|
|
273
|
+
arr.refresh = () => {};
|
|
274
|
+
return arr;
|
|
275
|
+
},
|
|
276
|
+
configurable: false,
|
|
277
|
+
enumerable: true
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Override navigator.mimeTypes
|
|
281
|
+
Object.defineProperty(navigator, 'mimeTypes', {
|
|
282
|
+
get: () => {
|
|
283
|
+
const arr = Object.create(MimeTypeArray.prototype);
|
|
284
|
+
fakeMimeTypes.forEach((m, i) => {
|
|
285
|
+
arr[i] = m;
|
|
286
|
+
arr[m.type] = m;
|
|
287
|
+
});
|
|
288
|
+
arr.length = fakeMimeTypes.length;
|
|
289
|
+
arr.item = (index) => arr[index] || null;
|
|
290
|
+
arr.namedItem = (name) => arr[name] || null;
|
|
291
|
+
return arr;
|
|
292
|
+
},
|
|
293
|
+
configurable: false,
|
|
294
|
+
enumerable: true
|
|
295
|
+
});
|
|
296
|
+
} catch (e) {}
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// 6. Permission API Spoofing (2025) - Fixed to return consistent Promise identity
|
|
300
|
+
const spoofPermissions = () => {
|
|
301
|
+
if (!navigator.permissions) return;
|
|
302
|
+
|
|
303
|
+
const promiseCache = new Map();
|
|
304
|
+
const originalQuery = navigator.permissions.query;
|
|
305
|
+
|
|
306
|
+
navigator.permissions.query = function(descriptor) {
|
|
307
|
+
// Common permissions that should be granted for a normal user
|
|
308
|
+
const allowedPermissions = ['geolocation', 'notifications', 'camera', 'microphone'];
|
|
309
|
+
|
|
310
|
+
if (descriptor && allowedPermissions.includes(descriptor.name)) {
|
|
311
|
+
// Return the same Promise instance for identical queries (Datadome checks this)
|
|
312
|
+
const key = JSON.stringify(descriptor);
|
|
313
|
+
if (promiseCache.has(key)) {
|
|
314
|
+
return promiseCache.get(key);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const promise = Promise.resolve({
|
|
318
|
+
state: 'prompt',
|
|
319
|
+
onchange: null,
|
|
320
|
+
addEventListener: () => {},
|
|
321
|
+
removeEventListener: () => {},
|
|
322
|
+
dispatchEvent: () => true
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
promiseCache.set(key, promise);
|
|
326
|
+
return promise;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return originalQuery.apply(this, arguments);
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
// 7. Battery API Spoofing (2025)
|
|
334
|
+
const spoofBatteryAPI = () => {
|
|
335
|
+
if ('getBattery' in navigator) {
|
|
336
|
+
navigator.getBattery = async () => {
|
|
337
|
+
return {
|
|
338
|
+
charging: true,
|
|
339
|
+
chargingTime: 0,
|
|
340
|
+
dischargingTime: Infinity,
|
|
341
|
+
level: 0.92 + Math.random() * 0.08, // Random between 0.92-1.0
|
|
342
|
+
onchargingchange: null,
|
|
343
|
+
onchargingtimechange: null,
|
|
344
|
+
ondischargingtimechange: null,
|
|
345
|
+
onlevelchange: null,
|
|
346
|
+
addEventListener: () => {},
|
|
347
|
+
removeEventListener: () => {},
|
|
348
|
+
dispatchEvent: () => true
|
|
349
|
+
};
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
// 8. Connection API Spoofing (2025)
|
|
355
|
+
const spoofConnectionAPI = () => {
|
|
356
|
+
if ('connection' in navigator || 'mozConnection' in navigator || 'webkitConnection' in navigator) {
|
|
357
|
+
const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
|
|
358
|
+
if (connection) {
|
|
359
|
+
try {
|
|
360
|
+
Object.defineProperty(connection, 'rtt', { value: 50, writable: false });
|
|
361
|
+
Object.defineProperty(connection, 'downlink', { value: 10.0, writable: false });
|
|
362
|
+
Object.defineProperty(connection, 'effectiveType', { value: '4g', writable: false });
|
|
363
|
+
Object.defineProperty(connection, 'saveData', { value: false, writable: false });
|
|
364
|
+
} catch (e) {}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
// 9. Chrome Runtime API Spoofing (2025) - NEW
|
|
370
|
+
const spoofChromeRuntime = () => {
|
|
371
|
+
if (!window.chrome?.runtime) {
|
|
372
|
+
const runtime = {
|
|
373
|
+
PlatformOs: { MAC: 'mac', WIN: 'win', ANDROID: 'android', CROS: 'cros', LINUX: 'linux', OPENBSD: 'openbsd' },
|
|
374
|
+
PlatformArch: { ARM: 'arm', ARM64: 'arm64', MIPS: 'mips', MIPS64: 'mips64', X86_32: 'x86-32', X86_64: 'x86-64' },
|
|
375
|
+
PlatformNaclArch: { ARM: 'arm', MIPS: 'mips', MIPS64: 'mips64', X86_32: 'x86-32', X86_64: 'x86-64' },
|
|
376
|
+
RequestUpdateCheckStatus: { THROTTLED: 'throttled', NO_UPDATE: 'no_update', UPDATE_AVAILABLE: 'update_available' },
|
|
377
|
+
OnInstalledReason: { INSTALL: 'install', UPDATE: 'update', CHROME_UPDATE: 'chrome_update', SHARED_MODULE_UPDATE: 'shared_module_update' },
|
|
378
|
+
OnRestartRequiredReason: { APP_UPDATE: 'app_update', OS_UPDATE: 'os_update', PERIODIC: 'periodic' },
|
|
379
|
+
getManifest: () => ({}),
|
|
380
|
+
id: 'chrome-extension-id-' + Math.random().toString(36).substr(2, 9),
|
|
381
|
+
connect: () => ({
|
|
382
|
+
name: '',
|
|
383
|
+
disconnect: () => {},
|
|
384
|
+
onDisconnect: { addListener: () => {}, removeListener: () => {} },
|
|
385
|
+
onMessage: { addListener: () => {}, removeListener: () => {} },
|
|
386
|
+
postMessage: () => {}
|
|
387
|
+
}),
|
|
388
|
+
sendMessage: () => {},
|
|
389
|
+
getURL: (path) => 'chrome-extension://invalid/' + path,
|
|
390
|
+
onConnect: { addListener: () => {}, removeListener: () => {} },
|
|
391
|
+
onMessage: { addListener: () => {}, removeListener: () => {} },
|
|
392
|
+
onStartup: { addListener: () => {}, removeListener: () => {} },
|
|
393
|
+
onInstalled: { addListener: () => {}, removeListener: () => {} },
|
|
394
|
+
onSuspend: { addListener: () => {}, removeListener: () => {} },
|
|
395
|
+
onSuspendCanceled: { addListener: () => {}, removeListener: () => {} },
|
|
396
|
+
onUpdateAvailable: { addListener: () => {}, removeListener: () => {} },
|
|
397
|
+
onBrowserUpdateAvailable: { addListener: () => {}, removeListener: () => {} },
|
|
398
|
+
onRestartRequired: { addListener: () => {}, removeListener: () => {} },
|
|
399
|
+
openOptionsPage: () => {},
|
|
400
|
+
setUninstallURL: () => {},
|
|
401
|
+
reload: () => {},
|
|
402
|
+
requestUpdateCheck: () => Promise.resolve(['no_update', {}]),
|
|
403
|
+
restart: () => {},
|
|
404
|
+
restartAfterDelay: () => {},
|
|
405
|
+
getPlatformInfo: () => Promise.resolve({
|
|
406
|
+
os: 'win',
|
|
407
|
+
arch: 'x86-64',
|
|
408
|
+
nacl_arch: 'x86-64'
|
|
409
|
+
}),
|
|
410
|
+
getPackageDirectoryEntry: () => Promise.resolve({}),
|
|
411
|
+
lastError: null
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
if (!window.chrome) window.chrome = {};
|
|
415
|
+
Object.defineProperty(window.chrome, 'runtime', {
|
|
416
|
+
value: runtime,
|
|
417
|
+
configurable: false,
|
|
418
|
+
enumerable: true,
|
|
419
|
+
writable: false
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
// Initialize all protections
|
|
425
|
+
try {
|
|
426
|
+
hideErrorStack();
|
|
427
|
+
patchConsole();
|
|
428
|
+
removeAutomationFlags();
|
|
429
|
+
preventRuntimeEnableDetection();
|
|
430
|
+
spoofPlugins();
|
|
431
|
+
spoofPermissions();
|
|
432
|
+
spoofBatteryAPI();
|
|
433
|
+
spoofConnectionAPI();
|
|
434
|
+
spoofChromeRuntime(); // NEW
|
|
435
|
+
} catch (e) {
|
|
436
|
+
// Silently fail to avoid detection
|
|
437
|
+
}
|
|
438
|
+
})();`;
|
|
439
|
+
};
|
|
440
|
+
//# sourceMappingURL=stealth-script.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stealth-script.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/stealth-script.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAW,EAAE;IAC5C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAgbL,CAAC;AACP,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ua-ch.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/ua-ch.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,iCAAiC,yBAAyB,MAyFtE,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* navigator.userAgentData spoofing
|
|
3
|
+
* Generates brand list & bitness matching the chosen platform.
|
|
4
|
+
*/
|
|
5
|
+
export const createUAClientHintsSpoofingScript = (platform = 'Win32') => {
|
|
6
|
+
let platformData;
|
|
7
|
+
let platformVersion;
|
|
8
|
+
if (platform.startsWith('Win')) {
|
|
9
|
+
platformData = 'Windows';
|
|
10
|
+
platformVersion = '15.0.0';
|
|
11
|
+
}
|
|
12
|
+
else if (platform.startsWith('Mac')) {
|
|
13
|
+
platformData = 'macOS';
|
|
14
|
+
platformVersion = '14.0.0';
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
platformData = 'Linux';
|
|
18
|
+
platformVersion = '6.2.0';
|
|
19
|
+
}
|
|
20
|
+
return `
|
|
21
|
+
(() => {
|
|
22
|
+
'use strict';
|
|
23
|
+
|
|
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
|
+
];
|
|
30
|
+
|
|
31
|
+
const mobile = false;
|
|
32
|
+
const platformData = "${platformData}";
|
|
33
|
+
|
|
34
|
+
const uaData = {
|
|
35
|
+
brands: brands,
|
|
36
|
+
mobile: mobile,
|
|
37
|
+
platform: platformData,
|
|
38
|
+
|
|
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
|
+
},
|
|
64
|
+
|
|
65
|
+
toJSON() {
|
|
66
|
+
return {
|
|
67
|
+
brands: brands,
|
|
68
|
+
mobile: mobile,
|
|
69
|
+
platform: platformData
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Override navigator.userAgentData
|
|
75
|
+
Object.defineProperty(navigator, "userAgentData", {
|
|
76
|
+
get: () => uaData,
|
|
77
|
+
configurable: false,
|
|
78
|
+
enumerable: true
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Also ensure the property exists and is not writable
|
|
82
|
+
try {
|
|
83
|
+
Object.defineProperty(navigator, "userAgentData", {
|
|
84
|
+
value: uaData,
|
|
85
|
+
writable: false,
|
|
86
|
+
configurable: false,
|
|
87
|
+
enumerable: true
|
|
88
|
+
});
|
|
89
|
+
} catch (e) {
|
|
90
|
+
// Property might already be defined
|
|
91
|
+
}
|
|
92
|
+
})();
|
|
93
|
+
`;
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=ua-ch.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebGL Fingerprinting Protection
|
|
3
|
+
* Platform-aware GPU spoofing for WebGL contexts
|
|
4
|
+
*/
|
|
5
|
+
export interface WebGLConfig {
|
|
6
|
+
vendor?: string;
|
|
7
|
+
renderer?: string;
|
|
8
|
+
vendorUnmasked?: string;
|
|
9
|
+
rendererUnmasked?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const createWebGLSpoofingScript: (fingerprintWebGL?: WebGLConfig) => string;
|
|
12
|
+
//# sourceMappingURL=webgl-spoofing.d.ts.map
|
|
@@ -0,0 +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,MAkK1E,CAAC"}
|