@fanboynz/network-scanner 2.0.55 → 2.0.57
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/.github/workflows/npm-publish.yml +3 -4
- package/lib/browserhealth.js +207 -179
- package/lib/cloudflare.js +117 -65
- package/lib/ignore_similar.js +78 -209
- package/lib/post-processing.js +282 -356
- package/lib/smart-cache.js +347 -267
- package/nwss.js +53 -13
- package/package.json +3 -2
package/nwss.js
CHANGED
|
@@ -20,7 +20,8 @@ const {
|
|
|
20
20
|
handleCloudflareProtection,
|
|
21
21
|
getCacheStats,
|
|
22
22
|
clearDetectionCache,
|
|
23
|
-
parallelChallengeDetection
|
|
23
|
+
parallelChallengeDetection,
|
|
24
|
+
cleanup: cleanupCloudflareCache
|
|
24
25
|
} = require('./lib/cloudflare');
|
|
25
26
|
// FP Bypass
|
|
26
27
|
const { handleFlowProxyProtection, getFlowProxyTimeouts } = require('./lib/flowproxy');
|
|
@@ -84,8 +85,8 @@ const TIMEOUTS = Object.freeze({
|
|
|
84
85
|
});
|
|
85
86
|
|
|
86
87
|
const CACHE_LIMITS = Object.freeze({
|
|
87
|
-
DISK_CACHE_SIZE:
|
|
88
|
-
MEDIA_CACHE_SIZE:
|
|
88
|
+
DISK_CACHE_SIZE: 1, // Effectively disabled — forcereload clears cache between loads
|
|
89
|
+
MEDIA_CACHE_SIZE: 1, // Effectively disabled — no media caching needed for scanning
|
|
89
90
|
DEFAULT_CACHE_PATH: '.cache',
|
|
90
91
|
DEFAULT_MAX_SIZE: 5000
|
|
91
92
|
});
|
|
@@ -150,7 +151,7 @@ function detectPuppeteerVersion() {
|
|
|
150
151
|
// Enhanced redirect handling
|
|
151
152
|
const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/redirect');
|
|
152
153
|
// Ensure web browser is working correctly
|
|
153
|
-
const { monitorBrowserHealth, isBrowserHealthy, isQuicklyResponsive, performGroupWindowCleanup, performRealtimeWindowCleanup, trackPageForRealtime, updatePageUsage, cleanupPageBeforeReload } = require('./lib/browserhealth');
|
|
154
|
+
const { monitorBrowserHealth, isBrowserHealthy, isQuicklyResponsive, performGroupWindowCleanup, performRealtimeWindowCleanup, trackPageForRealtime, updatePageUsage, cleanupPageBeforeReload, purgeStaleTrackers } = require('./lib/browserhealth');
|
|
154
155
|
|
|
155
156
|
// --- Script Configuration & Constants ---
|
|
156
157
|
const VERSION = '2.0.33'; // Script version
|
|
@@ -1020,11 +1021,28 @@ function flushLogBuffers() {
|
|
|
1020
1021
|
for (const [filePath, entries] of _logBuffers) {
|
|
1021
1022
|
if (entries.length > 0) {
|
|
1022
1023
|
try {
|
|
1023
|
-
|
|
1024
|
+
const data = entries.join('');
|
|
1025
|
+
entries.length = 0; // Clear buffer immediately
|
|
1026
|
+
fs.writeFile(filePath, data, { flag: 'a' }, (err) => {
|
|
1027
|
+
if (err) {
|
|
1028
|
+
console.warn(formatLogMessage('warn', `Failed to flush log buffer to ${filePath}: ${err.message}`));
|
|
1029
|
+
}
|
|
1030
|
+
});
|
|
1024
1031
|
} catch (err) {
|
|
1025
1032
|
console.warn(formatLogMessage('warn', `Failed to flush log buffer to ${filePath}: ${err.message}`));
|
|
1026
1033
|
}
|
|
1027
|
-
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
// Synchronous flush for exit handlers — guarantees data is written before process exits
|
|
1039
|
+
function flushLogBuffersSync() {
|
|
1040
|
+
for (const [filePath, entries] of _logBuffers) {
|
|
1041
|
+
if (entries.length > 0) {
|
|
1042
|
+
try {
|
|
1043
|
+
fs.appendFileSync(filePath, entries.join(''));
|
|
1044
|
+
} catch (err) { /* best effort on exit */ }
|
|
1045
|
+
entries.length = 0;
|
|
1028
1046
|
}
|
|
1029
1047
|
}
|
|
1030
1048
|
}
|
|
@@ -1426,12 +1444,19 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1426
1444
|
'--use-mock-keychain',
|
|
1427
1445
|
'--disable-client-side-phishing-detection',
|
|
1428
1446
|
'--enable-features=NetworkService',
|
|
1429
|
-
// Disk space controls -
|
|
1430
|
-
`--disk-cache-size=${CACHE_LIMITS.DISK_CACHE_SIZE}`,
|
|
1431
|
-
`--media-cache-size=${CACHE_LIMITS.MEDIA_CACHE_SIZE}`,
|
|
1447
|
+
// Disk space controls - minimal cache for scanning workloads
|
|
1448
|
+
`--disk-cache-size=${CACHE_LIMITS.DISK_CACHE_SIZE}`,
|
|
1449
|
+
`--media-cache-size=${CACHE_LIMITS.MEDIA_CACHE_SIZE}`,
|
|
1432
1450
|
'--disable-application-cache',
|
|
1433
1451
|
'--disable-offline-load-stale-cache',
|
|
1434
1452
|
'--disable-background-downloads',
|
|
1453
|
+
// DISK I/O REDUCTION: Eliminate unnecessary Chrome disk writes
|
|
1454
|
+
'--disable-breakpad', // No crash dump files
|
|
1455
|
+
'--disable-component-update', // No component update downloads
|
|
1456
|
+
'--disable-logging', // No Chrome internal log files
|
|
1457
|
+
'--log-level=3', // Fatal errors only (suppresses verbose disk logging)
|
|
1458
|
+
'--no-service-autorun', // No background service disk activity
|
|
1459
|
+
'--disable-domain-reliability', // No reliability monitor disk writes
|
|
1435
1460
|
// PERFORMANCE: Enhanced Puppeteer 23.x optimizations
|
|
1436
1461
|
'--disable-features=AudioServiceOutOfProcess,VizDisplayCompositor',
|
|
1437
1462
|
'--disable-features=TranslateUI,BlinkGenPropertyTrees,Translate',
|
|
@@ -1466,6 +1491,12 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1466
1491
|
'--disable-background-timer-throttling',
|
|
1467
1492
|
'--disable-features=site-per-process', // Better for single-site scanning
|
|
1468
1493
|
'--no-zygote', // Better process isolation
|
|
1494
|
+
// PERFORMANCE: Process and memory reduction for high concurrency
|
|
1495
|
+
'--renderer-process-limit=10', // Cap renderer processes (default: unlimited)
|
|
1496
|
+
'--disable-accelerated-2d-canvas', // Software canvas only (we spoof it anyway)
|
|
1497
|
+
'--disable-hang-monitor', // Remove per-renderer hang check overhead
|
|
1498
|
+
'--disable-features=PaintHolding', // Don't hold frames in renderer memory
|
|
1499
|
+
'--js-flags=--max-old-space-size=512', // Cap V8 heap per renderer to 512MB
|
|
1469
1500
|
...extraArgs,
|
|
1470
1501
|
],
|
|
1471
1502
|
// Optimized timeouts for Puppeteer 23.x performance
|
|
@@ -1517,7 +1548,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1517
1548
|
// Set up cleanup on process termination
|
|
1518
1549
|
process.on('SIGINT', async () => {
|
|
1519
1550
|
if (forceDebug) console.log(formatLogMessage('debug', 'SIGINT received, performing cleanup...'));
|
|
1520
|
-
|
|
1551
|
+
flushLogBuffersSync();
|
|
1521
1552
|
if (_logFlushTimer) clearInterval(_logFlushTimer);
|
|
1522
1553
|
await performEmergencyCleanup();
|
|
1523
1554
|
process.exit(0);
|
|
@@ -1525,7 +1556,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1525
1556
|
|
|
1526
1557
|
process.on('SIGTERM', async () => {
|
|
1527
1558
|
if (forceDebug) console.log(formatLogMessage('debug', 'SIGTERM received, performing cleanup...'));
|
|
1528
|
-
|
|
1559
|
+
flushLogBuffersSync();
|
|
1529
1560
|
if (_logFlushTimer) clearInterval(_logFlushTimer);
|
|
1530
1561
|
await performEmergencyCleanup();
|
|
1531
1562
|
process.exit(0);
|
|
@@ -1556,6 +1587,8 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1556
1587
|
}
|
|
1557
1588
|
wgDisconnectAll(forceDebug);
|
|
1558
1589
|
ovpnDisconnectAll(forceDebug);
|
|
1590
|
+
cleanupCloudflareCache();
|
|
1591
|
+
purgeStaleTrackers();
|
|
1559
1592
|
}
|
|
1560
1593
|
|
|
1561
1594
|
let siteCounter = 0;
|
|
@@ -3219,7 +3252,9 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
3219
3252
|
siteCounter++;
|
|
3220
3253
|
|
|
3221
3254
|
// Enhanced Cloudflare handling with parallel detection
|
|
3222
|
-
|
|
3255
|
+
// Only run parallel detection if cloudflare handling is explicitly configured
|
|
3256
|
+
const hasCloudflareConfig = siteConfig.cloudflare_bypass || siteConfig.cloudflare_phish;
|
|
3257
|
+
if (hasCloudflareConfig && siteConfig.cloudflare_parallel_detection !== false) {
|
|
3223
3258
|
try {
|
|
3224
3259
|
const parallelResult = await parallelChallengeDetection(page, forceDebug);
|
|
3225
3260
|
if (parallelResult.hasAnyChallenge && forceDebug) {
|
|
@@ -4073,6 +4108,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
4073
4108
|
|
|
4074
4109
|
// Reset cleanup counter and add delay
|
|
4075
4110
|
urlsSinceLastCleanup = 0;
|
|
4111
|
+
purgeStaleTrackers();
|
|
4076
4112
|
await fastTimeout(TIMEOUTS.BROWSER_STABILIZE_DELAY);
|
|
4077
4113
|
}
|
|
4078
4114
|
|
|
@@ -4125,6 +4161,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
4125
4161
|
browser = await createBrowser(proxyArgs);
|
|
4126
4162
|
currentProxyKey = batchProxyKey;
|
|
4127
4163
|
urlsSinceLastCleanup = 0;
|
|
4164
|
+
purgeStaleTrackers();
|
|
4128
4165
|
await fastTimeout(TIMEOUTS.BROWSER_STABILIZE_DELAY);
|
|
4129
4166
|
}
|
|
4130
4167
|
|
|
@@ -4156,6 +4193,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
4156
4193
|
const timeoutProxyArgs = currentProxyKey ? getProxyArgs(currentBatch[0].config, forceDebug) : [];
|
|
4157
4194
|
browser = await createBrowser(timeoutProxyArgs);
|
|
4158
4195
|
urlsSinceLastCleanup = 0;
|
|
4196
|
+
purgeStaleTrackers();
|
|
4159
4197
|
} catch (restartErr) {
|
|
4160
4198
|
throw restartErr;
|
|
4161
4199
|
}
|
|
@@ -4274,6 +4312,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
4274
4312
|
}
|
|
4275
4313
|
browser = await createBrowser(currentProxyKey ? getProxyArgs(currentBatch[0].config, forceDebug) : []);
|
|
4276
4314
|
urlsSinceLastCleanup = 0; // Reset counter
|
|
4315
|
+
purgeStaleTrackers();
|
|
4277
4316
|
await fastTimeout(TIMEOUTS.EMERGENCY_RESTART_DELAY); // Give browser time to stabilize
|
|
4278
4317
|
} catch (emergencyRestartErr) {
|
|
4279
4318
|
if (forceDebug) console.log(formatLogMessage('debug', `Emergency restart failed: ${emergencyRestartErr.message}`));
|
|
@@ -4286,6 +4325,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
4286
4325
|
await handleBrowserExit(browser, { forceDebug, timeout: 5000, exitOnFailure: false, cleanTempFiles: true });
|
|
4287
4326
|
browser = await createBrowser(currentProxyKey ? getProxyArgs(currentBatch[0].config, forceDebug) : []);
|
|
4288
4327
|
urlsSinceLastCleanup = 0;
|
|
4328
|
+
purgeStaleTrackers();
|
|
4289
4329
|
forceRestartFlag = false; // Reset flag
|
|
4290
4330
|
await fastTimeout(TIMEOUTS.EMERGENCY_RESTART_DELAY);
|
|
4291
4331
|
if (forceDebug) console.log(formatLogMessage('debug', `Emergency hang detection restart completed`));
|
|
@@ -4429,7 +4469,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
4429
4469
|
}
|
|
4430
4470
|
|
|
4431
4471
|
// Flush any remaining buffered log entries before compression/exit
|
|
4432
|
-
|
|
4472
|
+
flushLogBuffersSync();
|
|
4433
4473
|
if (_logFlushTimer) {
|
|
4434
4474
|
clearInterval(_logFlushTimer);
|
|
4435
4475
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fanboynz/network-scanner",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.57",
|
|
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": {
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
},
|
|
18
18
|
"overrides": {
|
|
19
19
|
"tar-fs": "3.1.1",
|
|
20
|
-
"ws": "8.18.3"
|
|
20
|
+
"ws": "8.18.3",
|
|
21
|
+
"yauzl": ">=3.2.1"
|
|
21
22
|
},
|
|
22
23
|
"keywords": [
|
|
23
24
|
"puppeteer",
|