jumpy-lion 0.0.41 → 0.0.42
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.map +1 -1
- package/dist/browser-controller.js +102 -16
- package/dist/browser-controller.js.map +1 -1
- package/dist/browser-plugin.d.ts +20 -1
- package/dist/browser-plugin.d.ts.map +1 -1
- package/dist/browser-plugin.js +21 -1
- package/dist/browser-plugin.js.map +1 -1
- package/dist/browser-process/browser.d.ts +22 -1
- package/dist/browser-process/browser.d.ts.map +1 -1
- package/dist/browser-process/browser.js +77 -5
- package/dist/browser-process/browser.js.map +1 -1
- package/dist/browser-profiles/chrome/default.d.ts +116 -0
- package/dist/browser-profiles/chrome/default.d.ts.map +1 -1
- package/dist/browser-profiles/chrome/default.js +118 -1
- package/dist/browser-profiles/chrome/default.js.map +1 -1
- package/dist/browser-profiles/chrome/populate-profile.d.ts +76 -0
- package/dist/browser-profiles/chrome/populate-profile.d.ts.map +1 -0
- package/dist/browser-profiles/chrome/populate-profile.js +300 -0
- package/dist/browser-profiles/chrome/populate-profile.js.map +1 -0
- package/dist/browser-profiles/index.d.ts +1 -0
- package/dist/browser-profiles/index.d.ts.map +1 -1
- package/dist/browser-profiles/index.js +2 -0
- package/dist/browser-profiles/index.js.map +1 -1
- package/dist/crawler.d.ts +32 -1
- package/dist/crawler.d.ts.map +1 -1
- package/dist/crawler.js +7 -0
- package/dist/crawler.js.map +1 -1
- package/dist/fingerprinting/custom-fingerprint-injector.d.ts +87 -0
- package/dist/fingerprinting/custom-fingerprint-injector.d.ts.map +1 -0
- package/dist/fingerprinting/custom-fingerprint-injector.js +342 -0
- package/dist/fingerprinting/custom-fingerprint-injector.js.map +1 -0
- package/dist/fingerprinting/fingerprint-injector.d.ts +40 -2
- package/dist/fingerprinting/fingerprint-injector.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-injector.js +449 -44
- package/dist/fingerprinting/fingerprint-injector.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.d.ts +14 -0
- package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.js +497 -0
- package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.d.ts +14 -0
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js +536 -0
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts +16 -1
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/index.js +19 -1
- package/dist/fingerprinting/fingerprint-overrides/index.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.d.ts +45 -0
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.js +291 -0
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js +54 -22
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.js +4 -5
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts +13 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js +413 -70
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts +10 -3
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js +132 -73
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.d.ts +55 -0
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.js +380 -0
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts +8 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js +417 -71
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/storage-consistency.d.ts +13 -0
- package/dist/fingerprinting/fingerprint-overrides/storage-consistency.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/storage-consistency.js +368 -0
- package/dist/fingerprinting/fingerprint-overrides/storage-consistency.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/timing-consistency.d.ts +13 -0
- package/dist/fingerprinting/fingerprint-overrides/timing-consistency.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/timing-consistency.js +438 -0
- package/dist/fingerprinting/fingerprint-overrides/timing-consistency.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/utils.d.ts +12 -0
- package/dist/fingerprinting/fingerprint-overrides/utils.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/utils.js +315 -0
- package/dist/fingerprinting/fingerprint-overrides/utils.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js +13 -1
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js.map +1 -1
- package/dist/page.d.ts +12 -0
- package/dist/page.d.ts.map +1 -1
- package/dist/page.js +35 -3
- package/dist/page.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/dist/fingerprinting/canvas-fingerprint.d.ts +0 -4
- package/dist/fingerprinting/canvas-fingerprint.d.ts.map +0 -1
- package/dist/fingerprinting/canvas-fingerprint.js +0 -60
- package/dist/fingerprinting/canvas-fingerprint.js.map +0 -1
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timing Consistency Module
|
|
3
|
+
* Dedicated timing fingerprint protection for 2024-2025
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* - Consistent Date.now() and performance.now() relationship
|
|
7
|
+
* - PerformanceEntry timing value protection
|
|
8
|
+
* - performance.measureUserAgentSpecificMemory() handling
|
|
9
|
+
* - event.timeStamp consistency in dispatched events
|
|
10
|
+
* - requestAnimationFrame timing patterns
|
|
11
|
+
*/
|
|
12
|
+
export const createTimingConsistencyScript = () => {
|
|
13
|
+
return `
|
|
14
|
+
(() => {
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
// Timing Consistency for 2024-2025
|
|
18
|
+
const setupTimingConsistency = () => {
|
|
19
|
+
// Base timestamps for consistency
|
|
20
|
+
const pageLoadTime = Date.now();
|
|
21
|
+
const performanceOrigin = performance.timeOrigin || pageLoadTime;
|
|
22
|
+
|
|
23
|
+
// Store original methods
|
|
24
|
+
const originalDateNow = Date.now;
|
|
25
|
+
const originalPerformanceNow = performance.now.bind(performance);
|
|
26
|
+
|
|
27
|
+
// Generate session seed for consistent variations
|
|
28
|
+
const generateSeed = () => {
|
|
29
|
+
const ua = navigator.userAgent || '';
|
|
30
|
+
return ua.length * 17 + (screen.width || 0) * 31;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const sessionSeed = generateSeed();
|
|
34
|
+
|
|
35
|
+
// Seeded random for consistent values
|
|
36
|
+
const seededRandom = (seed) => {
|
|
37
|
+
const x = Math.sin(seed) * 10000;
|
|
38
|
+
return x - Math.floor(x);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// 1. Ensure Date.now() and performance.now() have consistent relationship
|
|
42
|
+
const ensureDatePerformanceConsistency = () => {
|
|
43
|
+
let lastDateNow = originalDateNow();
|
|
44
|
+
let lastPerformanceNow = originalPerformanceNow();
|
|
45
|
+
|
|
46
|
+
// Ensure timing values don't expose automation
|
|
47
|
+
Date.now = function() {
|
|
48
|
+
const now = originalDateNow();
|
|
49
|
+
|
|
50
|
+
// Ensure monotonic increase with minimum 1ms resolution
|
|
51
|
+
if (now <= lastDateNow) {
|
|
52
|
+
lastDateNow += 1;
|
|
53
|
+
return lastDateNow;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
lastDateNow = now;
|
|
57
|
+
return now;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
performance.now = function() {
|
|
61
|
+
const now = originalPerformanceNow();
|
|
62
|
+
|
|
63
|
+
// Add subtle platform-specific jitter (Windows has ~1ms resolution)
|
|
64
|
+
const platform = navigator.platform || 'Win32';
|
|
65
|
+
let jitter = 0;
|
|
66
|
+
|
|
67
|
+
if (platform === 'Win32') {
|
|
68
|
+
// Windows timer resolution is typically 15.6ms or 1ms with high-res enabled
|
|
69
|
+
jitter = (seededRandom(sessionSeed + now) - 0.5) * 0.1;
|
|
70
|
+
} else if (platform === 'MacIntel') {
|
|
71
|
+
// macOS has high precision timing
|
|
72
|
+
jitter = (seededRandom(sessionSeed + now) - 0.5) * 0.01;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const adjustedNow = now + jitter;
|
|
76
|
+
|
|
77
|
+
// Ensure monotonic increase
|
|
78
|
+
if (adjustedNow <= lastPerformanceNow) {
|
|
79
|
+
lastPerformanceNow += 0.001;
|
|
80
|
+
return lastPerformanceNow;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
lastPerformanceNow = adjustedNow;
|
|
84
|
+
return adjustedNow;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// 2. Protect PerformanceEntry timing values
|
|
89
|
+
const protectPerformanceEntries = () => {
|
|
90
|
+
const originalGetEntries = performance.getEntries.bind(performance);
|
|
91
|
+
const originalGetEntriesByName = performance.getEntriesByName.bind(performance);
|
|
92
|
+
const originalGetEntriesByType = performance.getEntriesByType.bind(performance);
|
|
93
|
+
|
|
94
|
+
// Add consistent variations to timing entries
|
|
95
|
+
const adjustEntry = (entry) => {
|
|
96
|
+
if (!entry) return entry;
|
|
97
|
+
|
|
98
|
+
const timingProps = [
|
|
99
|
+
'startTime', 'duration', 'fetchStart', 'domainLookupStart',
|
|
100
|
+
'domainLookupEnd', 'connectStart', 'secureConnectionStart',
|
|
101
|
+
'connectEnd', 'requestStart', 'responseStart', 'responseEnd',
|
|
102
|
+
'workerStart', 'redirectStart', 'redirectEnd', 'processingStart',
|
|
103
|
+
'processingEnd', 'loadEventStart', 'loadEventEnd',
|
|
104
|
+
'unloadEventStart', 'unloadEventEnd'
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
const adjusted = {};
|
|
108
|
+
|
|
109
|
+
for (const key of Object.keys(entry)) {
|
|
110
|
+
if (timingProps.includes(key) && typeof entry[key] === 'number' && entry[key] > 0) {
|
|
111
|
+
// Add consistent micro-variation
|
|
112
|
+
const variation = seededRandom(sessionSeed + entry[key]) * 0.001;
|
|
113
|
+
adjusted[key] = entry[key] + variation;
|
|
114
|
+
} else {
|
|
115
|
+
adjusted[key] = entry[key];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Preserve prototype
|
|
120
|
+
Object.setPrototypeOf(adjusted, Object.getPrototypeOf(entry));
|
|
121
|
+
|
|
122
|
+
return adjusted;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
performance.getEntries = function() {
|
|
126
|
+
return originalGetEntries().map(adjustEntry);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
performance.getEntriesByName = function(name, type) {
|
|
130
|
+
return originalGetEntriesByName(name, type).map(adjustEntry);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
performance.getEntriesByType = function(type) {
|
|
134
|
+
return originalGetEntriesByType(type).map(adjustEntry);
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// 3. Handle performance.measureUserAgentSpecificMemory()
|
|
139
|
+
const protectMemoryMeasurement = () => {
|
|
140
|
+
if (performance.measureUserAgentSpecificMemory) {
|
|
141
|
+
const originalMeasure = performance.measureUserAgentSpecificMemory.bind(performance);
|
|
142
|
+
|
|
143
|
+
performance.measureUserAgentSpecificMemory = function() {
|
|
144
|
+
return originalMeasure().then(result => {
|
|
145
|
+
// Normalize memory values to be less fingerprintable
|
|
146
|
+
const normalizedBytes = Math.round(result.bytes / (1024 * 1024)) * 1024 * 1024;
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
bytes: normalizedBytes + Math.floor(seededRandom(sessionSeed) * 1024 * 100),
|
|
150
|
+
breakdown: (result.breakdown || []).map(item => ({
|
|
151
|
+
...item,
|
|
152
|
+
bytes: Math.round(item.bytes / 1024) * 1024
|
|
153
|
+
}))
|
|
154
|
+
};
|
|
155
|
+
}).catch(() => {
|
|
156
|
+
// Return a reasonable default if measurement fails
|
|
157
|
+
return {
|
|
158
|
+
bytes: 30 * 1024 * 1024 + Math.floor(seededRandom(sessionSeed) * 5 * 1024 * 1024),
|
|
159
|
+
breakdown: []
|
|
160
|
+
};
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// 4. Event timeStamp consistency
|
|
167
|
+
const ensureEventTimestampConsistency = () => {
|
|
168
|
+
// Override Event constructor to ensure consistent timestamps
|
|
169
|
+
const OriginalEvent = Event;
|
|
170
|
+
|
|
171
|
+
window.Event = function(type, eventInitDict) {
|
|
172
|
+
const event = new OriginalEvent(type, eventInitDict);
|
|
173
|
+
|
|
174
|
+
// Ensure timeStamp is consistent with performance.now()
|
|
175
|
+
const currentTime = performance.now();
|
|
176
|
+
|
|
177
|
+
Object.defineProperty(event, 'timeStamp', {
|
|
178
|
+
get: () => currentTime,
|
|
179
|
+
configurable: false,
|
|
180
|
+
enumerable: true
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
return event;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// Note: Don't assign to prototype - it may be frozen in modern Chrome
|
|
187
|
+
|
|
188
|
+
// Also override CustomEvent
|
|
189
|
+
const OriginalCustomEvent = CustomEvent;
|
|
190
|
+
|
|
191
|
+
window.CustomEvent = function(type, eventInitDict) {
|
|
192
|
+
const event = new OriginalCustomEvent(type, eventInitDict);
|
|
193
|
+
|
|
194
|
+
const currentTime = performance.now();
|
|
195
|
+
|
|
196
|
+
Object.defineProperty(event, 'timeStamp', {
|
|
197
|
+
get: () => currentTime,
|
|
198
|
+
configurable: false,
|
|
199
|
+
enumerable: true
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
return event;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// Note: Don't assign to prototype - it may be frozen in modern Chrome
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// 5. requestAnimationFrame timing patterns
|
|
209
|
+
const normalizeRAFTiming = () => {
|
|
210
|
+
const originalRAF = window.requestAnimationFrame;
|
|
211
|
+
let lastRAFTime = 0;
|
|
212
|
+
const targetFPS = 60;
|
|
213
|
+
const targetFrameTime = 1000 / targetFPS; // ~16.67ms
|
|
214
|
+
|
|
215
|
+
window.requestAnimationFrame = function(callback) {
|
|
216
|
+
return originalRAF(function(timestamp) {
|
|
217
|
+
// Ensure consistent frame timing (~60fps)
|
|
218
|
+
let adjustedTimestamp = timestamp;
|
|
219
|
+
|
|
220
|
+
if (lastRAFTime > 0) {
|
|
221
|
+
const delta = timestamp - lastRAFTime;
|
|
222
|
+
|
|
223
|
+
// If frame time is suspiciously consistent (automation), add variation
|
|
224
|
+
if (Math.abs(delta - targetFrameTime) < 0.1) {
|
|
225
|
+
adjustedTimestamp = lastRAFTime + targetFrameTime +
|
|
226
|
+
(seededRandom(sessionSeed + timestamp) - 0.5) * 2;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
lastRAFTime = adjustedTimestamp;
|
|
231
|
+
|
|
232
|
+
return callback(adjustedTimestamp);
|
|
233
|
+
});
|
|
234
|
+
};
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
// 6. setTimeout/setInterval timing normalization
|
|
238
|
+
const normalizeTimerTiming = () => {
|
|
239
|
+
const originalSetTimeout = window.setTimeout;
|
|
240
|
+
const originalSetInterval = window.setInterval;
|
|
241
|
+
|
|
242
|
+
window.setTimeout = function(callback, delay, ...args) {
|
|
243
|
+
// Add slight variation to delays to appear more natural
|
|
244
|
+
const variation = Math.floor(seededRandom(sessionSeed + (delay || 0)) * 2);
|
|
245
|
+
const adjustedDelay = Math.max(0, (delay || 0) + variation);
|
|
246
|
+
|
|
247
|
+
return originalSetTimeout.call(this, callback, adjustedDelay, ...args);
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
window.setInterval = function(callback, delay, ...args) {
|
|
251
|
+
// Add slight variation
|
|
252
|
+
const variation = Math.floor(seededRandom(sessionSeed + (delay || 0)) * 2);
|
|
253
|
+
const adjustedDelay = Math.max(1, (delay || 0) + variation);
|
|
254
|
+
|
|
255
|
+
return originalSetInterval.call(this, callback, adjustedDelay, ...args);
|
|
256
|
+
};
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
// 7. Performance Observer timing protection
|
|
260
|
+
const protectPerformanceObserver = () => {
|
|
261
|
+
if (typeof PerformanceObserver !== 'undefined') {
|
|
262
|
+
const OriginalPerformanceObserver = PerformanceObserver;
|
|
263
|
+
|
|
264
|
+
window.PerformanceObserver = class extends OriginalPerformanceObserver {
|
|
265
|
+
constructor(callback) {
|
|
266
|
+
super(function(list, observer) {
|
|
267
|
+
const entries = list.getEntries();
|
|
268
|
+
|
|
269
|
+
// Create modified list with adjusted entries
|
|
270
|
+
const adjustedEntries = entries.map(entry => {
|
|
271
|
+
const clone = {};
|
|
272
|
+
|
|
273
|
+
for (const key of Object.keys(entry)) {
|
|
274
|
+
if (typeof entry[key] === 'number' && key.includes('Time') || key === 'duration' || key === 'startTime') {
|
|
275
|
+
clone[key] = entry[key] + seededRandom(sessionSeed + entry[key]) * 0.001;
|
|
276
|
+
} else {
|
|
277
|
+
clone[key] = entry[key];
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
Object.setPrototypeOf(clone, Object.getPrototypeOf(entry));
|
|
282
|
+
return clone;
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const modifiedList = {
|
|
286
|
+
getEntries: () => adjustedEntries,
|
|
287
|
+
getEntriesByType: (type) => adjustedEntries.filter(e => e.entryType === type),
|
|
288
|
+
getEntriesByName: (name, type) => adjustedEntries.filter(e =>
|
|
289
|
+
e.name === name && (!type || e.entryType === type)
|
|
290
|
+
)
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
return callback(modifiedList, observer);
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
// supportedEntryTypes is a getter-only property, check if configurable first
|
|
299
|
+
try {
|
|
300
|
+
const descriptor = Object.getOwnPropertyDescriptor(window.PerformanceObserver, 'supportedEntryTypes');
|
|
301
|
+
if (!descriptor || descriptor.configurable !== false) {
|
|
302
|
+
Object.defineProperty(window.PerformanceObserver, 'supportedEntryTypes', {
|
|
303
|
+
get: () => OriginalPerformanceObserver.supportedEntryTypes,
|
|
304
|
+
configurable: true,
|
|
305
|
+
enumerable: true
|
|
306
|
+
});
|
|
307
|
+
} else {
|
|
308
|
+
// Property is frozen, skip silently
|
|
309
|
+
console.log('[CDP-FP-DEBUG] PerformanceObserver.supportedEntryTypes is frozen, using original');
|
|
310
|
+
}
|
|
311
|
+
} catch (e) {
|
|
312
|
+
// Property might already be defined or frozen
|
|
313
|
+
console.log('[CDP-FP-DEBUG] Could not redefine supportedEntryTypes:', e.message);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
// 8. Idle callback timing
|
|
319
|
+
const normalizeIdleCallback = () => {
|
|
320
|
+
if (window.requestIdleCallback) {
|
|
321
|
+
const originalRIC = window.requestIdleCallback;
|
|
322
|
+
|
|
323
|
+
window.requestIdleCallback = function(callback, options) {
|
|
324
|
+
return originalRIC(function(deadline) {
|
|
325
|
+
// Wrap deadline to provide consistent behavior
|
|
326
|
+
const wrappedDeadline = {
|
|
327
|
+
didTimeout: deadline.didTimeout,
|
|
328
|
+
timeRemaining: function() {
|
|
329
|
+
const remaining = deadline.timeRemaining();
|
|
330
|
+
// Add slight variation
|
|
331
|
+
return Math.max(0, remaining + (seededRandom(sessionSeed + remaining) - 0.5) * 2);
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
return callback(wrappedDeadline);
|
|
336
|
+
}, options);
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
// 9. Navigation Timing API protection
|
|
342
|
+
const protectNavigationTiming = () => {
|
|
343
|
+
if (performance.timing) {
|
|
344
|
+
const originalTiming = performance.timing;
|
|
345
|
+
const timingProxy = {};
|
|
346
|
+
|
|
347
|
+
const timingProps = [
|
|
348
|
+
'navigationStart', 'unloadEventStart', 'unloadEventEnd',
|
|
349
|
+
'redirectStart', 'redirectEnd', 'fetchStart',
|
|
350
|
+
'domainLookupStart', 'domainLookupEnd', 'connectStart',
|
|
351
|
+
'connectEnd', 'secureConnectionStart', 'requestStart',
|
|
352
|
+
'responseStart', 'responseEnd', 'domLoading',
|
|
353
|
+
'domInteractive', 'domContentLoadedEventStart',
|
|
354
|
+
'domContentLoadedEventEnd', 'domComplete',
|
|
355
|
+
'loadEventStart', 'loadEventEnd'
|
|
356
|
+
];
|
|
357
|
+
|
|
358
|
+
timingProps.forEach(prop => {
|
|
359
|
+
const originalValue = originalTiming[prop];
|
|
360
|
+
if (typeof originalValue === 'number' && originalValue > 0) {
|
|
361
|
+
Object.defineProperty(timingProxy, prop, {
|
|
362
|
+
get: () => originalValue + seededRandom(sessionSeed + originalValue) * 0.5,
|
|
363
|
+
configurable: true,
|
|
364
|
+
enumerable: true
|
|
365
|
+
});
|
|
366
|
+
} else {
|
|
367
|
+
Object.defineProperty(timingProxy, prop, {
|
|
368
|
+
get: () => originalValue,
|
|
369
|
+
configurable: true,
|
|
370
|
+
enumerable: true
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
// Add toJSON method
|
|
376
|
+
timingProxy.toJSON = function() {
|
|
377
|
+
const json = {};
|
|
378
|
+
timingProps.forEach(prop => {
|
|
379
|
+
json[prop] = this[prop];
|
|
380
|
+
});
|
|
381
|
+
return json;
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
Object.setPrototypeOf(timingProxy, PerformanceTiming.prototype);
|
|
385
|
+
|
|
386
|
+
Object.defineProperty(performance, 'timing', {
|
|
387
|
+
get: () => timingProxy,
|
|
388
|
+
configurable: true
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
// 10. High Resolution Time protection
|
|
394
|
+
const protectHighResolutionTime = () => {
|
|
395
|
+
// Ensure performance.timeOrigin is consistent
|
|
396
|
+
if (performance.timeOrigin) {
|
|
397
|
+
const originalOrigin = performance.timeOrigin;
|
|
398
|
+
const adjustedOrigin = originalOrigin + seededRandom(sessionSeed) * 0.1;
|
|
399
|
+
|
|
400
|
+
Object.defineProperty(performance, 'timeOrigin', {
|
|
401
|
+
get: () => adjustedOrigin,
|
|
402
|
+
configurable: true
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
// Initialize all timing protections
|
|
408
|
+
try {
|
|
409
|
+
ensureDatePerformanceConsistency();
|
|
410
|
+
protectPerformanceEntries();
|
|
411
|
+
protectMemoryMeasurement();
|
|
412
|
+
ensureEventTimestampConsistency();
|
|
413
|
+
normalizeRAFTiming();
|
|
414
|
+
normalizeTimerTiming();
|
|
415
|
+
protectPerformanceObserver();
|
|
416
|
+
normalizeIdleCallback();
|
|
417
|
+
protectNavigationTiming();
|
|
418
|
+
protectHighResolutionTime();
|
|
419
|
+
} catch (e) {
|
|
420
|
+
console.error('[TIMING-CONSISTENCY] Failed to apply timing consistency:', e);
|
|
421
|
+
throw e; // Rethrow to make errors visible
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
const DEBUG_PREFIX = '[CDP-FP-DEBUG]';
|
|
426
|
+
const ERROR_PREFIX = '[CDP-FP-ERROR]';
|
|
427
|
+
|
|
428
|
+
try {
|
|
429
|
+
console.log(DEBUG_PREFIX, 'Starting timing consistency...');
|
|
430
|
+
setupTimingConsistency();
|
|
431
|
+
console.log(DEBUG_PREFIX, '✓ Timing consistency applied');
|
|
432
|
+
} catch (e) {
|
|
433
|
+
console.error(ERROR_PREFIX, '✗ Failed to apply timing consistency:', e);
|
|
434
|
+
throw e;
|
|
435
|
+
}
|
|
436
|
+
})();`;
|
|
437
|
+
};
|
|
438
|
+
//# sourceMappingURL=timing-consistency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timing-consistency.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/timing-consistency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAW,EAAE;IACtD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAuaL,CAAC;AACP,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stealth Utility Functions
|
|
3
|
+
*
|
|
4
|
+
* Similar to puppeteer-extra-plugin-stealth's utils.js
|
|
5
|
+
* Provides helper functions for overriding browser properties without detection.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Creates a stealth utilities script that can be injected into the browser.
|
|
9
|
+
* This script provides helper functions for property overrides that hide their tracks.
|
|
10
|
+
*/
|
|
11
|
+
export declare const createStealthUtilsScript: () => string;
|
|
12
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +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"}
|