@fanboynz/network-scanner 2.0.25 → 2.0.26
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/README.md +1 -1
- package/lib/fingerprint.js +5 -5
- package/nwss.js +81 -50
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -223,7 +223,7 @@ When a page redirects to a new domain, first-party/third-party detection is base
|
|
|
223
223
|
| `whois_timeout_multiplier` | Number | `1.5` | Timeout increase multiplier per retry |
|
|
224
224
|
| `whois_use_fallback` | Boolean | `true` | Add TLD-specific fallback servers |
|
|
225
225
|
| `whois_retry_on_timeout` | Boolean | `true` | Retry on timeout errors |
|
|
226
|
-
| `whois_retry_on_error` | Boolean | `
|
|
226
|
+
| `whois_retry_on_error` | Boolean | `true` | Retry on connection/other errors |
|
|
227
227
|
| `dig` | Array | - | Check dig output for ALL specified terms (AND logic) |
|
|
228
228
|
| `dig-or` | Array | - | Check dig output for ANY specified term (OR logic) |
|
|
229
229
|
| `dig_subdomain` | Boolean | `false` | Use subdomain for dig lookup instead of root domain |
|
package/lib/fingerprint.js
CHANGED
|
@@ -59,7 +59,7 @@ const PRECOMPILED_MOCKS = Object.freeze({
|
|
|
59
59
|
postMessage: () => {},
|
|
60
60
|
disconnect: () => {}
|
|
61
61
|
}),
|
|
62
|
-
getManifest: () => Object.freeze({ name: "Chrome", version: "
|
|
62
|
+
getManifest: () => Object.freeze({ name: "Chrome", version: "141.0.0.0" }),
|
|
63
63
|
getURL: (path) => `chrome-extension://invalid/${path}`,
|
|
64
64
|
id: undefined
|
|
65
65
|
}),
|
|
@@ -91,9 +91,9 @@ const BUILT_IN_PROPERTIES = new Set([
|
|
|
91
91
|
// User agent collections with latest versions
|
|
92
92
|
const USER_AGENT_COLLECTIONS = {
|
|
93
93
|
chrome: [
|
|
94
|
-
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
|
|
95
|
-
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
|
|
96
|
-
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
|
|
94
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
|
|
95
|
+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
|
|
96
|
+
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"
|
|
97
97
|
],
|
|
98
98
|
firefox: [
|
|
99
99
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:143.0) Gecko/20100101 Firefox/143.0",
|
|
@@ -535,7 +535,7 @@ async function applyUserAgentSpoofing(page, siteConfig, forceDebug, currentUrl)
|
|
|
535
535
|
onMessage: { addListener: () => {}, removeListener: () => {} },
|
|
536
536
|
sendMessage: () => {},
|
|
537
537
|
connect: () => ({ onMessage: { addListener: () => {}, removeListener: () => {} }, postMessage: () => {}, disconnect: () => {} }),
|
|
538
|
-
getManifest: () => ({ name: "Chrome", version: "
|
|
538
|
+
getManifest: () => ({ name: "Chrome", version: "141.0.0.0" }),
|
|
539
539
|
getURL: (path) => `chrome-extension://invalid/${path}`,
|
|
540
540
|
id: undefined
|
|
541
541
|
},
|
package/nwss.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// === Network scanner script (nwss.js) v2.0.
|
|
1
|
+
// === Network scanner script (nwss.js) v2.0.26 ===
|
|
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
|
|
@@ -56,7 +56,7 @@ function fastTimeout(ms) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
// --- Configuration Constants ---
|
|
59
|
-
const TIMEOUTS = {
|
|
59
|
+
const TIMEOUTS = Object.freeze({
|
|
60
60
|
DEFAULT_PAGE: 35000, // Standard page load timeout (35s)
|
|
61
61
|
DEFAULT_NAVIGATION: 25000, // Navigation operation timeout
|
|
62
62
|
DEFAULT_NAVIGATION_REDUCED: 20000, // Reduced timeout for faster failures
|
|
@@ -71,21 +71,32 @@ const TIMEOUTS = {
|
|
|
71
71
|
CURL_HANDLER_DELAY: 3000, // Wait for async curl operations
|
|
72
72
|
PROTOCOL_TIMEOUT: 180000, // Chrome DevTools Protocol timeout
|
|
73
73
|
REDIRECT_JS_TIMEOUT: 5000 // JavaScript redirect detection timeout
|
|
74
|
-
};
|
|
74
|
+
});
|
|
75
75
|
|
|
76
|
-
const CACHE_LIMITS = {
|
|
76
|
+
const CACHE_LIMITS = Object.freeze({
|
|
77
77
|
DISK_CACHE_SIZE: 52428800, // 50MB
|
|
78
78
|
MEDIA_CACHE_SIZE: 52428800, // 50MB
|
|
79
79
|
DEFAULT_CACHE_PATH: '.cache',
|
|
80
80
|
DEFAULT_MAX_SIZE: 5000
|
|
81
|
-
};
|
|
81
|
+
});
|
|
82
82
|
|
|
83
|
-
const CONCURRENCY_LIMITS = {
|
|
83
|
+
const CONCURRENCY_LIMITS = Object.freeze({
|
|
84
84
|
MIN: 1,
|
|
85
85
|
MAX: 50,
|
|
86
86
|
DEFAULT: 6,
|
|
87
87
|
HIGH_CONCURRENCY_THRESHOLD: 12 // Auto-enable aggressive caching above this
|
|
88
|
-
};
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// V8 Optimization: Use Map for user agent lookups instead of object
|
|
91
|
+
const USER_AGENTS = Object.freeze(new Map([
|
|
92
|
+
['chrome', "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"],
|
|
93
|
+
['chrome_mac', "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"],
|
|
94
|
+
['chrome_linux', "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"],
|
|
95
|
+
['firefox', "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:142.0) Gecko/20100101 Firefox/143.0"],
|
|
96
|
+
['firefox_mac', "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:142.0) Gecko/20100101 Firefox/143.0"],
|
|
97
|
+
['firefox_linux', "Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/143.0"],
|
|
98
|
+
['safari', "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Safari/605.1.15"]
|
|
99
|
+
]));
|
|
89
100
|
|
|
90
101
|
const REALTIME_CLEANUP_THRESHOLD = 8; // Default pages to keep for realtime cleanup
|
|
91
102
|
|
|
@@ -132,7 +143,7 @@ const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/r
|
|
|
132
143
|
const { monitorBrowserHealth, isBrowserHealthy, isQuicklyResponsive, performGroupWindowCleanup, performRealtimeWindowCleanup, trackPageForRealtime, updatePageUsage, cleanupPageBeforeReload } = require('./lib/browserhealth');
|
|
133
144
|
|
|
134
145
|
// --- Script Configuration & Constants ---
|
|
135
|
-
const VERSION = '2.0.
|
|
146
|
+
const VERSION = '2.0.26'; // Script version
|
|
136
147
|
|
|
137
148
|
// get startTime
|
|
138
149
|
const startTime = Date.now();
|
|
@@ -1211,6 +1222,9 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1211
1222
|
'/usr/bin/chromium',
|
|
1212
1223
|
'/snap/bin/chromium'
|
|
1213
1224
|
];
|
|
1225
|
+
// V8 Optimization: Freeze the Chrome paths array since it's constant
|
|
1226
|
+
Object.freeze(systemChromePaths);
|
|
1227
|
+
|
|
1214
1228
|
|
|
1215
1229
|
let executablePath = null;
|
|
1216
1230
|
for (const chromePath of systemChromePaths) {
|
|
@@ -1387,12 +1401,28 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1387
1401
|
* @returns {Promise<object>} A promise that resolves to an object containing scan results.
|
|
1388
1402
|
*/
|
|
1389
1403
|
async function processUrl(currentUrl, siteConfig, browserInstance) {
|
|
1390
|
-
|
|
1391
|
-
const
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1404
|
+
// V8 Optimization: Single destructuring to avoid multiple property lookups
|
|
1405
|
+
const {
|
|
1406
|
+
firstParty,
|
|
1407
|
+
thirdParty,
|
|
1408
|
+
subDomains,
|
|
1409
|
+
localhost,
|
|
1410
|
+
cloudflare_phish,
|
|
1411
|
+
cloudflare_bypass,
|
|
1412
|
+
flowproxy_detection,
|
|
1413
|
+
privoxy,
|
|
1414
|
+
pihole,
|
|
1415
|
+
even_blocked,
|
|
1416
|
+
comments,
|
|
1417
|
+
bypass_cache
|
|
1418
|
+
} = siteConfig;
|
|
1419
|
+
|
|
1420
|
+
const allowFirstParty = firstParty === true || firstParty === 1;
|
|
1421
|
+
const allowThirdParty = thirdParty === undefined || thirdParty === true || thirdParty === 1;
|
|
1422
|
+
const perSiteSubDomains = subDomains === 1 ? true : subDomainsMode;
|
|
1423
|
+
const siteLocalhostIP = localhost || null;
|
|
1424
|
+
const cloudflarePhishBypass = cloudflare_phish === true;
|
|
1425
|
+
const cloudflareBypass = cloudflare_bypass === true;
|
|
1396
1426
|
// Add redirect and same-page loop protection
|
|
1397
1427
|
const MAX_REDIRECT_DEPTH = siteConfig.max_redirects || 10;
|
|
1398
1428
|
const redirectHistory = new Set();
|
|
@@ -1401,14 +1431,14 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1401
1431
|
const MAX_SAME_PAGE_LOADS = 3;
|
|
1402
1432
|
let currentPageUrl = currentUrl;
|
|
1403
1433
|
|
|
1404
|
-
const sitePrivoxy =
|
|
1405
|
-
const sitePihole =
|
|
1406
|
-
const flowproxyDetection =
|
|
1434
|
+
const sitePrivoxy = privoxy === true;
|
|
1435
|
+
const sitePihole = pihole === true;
|
|
1436
|
+
const flowproxyDetection = flowproxy_detection === true;
|
|
1407
1437
|
|
|
1408
|
-
const evenBlocked =
|
|
1438
|
+
const evenBlocked = even_blocked === true;
|
|
1409
1439
|
// Log site-level comments if debug mode is enabled
|
|
1410
|
-
if (forceDebug &&
|
|
1411
|
-
const siteComments = Array.isArray(
|
|
1440
|
+
if (forceDebug && comments) {
|
|
1441
|
+
const siteComments = Array.isArray(comments) ? comments : [comments];
|
|
1412
1442
|
console.log(formatLogMessage('debug', `Site comments for ${currentUrl}: ${siteComments.length} item(s)`));
|
|
1413
1443
|
siteComments.forEach((comment, idx) =>
|
|
1414
1444
|
console.log(formatLogMessage('debug', ` Site comment ${idx + 1}: ${comment}`))
|
|
@@ -1416,11 +1446,11 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1416
1446
|
}
|
|
1417
1447
|
|
|
1418
1448
|
// Log bypass_cache setting if enabled
|
|
1419
|
-
if (forceDebug &&
|
|
1449
|
+
if (forceDebug && bypass_cache === true) {
|
|
1420
1450
|
console.log(formatLogMessage('debug', `Cache bypass enabled for all URLs in site: ${currentUrl}`));
|
|
1421
1451
|
}
|
|
1422
1452
|
|
|
1423
|
-
if (
|
|
1453
|
+
if (firstParty === 0 && thirdParty === 0) {
|
|
1424
1454
|
console.warn(`⚠ Skipping ${currentUrl} because both firstParty and thirdParty are disabled.`);
|
|
1425
1455
|
return { url: currentUrl, rules: [], success: false, skipped: true };
|
|
1426
1456
|
}
|
|
@@ -1475,14 +1505,14 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1475
1505
|
let finalUrlAfterRedirect = null;
|
|
1476
1506
|
|
|
1477
1507
|
// Enhanced error types for Puppeteer 23.x compatibility
|
|
1478
|
-
const CRITICAL_BROWSER_ERRORS = [
|
|
1508
|
+
const CRITICAL_BROWSER_ERRORS = Object.freeze([
|
|
1479
1509
|
'Protocol error',
|
|
1480
1510
|
'Target closed',
|
|
1481
1511
|
'Browser has been closed',
|
|
1482
1512
|
'Browser protocol broken',
|
|
1483
1513
|
'Browser process exited',
|
|
1484
1514
|
'Browser disconnected'
|
|
1485
|
-
];
|
|
1515
|
+
]);
|
|
1486
1516
|
|
|
1487
1517
|
try {
|
|
1488
1518
|
|
|
@@ -1907,29 +1937,30 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1907
1937
|
|
|
1908
1938
|
// Client Hints protection for Chrome user agents
|
|
1909
1939
|
if (siteConfig.userAgent && siteConfig.userAgent.toLowerCase().includes('chrome')) {
|
|
1940
|
+
const userAgentKey = siteConfig.userAgent.toLowerCase();
|
|
1910
1941
|
let platform = 'Windows';
|
|
1911
1942
|
let platformVersion = '15.0.0';
|
|
1912
1943
|
let arch = 'x86';
|
|
1913
1944
|
|
|
1914
|
-
if (
|
|
1945
|
+
if (userAgentKey === 'chrome_mac') {
|
|
1915
1946
|
platform = 'macOS';
|
|
1916
|
-
platformVersion = '13.5.0';
|
|
1947
|
+
platformVersion = '13.5.0';
|
|
1917
1948
|
arch = 'arm';
|
|
1918
|
-
} else if (
|
|
1949
|
+
} else if (userAgentKey === 'chrome_linux') {
|
|
1919
1950
|
platform = 'Linux';
|
|
1920
1951
|
platformVersion = '6.5.0';
|
|
1921
1952
|
arch = 'x86';
|
|
1922
1953
|
}
|
|
1923
|
-
|
|
1954
|
+
|
|
1924
1955
|
await page.setExtraHTTPHeaders({
|
|
1925
|
-
'Sec-CH-UA': '"Chromium";v="
|
|
1956
|
+
'Sec-CH-UA': '"Chromium";v="141", "Not=A?Brand";v="24", "Google Chrome";v="141"',
|
|
1926
1957
|
'Sec-CH-UA-Platform': `"${platform}"`,
|
|
1927
1958
|
'Sec-CH-UA-Platform-Version': `"${platformVersion}"`,
|
|
1928
1959
|
'Sec-CH-UA-Mobile': '?0',
|
|
1929
1960
|
'Sec-CH-UA-Arch': `"${arch}"`,
|
|
1930
1961
|
'Sec-CH-UA-Bitness': '"64"',
|
|
1931
|
-
'Sec-CH-UA-Full-Version': '"
|
|
1932
|
-
'Sec-CH-UA-Full-Version-List': '"Chromium";v="
|
|
1962
|
+
'Sec-CH-UA-Full-Version': '"141.0.7390.55"',
|
|
1963
|
+
'Sec-CH-UA-Full-Version-List': '"Chromium";v="141.0.7390.55", "Not=A?Brand";v="24.0.0.0", "Google Chrome";v="141.0.7390.55"'
|
|
1933
1964
|
});
|
|
1934
1965
|
}
|
|
1935
1966
|
} catch (fingerprintErr) {
|
|
@@ -1959,16 +1990,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1959
1990
|
// Get user agent for curl if needed
|
|
1960
1991
|
let curlUserAgent = '';
|
|
1961
1992
|
if (useCurl && siteConfig.userAgent) {
|
|
1962
|
-
|
|
1963
|
-
chrome: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
|
|
1964
|
-
chrome_mac: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
|
|
1965
|
-
chrome_linux: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
|
|
1966
|
-
firefox: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:142.0) Gecko/20100101 Firefox/143.0",
|
|
1967
|
-
firefox_mac: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:142.0) Gecko/20100101 Firefox/143.0",
|
|
1968
|
-
firefox_linux: "Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/143.0",
|
|
1969
|
-
safari: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Safari/605.1.15"
|
|
1970
|
-
};
|
|
1971
|
-
curlUserAgent = userAgents[siteConfig.userAgent.toLowerCase()] || '';
|
|
1993
|
+
curlUserAgent = USER_AGENTS.get(siteConfig.userAgent.toLowerCase()) || '';
|
|
1972
1994
|
}
|
|
1973
1995
|
|
|
1974
1996
|
if (useCurl && forceDebug) {
|
|
@@ -3487,20 +3509,29 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
3487
3509
|
// Temporarily store the pLimit function
|
|
3488
3510
|
const originalLimit = limit;
|
|
3489
3511
|
|
|
3490
|
-
//
|
|
3491
|
-
|
|
3512
|
+
// V8 Optimization: Calculate total URLs first to pre-allocate array
|
|
3513
|
+
let totalUrls = 0;
|
|
3492
3514
|
for (const site of sites) {
|
|
3493
3515
|
const urlsToProcess = Array.isArray(site.url) ? site.url : [site.url];
|
|
3494
|
-
urlsToProcess.
|
|
3495
|
-
|
|
3516
|
+
totalUrls += urlsToProcess.length;
|
|
3517
|
+
}
|
|
3518
|
+
|
|
3519
|
+
// Pre-allocate array with exact size to prevent multiple reallocations
|
|
3520
|
+
const allTasks = new Array(totalUrls);
|
|
3521
|
+
let taskIndex = 0;
|
|
3522
|
+
|
|
3523
|
+
// Populate the pre-allocated array
|
|
3524
|
+
for (const site of sites) {
|
|
3525
|
+
const urlsToProcess = Array.isArray(site.url) ? site.url : [site.url];
|
|
3526
|
+
for (const url of urlsToProcess) {
|
|
3527
|
+
allTasks[taskIndex++] = {
|
|
3496
3528
|
url,
|
|
3497
3529
|
config: { ...site, _originalUrl: url }, // Preserve original URL for CDP domain checking
|
|
3498
|
-
taskId:
|
|
3499
|
-
}
|
|
3500
|
-
}
|
|
3530
|
+
taskId: taskIndex - 1 // For tracking
|
|
3531
|
+
};
|
|
3532
|
+
}
|
|
3501
3533
|
}
|
|
3502
|
-
|
|
3503
|
-
const totalUrls = allTasks.length;
|
|
3534
|
+
|
|
3504
3535
|
|
|
3505
3536
|
let results = [];
|
|
3506
3537
|
let processedUrlCount = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fanboynz/network-scanner",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.26",
|
|
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": {
|