@fanboynz/network-scanner 2.0.22 → 2.0.24
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/lib/fingerprint.js +200 -70
- package/lib/nettools.js +5 -5
- package/nwss.1 +1 -1
- package/nwss.js +3 -3
- package/package.json +1 -1
package/lib/fingerprint.js
CHANGED
|
@@ -7,6 +7,81 @@
|
|
|
7
7
|
const DEFAULT_PLATFORM = 'Win32';
|
|
8
8
|
const DEFAULT_TIMEZONE = 'America/New_York';
|
|
9
9
|
|
|
10
|
+
// Cached property descriptors for V8 optimization
|
|
11
|
+
const CACHED_DESCRIPTORS = {
|
|
12
|
+
readOnlyValue: (value) => ({ value, writable: false, enumerable: true, configurable: true }),
|
|
13
|
+
getter: (fn) => ({ get: fn, enumerable: true, configurable: true }),
|
|
14
|
+
hiddenValue: (value) => ({ value, writable: false, enumerable: false, configurable: true })
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Type-specific property spoofing functions for monomorphic optimization
|
|
18
|
+
function spoofNavigatorProperties(navigator, properties, options = {}) {
|
|
19
|
+
if (!navigator || typeof navigator !== 'object') return false;
|
|
20
|
+
|
|
21
|
+
for (const [prop, descriptor] of Object.entries(properties)) {
|
|
22
|
+
if (!safeDefineProperty(navigator, prop, descriptor, options)) {
|
|
23
|
+
if (options.debug) console.log(`[fingerprint] Failed to spoof navigator.${prop}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function spoofScreenProperties(screen, properties, options = {}) {
|
|
30
|
+
if (!screen || typeof screen !== 'object') return false;
|
|
31
|
+
|
|
32
|
+
for (const [prop, descriptor] of Object.entries(properties)) {
|
|
33
|
+
if (!safeDefineProperty(screen, prop, descriptor, options)) {
|
|
34
|
+
if (options.debug) console.log(`[fingerprint] Failed to spoof screen.${prop}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function spoofWindowProperties(window, properties, options = {}) {
|
|
41
|
+
if (!window || typeof window !== 'object') return false;
|
|
42
|
+
|
|
43
|
+
for (const [prop, descriptor] of Object.entries(properties)) {
|
|
44
|
+
if (!safeDefineProperty(window, prop, descriptor, options)) {
|
|
45
|
+
if (options.debug) console.log(`[fingerprint] Failed to spoof window.${prop}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Pre-compiled mock objects for V8 optimization
|
|
52
|
+
const PRECOMPILED_MOCKS = Object.freeze({
|
|
53
|
+
chromeRuntime: Object.freeze({
|
|
54
|
+
onConnect: Object.freeze({ addListener: () => {}, removeListener: () => {} }),
|
|
55
|
+
onMessage: Object.freeze({ addListener: () => {}, removeListener: () => {} }),
|
|
56
|
+
sendMessage: () => {},
|
|
57
|
+
connect: () => Object.freeze({
|
|
58
|
+
onMessage: Object.freeze({ addListener: () => {}, removeListener: () => {} }),
|
|
59
|
+
postMessage: () => {},
|
|
60
|
+
disconnect: () => {}
|
|
61
|
+
}),
|
|
62
|
+
getManifest: () => Object.freeze({ name: "Chrome", version: "140.0.0.0" }),
|
|
63
|
+
getURL: (path) => `chrome-extension://invalid/${path}`,
|
|
64
|
+
id: undefined
|
|
65
|
+
}),
|
|
66
|
+
|
|
67
|
+
fingerprintResult: Object.freeze({
|
|
68
|
+
visitorId: 'mock_visitor_' + Math.random().toString(36).substr(2, 9),
|
|
69
|
+
confidence: Object.freeze({ score: 0.99 }),
|
|
70
|
+
components: Object.freeze({
|
|
71
|
+
screen: Object.freeze({ value: Object.freeze({ width: 1920, height: 1080 }) }),
|
|
72
|
+
timezone: Object.freeze({ value: 'America/New_York' }),
|
|
73
|
+
language: Object.freeze({ value: 'en-US' })
|
|
74
|
+
})
|
|
75
|
+
}),
|
|
76
|
+
|
|
77
|
+
loadTimes: Object.freeze({
|
|
78
|
+
commitLoadTime: performance.now() - Math.random() * 1000,
|
|
79
|
+
connectionInfo: 'http/1.1',
|
|
80
|
+
finishDocumentLoadTime: performance.now() - Math.random() * 500,
|
|
81
|
+
navigationType: 'Navigation'
|
|
82
|
+
})
|
|
83
|
+
});
|
|
84
|
+
|
|
10
85
|
// Built-in properties that should not be modified
|
|
11
86
|
const BUILT_IN_PROPERTIES = new Set([
|
|
12
87
|
'href', 'origin', 'protocol', 'host', 'hostname', 'port', 'pathname', 'search', 'hash',
|
|
@@ -55,10 +130,7 @@ function safeDefineProperty(target, property, descriptor, options = {}) {
|
|
|
55
130
|
return false;
|
|
56
131
|
}
|
|
57
132
|
|
|
58
|
-
Object.defineProperty(target, property,
|
|
59
|
-
...descriptor,
|
|
60
|
-
configurable: true
|
|
61
|
-
});
|
|
133
|
+
Object.defineProperty(target, property, descriptor);
|
|
62
134
|
return true;
|
|
63
135
|
} catch (err) {
|
|
64
136
|
if (options.debug) console.log(`[fingerprint] Failed to define ${property}: ${err.message}`);
|
|
@@ -99,11 +171,61 @@ function getRealisticScreenResolution() {
|
|
|
99
171
|
/**
|
|
100
172
|
* Generates randomized but realistic browser fingerprint values
|
|
101
173
|
*/
|
|
102
|
-
function
|
|
103
|
-
|
|
174
|
+
function generateRealisticFingerprint(userAgent) {
|
|
175
|
+
// Determine OS from user agent
|
|
176
|
+
let osType = 'windows';
|
|
177
|
+
if (userAgent.includes('Macintosh') || userAgent.includes('Mac OS X')) {
|
|
178
|
+
osType = 'mac';
|
|
179
|
+
} else if (userAgent.includes('X11; Linux') || userAgent.includes('Ubuntu')) {
|
|
180
|
+
osType = 'linux';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Generate OS-appropriate hardware specs
|
|
184
|
+
const profiles = {
|
|
185
|
+
windows: {
|
|
186
|
+
deviceMemory: [8, 16], // Common Windows configurations
|
|
187
|
+
hardwareConcurrency: [4, 6, 8], // Typical consumer CPUs
|
|
188
|
+
platform: 'Win32',
|
|
189
|
+
timezone: 'America/New_York',
|
|
190
|
+
language: 'en-US',
|
|
191
|
+
resolutions: [
|
|
192
|
+
{ width: 1920, height: 1080 },
|
|
193
|
+
{ width: 2560, height: 1440 },
|
|
194
|
+
{ width: 1366, height: 768 }
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
mac: {
|
|
198
|
+
deviceMemory: [8, 16], // MacBook/iMac typical configs
|
|
199
|
+
hardwareConcurrency: [8, 10], // Apple Silicon M1/M2 cores
|
|
200
|
+
platform: 'MacIntel',
|
|
201
|
+
timezone: 'America/Los_Angeles',
|
|
202
|
+
language: 'en-US',
|
|
203
|
+
resolutions: [
|
|
204
|
+
{ width: 2560, height: 1600 }, // MacBook Pro
|
|
205
|
+
{ width: 3840, height: 2160 }, // iMac 4K
|
|
206
|
+
{ width: 1440, height: 900 } // MacBook Air
|
|
207
|
+
]
|
|
208
|
+
},
|
|
209
|
+
linux: {
|
|
210
|
+
deviceMemory: [8, 16],
|
|
211
|
+
hardwareConcurrency: [4, 8, 12], // Wide variety on Linux
|
|
212
|
+
platform: 'Linux x86_64',
|
|
213
|
+
timezone: 'America/New_York',
|
|
214
|
+
language: 'en-US',
|
|
215
|
+
resolutions: [
|
|
216
|
+
{ width: 1920, height: 1080 },
|
|
217
|
+
{ width: 2560, height: 1440 },
|
|
218
|
+
{ width: 1600, height: 900 }
|
|
219
|
+
]
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
const profile = profiles[osType];
|
|
224
|
+
const resolution = profile.resolutions[Math.floor(Math.random() * profile.resolutions.length)];
|
|
225
|
+
|
|
104
226
|
return {
|
|
105
|
-
deviceMemory: [
|
|
106
|
-
hardwareConcurrency: [
|
|
227
|
+
deviceMemory: profile.deviceMemory[Math.floor(Math.random() * profile.deviceMemory.length)],
|
|
228
|
+
hardwareConcurrency: profile.hardwareConcurrency[Math.floor(Math.random() * profile.hardwareConcurrency.length)],
|
|
107
229
|
screen: {
|
|
108
230
|
width: resolution.width,
|
|
109
231
|
height: resolution.height,
|
|
@@ -112,11 +234,11 @@ function getRandomFingerprint() {
|
|
|
112
234
|
colorDepth: 24,
|
|
113
235
|
pixelDepth: 24
|
|
114
236
|
},
|
|
115
|
-
platform:
|
|
116
|
-
timezone:
|
|
117
|
-
language:
|
|
237
|
+
platform: profile.platform,
|
|
238
|
+
timezone: profile.timezone,
|
|
239
|
+
language: profile.language,
|
|
118
240
|
cookieEnabled: true,
|
|
119
|
-
doNotTrack:
|
|
241
|
+
doNotTrack: null // Most users don't enable DNT
|
|
120
242
|
};
|
|
121
243
|
}
|
|
122
244
|
|
|
@@ -124,19 +246,7 @@ function getRandomFingerprint() {
|
|
|
124
246
|
* Creates mock Chrome runtime objects
|
|
125
247
|
*/
|
|
126
248
|
function createMockChromeRuntime() {
|
|
127
|
-
return
|
|
128
|
-
onConnect: { addListener: () => {}, removeListener: () => {} },
|
|
129
|
-
onMessage: { addListener: () => {}, removeListener: () => {} },
|
|
130
|
-
sendMessage: () => {},
|
|
131
|
-
connect: () => ({
|
|
132
|
-
onMessage: { addListener: () => {}, removeListener: () => {} },
|
|
133
|
-
postMessage: () => {},
|
|
134
|
-
disconnect: () => {}
|
|
135
|
-
}),
|
|
136
|
-
getManifest: () => ({ name: "Chrome", version: "131.0.0.0" }),
|
|
137
|
-
getURL: (path) => `chrome-extension://invalid/${path}`,
|
|
138
|
-
id: undefined
|
|
139
|
-
};
|
|
249
|
+
return PRECOMPILED_MOCKS.chromeRuntime;
|
|
140
250
|
}
|
|
141
251
|
|
|
142
252
|
/**
|
|
@@ -144,21 +254,8 @@ function createMockChromeRuntime() {
|
|
|
144
254
|
*/
|
|
145
255
|
function generateRealisticLoadTimes() {
|
|
146
256
|
const now = performance.now();
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
connectionInfo: 'http/1.1',
|
|
150
|
-
finishDocumentLoadTime: now - Math.random() * 500,
|
|
151
|
-
finishLoadTime: now - Math.random() * 100,
|
|
152
|
-
firstPaintAfterLoadTime: now - Math.random() * 50,
|
|
153
|
-
firstPaintTime: now - Math.random() * 200,
|
|
154
|
-
navigationType: 'Navigation',
|
|
155
|
-
npnNegotiatedProtocol: 'unknown',
|
|
156
|
-
requestTime: now - Math.random() * 2000,
|
|
157
|
-
startLoadTime: now - Math.random() * 1500,
|
|
158
|
-
wasAlternateProtocolAvailable: false,
|
|
159
|
-
wasFetchedViaSpdy: false,
|
|
160
|
-
wasNpnNegotiated: false
|
|
161
|
-
};
|
|
257
|
+
// Return a copy with updated timing values
|
|
258
|
+
return { ...PRECOMPILED_MOCKS.loadTimes, commitLoadTime: now - Math.random() * 1000 };
|
|
162
259
|
}
|
|
163
260
|
|
|
164
261
|
/**
|
|
@@ -194,22 +291,14 @@ async function validatePageForInjection(page, currentUrl, forceDebug) {
|
|
|
194
291
|
* Creates mock fingerprinting objects
|
|
195
292
|
*/
|
|
196
293
|
function createFingerprintMocks() {
|
|
197
|
-
const mockResult =
|
|
198
|
-
visitorId: 'mock_visitor_' + Math.random().toString(36).substr(2, 9),
|
|
199
|
-
confidence: { score: 0.99 },
|
|
200
|
-
components: {
|
|
201
|
-
screen: { value: { width: 1920, height: 1080 } },
|
|
202
|
-
timezone: { value: DEFAULT_TIMEZONE },
|
|
203
|
-
language: { value: 'en-US' }
|
|
204
|
-
}
|
|
205
|
-
};
|
|
294
|
+
const mockResult = PRECOMPILED_MOCKS.fingerprintResult;
|
|
206
295
|
|
|
207
296
|
return {
|
|
208
297
|
fp: {
|
|
209
298
|
getResult: (callback) => callback ? setTimeout(() => callback(mockResult), 0) : mockResult,
|
|
210
299
|
get: (callback) => Promise.resolve(mockResult),
|
|
211
300
|
load: () => Promise.resolve(window.fp),
|
|
212
|
-
components:
|
|
301
|
+
components: mockResult.components,
|
|
213
302
|
x64hash128: () => 'mock_hash',
|
|
214
303
|
tz: DEFAULT_TIMEZONE,
|
|
215
304
|
timezone: DEFAULT_TIMEZONE
|
|
@@ -351,7 +440,7 @@ async function applyUserAgentSpoofing(page, siteConfig, forceDebug, currentUrl)
|
|
|
351
440
|
// Create safe property definition helper
|
|
352
441
|
function safeDefinePropertyLocal(target, property, descriptor) {
|
|
353
442
|
const builtInProps = new Set(['href', 'origin', 'protocol', 'host', 'hostname', 'port', 'pathname', 'search', 'hash', 'constructor', 'prototype', '__proto__', 'toString', 'valueOf', 'assign', 'reload', 'replace']);
|
|
354
|
-
|
|
443
|
+
|
|
355
444
|
if (builtInProps.has(property)) {
|
|
356
445
|
if (debugEnabled) console.log(`[fingerprint] Skipping built-in property: ${property}`);
|
|
357
446
|
return false;
|
|
@@ -374,6 +463,24 @@ async function applyUserAgentSpoofing(page, siteConfig, forceDebug, currentUrl)
|
|
|
374
463
|
return false;
|
|
375
464
|
}
|
|
376
465
|
}
|
|
466
|
+
|
|
467
|
+
// Add cached descriptors helper for page context
|
|
468
|
+
const CACHED_DESCRIPTORS = {
|
|
469
|
+
getter: (fn) => ({ get: fn, enumerable: true, configurable: true })
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
// Add monomorphic spoofing functions for page context
|
|
473
|
+
function spoofNavigatorProperties(navigator, properties) {
|
|
474
|
+
for (const [prop, descriptor] of Object.entries(properties)) {
|
|
475
|
+
safeDefinePropertyLocal(navigator, prop, descriptor);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function spoofScreenProperties(screen, properties) {
|
|
480
|
+
for (const [prop, descriptor] of Object.entries(properties)) {
|
|
481
|
+
safeDefinePropertyLocal(screen, prop, descriptor);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
377
484
|
|
|
378
485
|
// Safe execution wrapper
|
|
379
486
|
function safeExecute(fn, description) {
|
|
@@ -428,7 +535,7 @@ async function applyUserAgentSpoofing(page, siteConfig, forceDebug, currentUrl)
|
|
|
428
535
|
onMessage: { addListener: () => {}, removeListener: () => {} },
|
|
429
536
|
sendMessage: () => {},
|
|
430
537
|
connect: () => ({ onMessage: { addListener: () => {}, removeListener: () => {} }, postMessage: () => {}, disconnect: () => {} }),
|
|
431
|
-
getManifest: () => ({ name: "Chrome", version: "
|
|
538
|
+
getManifest: () => ({ name: "Chrome", version: "140.0.0.0" }),
|
|
432
539
|
getURL: (path) => `chrome-extension://invalid/${path}`,
|
|
433
540
|
id: undefined
|
|
434
541
|
},
|
|
@@ -507,8 +614,11 @@ async function applyUserAgentSpoofing(page, siteConfig, forceDebug, currentUrl)
|
|
|
507
614
|
//
|
|
508
615
|
safeExecute(() => {
|
|
509
616
|
const languages = ['en-US', 'en'];
|
|
510
|
-
|
|
511
|
-
|
|
617
|
+
const languageProps = {
|
|
618
|
+
languages: { get: () => languages },
|
|
619
|
+
language: { get: () => languages[0] }
|
|
620
|
+
};
|
|
621
|
+
spoofNavigatorProperties(navigator, languageProps);
|
|
512
622
|
}, 'language spoofing');
|
|
513
623
|
|
|
514
624
|
// Spoof vendor information
|
|
@@ -523,8 +633,11 @@ async function applyUserAgentSpoofing(page, siteConfig, forceDebug, currentUrl)
|
|
|
523
633
|
vendor = 'Apple Computer, Inc.';
|
|
524
634
|
}
|
|
525
635
|
|
|
526
|
-
|
|
527
|
-
|
|
636
|
+
const vendorProps = {
|
|
637
|
+
vendor: { get: () => vendor },
|
|
638
|
+
product: { get: () => product }
|
|
639
|
+
};
|
|
640
|
+
spoofNavigatorProperties(navigator, vendorProps);
|
|
528
641
|
}, 'vendor/product spoofing');
|
|
529
642
|
|
|
530
643
|
// Enhanced OS fingerprinting protection based on actual user agent content
|
|
@@ -574,7 +687,10 @@ async function applyUserAgentSpoofing(page, siteConfig, forceDebug, currentUrl)
|
|
|
574
687
|
// Hardware concurrency spoofing (universal coverage)
|
|
575
688
|
//
|
|
576
689
|
safeExecute(() => {
|
|
577
|
-
|
|
690
|
+
const hardwareProps = {
|
|
691
|
+
hardwareConcurrency: { get: () => [4, 6, 8, 12][Math.floor(Math.random() * 4)] }
|
|
692
|
+
};
|
|
693
|
+
spoofNavigatorProperties(navigator, hardwareProps);
|
|
578
694
|
}, 'hardware concurrency spoofing');
|
|
579
695
|
|
|
580
696
|
|
|
@@ -593,10 +709,13 @@ async function applyUserAgentSpoofing(page, siteConfig, forceDebug, currentUrl)
|
|
|
593
709
|
];
|
|
594
710
|
const resolution = commonResolutions[Math.floor(Math.random() * commonResolutions.length)];
|
|
595
711
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
712
|
+
const screenProps = {
|
|
713
|
+
width: { get: () => resolution.width },
|
|
714
|
+
height: { get: () => resolution.height },
|
|
715
|
+
availWidth: { get: () => resolution.width },
|
|
716
|
+
availHeight: { get: () => resolution.height - 40 }
|
|
717
|
+
};
|
|
718
|
+
spoofScreenProperties(window.screen, screenProps);
|
|
600
719
|
}, 'screen resolution protection');
|
|
601
720
|
|
|
602
721
|
// Spoof MIME types
|
|
@@ -1213,7 +1332,9 @@ async function applyFingerprintProtection(page, siteConfig, forceDebug, currentU
|
|
|
1213
1332
|
// Validate page state before injection
|
|
1214
1333
|
if (!(await validatePageForInjection(page, currentUrl, forceDebug))) return;
|
|
1215
1334
|
|
|
1216
|
-
|
|
1335
|
+
const currentUserAgent = await page.evaluate(() => navigator.userAgent);
|
|
1336
|
+
|
|
1337
|
+
const spoof = fingerprintSetting === 'random' ? generateRealisticFingerprint(currentUserAgent) : {
|
|
1217
1338
|
deviceMemory: 8,
|
|
1218
1339
|
hardwareConcurrency: 4,
|
|
1219
1340
|
screen: { width: 1920, height: 1080, availWidth: 1920, availHeight: 1040, colorDepth: 24, pixelDepth: 24 },
|
|
@@ -1244,11 +1365,15 @@ async function applyFingerprintProtection(page, siteConfig, forceDebug, currentU
|
|
|
1244
1365
|
}
|
|
1245
1366
|
|
|
1246
1367
|
// Platform spoofing
|
|
1247
|
-
|
|
1368
|
+
const navigatorProps = {
|
|
1369
|
+
platform: { get: () => spoof.platform },
|
|
1370
|
+
deviceMemory: { get: () => spoof.deviceMemory },
|
|
1371
|
+
hardwareConcurrency: { get: () => spoof.hardwareConcurrency }
|
|
1372
|
+
};
|
|
1373
|
+
spoofNavigatorProperties(navigator, navigatorProps);
|
|
1248
1374
|
|
|
1249
|
-
//
|
|
1250
|
-
|
|
1251
|
-
safeDefinePropertyLocal(navigator, 'hardwareConcurrency', { get: () => spoof.hardwareConcurrency });
|
|
1375
|
+
// Platform, memory, and hardware spoofing combined for better V8 optimization
|
|
1376
|
+
// (moved into navigatorProps above);
|
|
1252
1377
|
|
|
1253
1378
|
// Connection type spoofing
|
|
1254
1379
|
safeDefinePropertyLocal(navigator, 'connection', {
|
|
@@ -1262,16 +1387,21 @@ async function applyFingerprintProtection(page, siteConfig, forceDebug, currentU
|
|
|
1262
1387
|
});
|
|
1263
1388
|
|
|
1264
1389
|
// Screen properties spoofing
|
|
1390
|
+
const screenSpoofProps = {};
|
|
1265
1391
|
['width', 'height', 'availWidth', 'availHeight', 'colorDepth', 'pixelDepth'].forEach(prop => {
|
|
1266
1392
|
if (spoof.screen[prop] !== undefined) {
|
|
1267
|
-
|
|
1393
|
+
screenSpoofProps[prop] = { get: () => spoof.screen[prop] };
|
|
1268
1394
|
}
|
|
1269
1395
|
});
|
|
1396
|
+
spoofScreenProperties(window.screen, screenSpoofProps);
|
|
1270
1397
|
|
|
1271
1398
|
// Language spoofing
|
|
1272
1399
|
const languages = Array.isArray(spoof.language) ? spoof.language : [spoof.language, spoof.language.split('-')[0]];
|
|
1273
|
-
|
|
1274
|
-
|
|
1400
|
+
const languageSpoofProps = {
|
|
1401
|
+
languages: { get: () => languages },
|
|
1402
|
+
language: { get: () => languages[0] }
|
|
1403
|
+
};
|
|
1404
|
+
spoofNavigatorProperties(navigator, languageSpoofProps);
|
|
1275
1405
|
|
|
1276
1406
|
// Timezone spoofing
|
|
1277
1407
|
if (spoof.timezone && window.Intl?.DateTimeFormat) {
|
|
@@ -1480,7 +1610,7 @@ function safeExecuteSpoofing(spoofFunction, description, forceDebug = false) {
|
|
|
1480
1610
|
|
|
1481
1611
|
|
|
1482
1612
|
module.exports = {
|
|
1483
|
-
|
|
1613
|
+
generateRealisticFingerprint,
|
|
1484
1614
|
getRealisticScreenResolution,
|
|
1485
1615
|
applyUserAgentSpoofing,
|
|
1486
1616
|
applyBraveSpoofing,
|
package/lib/nettools.js
CHANGED
|
@@ -357,13 +357,13 @@ async function whoisLookup(domain, timeout = 10000, whoisServer = null, debugMod
|
|
|
357
357
|
* @param {number} whoisDelay - Delay in milliseconds before whois requests (default: 2000)
|
|
358
358
|
* @returns {Promise<Object>} Object with success status and output/error
|
|
359
359
|
*/
|
|
360
|
-
async function whoisLookupWithRetry(domain, timeout = 10000, whoisServer = null, debugMode = false, retryOptions = {}, whoisDelay =
|
|
360
|
+
async function whoisLookupWithRetry(domain, timeout = 10000, whoisServer = null, debugMode = false, retryOptions = {}, whoisDelay = 4000, logFunc = null) {
|
|
361
361
|
const {
|
|
362
|
-
maxRetries =
|
|
362
|
+
maxRetries = 3,
|
|
363
363
|
timeoutMultiplier = 1.5,
|
|
364
364
|
useFallbackServers = true,
|
|
365
365
|
retryOnTimeout = true,
|
|
366
|
-
retryOnError =
|
|
366
|
+
retryOnError = true
|
|
367
367
|
} = retryOptions;
|
|
368
368
|
|
|
369
369
|
let serversToTry = [];
|
|
@@ -709,7 +709,7 @@ function createNetToolsHandler(config) {
|
|
|
709
709
|
const {
|
|
710
710
|
whoisTerms,
|
|
711
711
|
whoisOrTerms,
|
|
712
|
-
whoisDelay =
|
|
712
|
+
whoisDelay = 4000,
|
|
713
713
|
whoisServer,
|
|
714
714
|
whoisServerMode = 'random',
|
|
715
715
|
debugLogFile = null,
|
|
@@ -941,7 +941,7 @@ function createNetToolsHandler(config) {
|
|
|
941
941
|
|
|
942
942
|
// Configure retry options based on site config or use defaults
|
|
943
943
|
const retryOptions = {
|
|
944
|
-
maxRetries: siteConfig.whois_max_retries ||
|
|
944
|
+
maxRetries: siteConfig.whois_max_retries || 3,
|
|
945
945
|
timeoutMultiplier: siteConfig.whois_timeout_multiplier || 1.5,
|
|
946
946
|
useFallbackServers: siteConfig.whois_use_fallback !== false, // Default true
|
|
947
947
|
retryOnTimeout: siteConfig.whois_retry_on_timeout !== false, // Default true
|
package/nwss.1
CHANGED
package/nwss.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// === Network scanner script (nwss.js) v2.0.
|
|
1
|
+
// === Network scanner script (nwss.js) v2.0.24 ===
|
|
2
2
|
|
|
3
3
|
// puppeteer for browser automation, fs for file system operations, psl for domain parsing.
|
|
4
4
|
// const pLimit = require('p-limit'); // Will be dynamically imported
|
|
@@ -132,7 +132,7 @@ const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/r
|
|
|
132
132
|
const { monitorBrowserHealth, isBrowserHealthy, isQuicklyResponsive, performGroupWindowCleanup, performRealtimeWindowCleanup, trackPageForRealtime, updatePageUsage, cleanupPageBeforeReload } = require('./lib/browserhealth');
|
|
133
133
|
|
|
134
134
|
// --- Script Configuration & Constants ---
|
|
135
|
-
const VERSION = '2.0.
|
|
135
|
+
const VERSION = '2.0.24'; // Script version
|
|
136
136
|
|
|
137
137
|
// get startTime
|
|
138
138
|
const startTime = Date.now();
|
|
@@ -575,7 +575,7 @@ Advanced Options:
|
|
|
575
575
|
whois_timeout_multiplier: 1.5 Timeout increase multiplier per retry (default: 1.5)
|
|
576
576
|
whois_use_fallback: true Add TLD-specific fallback servers (default: true)
|
|
577
577
|
whois_retry_on_timeout: true Retry on timeout errors (default: true)
|
|
578
|
-
whois_retry_on_error:
|
|
578
|
+
whois_retry_on_error: true Retry on connection/other errors (default: true)
|
|
579
579
|
whois_delay: <milliseconds> Delay between whois requests for this site (default: global whois_delay)
|
|
580
580
|
dig: ["term1", "term2"] Check dig output for ALL specified terms (AND logic)
|
|
581
581
|
dig-or: ["term1", "term2"] Check dig output for ANY specified term (OR logic)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fanboynz/network-scanner",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.24",
|
|
4
4
|
"description": "A Puppeteer-based network scanner for analyzing web traffic, generating adblock filter rules, and identifying third-party requests. Features include fingerprint spoofing, Cloudflare bypass, content analysis with curl/grep, and multiple output formats.",
|
|
5
5
|
"main": "nwss.js",
|
|
6
6
|
"scripts": {
|