@fanboynz/network-scanner 2.0.59 → 2.0.60
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/CHANGELOG.md +30 -0
- package/lib/adblock.js +215 -179
- package/lib/compare.js +19 -32
- package/lib/domain-cache.js +9 -7
- package/lib/grep.js +9 -13
- package/lib/nettools.js +177 -42
- package/lib/output.js +17 -30
- package/nwss.js +75 -23
- package/package.json +1 -1
package/nwss.js
CHANGED
|
@@ -32,7 +32,7 @@ const { shouldIgnoreSimilarDomain, calculateSimilarity } = require('./lib/ignore
|
|
|
32
32
|
// Graceful exit
|
|
33
33
|
const { handleBrowserExit, cleanupChromeTempFiles } = require('./lib/browserexit');
|
|
34
34
|
// Whois & Dig
|
|
35
|
-
const { createNetToolsHandler, createEnhancedDryRunCallback, validateWhoisAvailability, validateDigAvailability } = require('./lib/nettools');
|
|
35
|
+
const { createNetToolsHandler, createEnhancedDryRunCallback, validateWhoisAvailability, validateDigAvailability, enableDiskCache, getDnsCacheStats } = require('./lib/nettools');
|
|
36
36
|
// File compare
|
|
37
37
|
const { loadComparisonRules, filterUniqueRules } = require('./lib/compare');
|
|
38
38
|
// CDP functionality
|
|
@@ -208,6 +208,12 @@ if (localhostIndex !== -1) {
|
|
|
208
208
|
localhostIP = args[localhostIndex].includes('=') ? args[localhostIndex].split('=')[1] : '127.0.0.1';
|
|
209
209
|
}
|
|
210
210
|
const keepBrowserOpen = args.includes('--keep-open');
|
|
211
|
+
const loadExtensionPaths = [];
|
|
212
|
+
args.forEach((arg, idx) => {
|
|
213
|
+
if (arg === '--load-extension' && args[idx + 1] && !args[idx + 1].startsWith('--')) {
|
|
214
|
+
loadExtensionPaths.push(path.resolve(args[idx + 1]));
|
|
215
|
+
}
|
|
216
|
+
});
|
|
211
217
|
const disableInteract = args.includes('--no-interact');
|
|
212
218
|
const globalGhostCursor = args.includes('--ghost-cursor');
|
|
213
219
|
const plainOutput = args.includes('--plain');
|
|
@@ -229,6 +235,8 @@ let cleanRules = args.includes('--clean-rules');
|
|
|
229
235
|
const clearCache = args.includes('--clear-cache');
|
|
230
236
|
const ignoreCache = args.includes('--ignore-cache');
|
|
231
237
|
const cacheRequests = args.includes('--cache-requests');
|
|
238
|
+
const dnsCacheMode = args.includes('--dns-cache');
|
|
239
|
+
if (dnsCacheMode) enableDiskCache();
|
|
232
240
|
|
|
233
241
|
let validateRulesFile = null;
|
|
234
242
|
const validateRulesIndex = args.findIndex(arg => arg === '--validate-rules');
|
|
@@ -499,22 +507,38 @@ if (validateRules || validateRulesFile) {
|
|
|
499
507
|
}
|
|
500
508
|
}
|
|
501
509
|
|
|
502
|
-
// Parse --block-ads argument for request-level ad blocking
|
|
510
|
+
// Parse --block-ads argument for request-level ad blocking (supports comma-separated lists)
|
|
503
511
|
const blockAdsIndex = args.findIndex(arg => arg.startsWith('--block-ads'));
|
|
504
512
|
if (blockAdsIndex !== -1) {
|
|
505
|
-
const
|
|
506
|
-
? args[blockAdsIndex].split('=')[1]
|
|
513
|
+
const rulesArg = args[blockAdsIndex].includes('=')
|
|
514
|
+
? args[blockAdsIndex].split('=')[1]
|
|
507
515
|
: args[blockAdsIndex + 1];
|
|
508
|
-
|
|
509
|
-
if (!
|
|
510
|
-
console.log(
|
|
516
|
+
|
|
517
|
+
if (!rulesArg) {
|
|
518
|
+
console.log('Error: No adblock rules file specified');
|
|
511
519
|
process.exit(1);
|
|
512
520
|
}
|
|
513
|
-
|
|
521
|
+
|
|
522
|
+
const rulesFiles = rulesArg.split(',').map(f => f.trim()).filter(f => f);
|
|
523
|
+
for (const file of rulesFiles) {
|
|
524
|
+
if (!fs.existsSync(file)) {
|
|
525
|
+
console.log(`Error: Adblock rules file not found: ${file}`);
|
|
526
|
+
process.exit(1);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Concatenate multiple lists into a single temp file for the parser
|
|
531
|
+
let rulesFile = rulesFiles[0];
|
|
532
|
+
if (rulesFiles.length > 1) {
|
|
533
|
+
rulesFile = path.join(os.tmpdir(), `nwss-adblock-combined-${Date.now()}.txt`);
|
|
534
|
+
const combined = rulesFiles.map(f => fs.readFileSync(f, 'utf-8')).join('\n');
|
|
535
|
+
fs.writeFileSync(rulesFile, combined);
|
|
536
|
+
}
|
|
537
|
+
|
|
514
538
|
adblockEnabled = true;
|
|
515
539
|
adblockMatcher = parseAdblockRules(rulesFile, { enableLogging: forceDebug });
|
|
516
540
|
const stats = adblockMatcher.getStats();
|
|
517
|
-
if (!silentMode) console.log(messageColors.success(`Adblock enabled: Loaded ${stats.total} blocking rules from ${
|
|
541
|
+
if (!silentMode) console.log(messageColors.success(`Adblock enabled: Loaded ${stats.total} blocking rules from ${rulesFiles.length} list${rulesFiles.length > 1 ? 's' : ''}`));
|
|
518
542
|
}
|
|
519
543
|
|
|
520
544
|
if (args.includes('--help') || args.includes('-h')) {
|
|
@@ -556,6 +580,7 @@ General Options:
|
|
|
556
580
|
--headful Launch browser with GUI (not headless)
|
|
557
581
|
--keep-open Keep browser open after scan completes (use with --headful)
|
|
558
582
|
--use-puppeteer-core Use puppeteer-core with system Chrome instead of bundled Chromium
|
|
583
|
+
--load-extension <path> Load unpacked Chrome extension from directory
|
|
559
584
|
--cdp Enable Chrome DevTools Protocol logging (now per-page if enabled)
|
|
560
585
|
--remove-dupes Remove duplicate domains from output (only with -o)
|
|
561
586
|
--eval-on-doc Globally enable evaluateOnNewDocument() for Fetch/XHR interception
|
|
@@ -567,6 +592,7 @@ General Options:
|
|
|
567
592
|
|
|
568
593
|
Validation Options:
|
|
569
594
|
--cache-requests Cache HTTP requests to avoid re-requesting same URLs within scan
|
|
595
|
+
--dns-cache Persist dig/whois results to disk between runs (3hr/4hr TTL)
|
|
570
596
|
--validate-config Validate config.json file and exit
|
|
571
597
|
--validate-rules [file] Validate rule file format (uses --output/--compare files if no file specified)
|
|
572
598
|
--clean-rules [file] Clean rule files by removing invalid lines and optionally duplicates (uses --output/--compare files if no file specified)
|
|
@@ -583,6 +609,7 @@ Global config.json options:
|
|
|
583
609
|
ignore_similar_ignored_domains: true/false Ignore domains similar to ignoreDomains list (default: true)
|
|
584
610
|
max_concurrent_sites: 8 Maximum concurrent site processing (1-50, default: 8)
|
|
585
611
|
resource_cleanup_interval: 80 Browser restart interval in URLs processed (1-1000, default: 80)
|
|
612
|
+
disable_ad_tagging: true/false Disable Chrome AdTagging to prevent ad frame throttling (default: true)
|
|
586
613
|
|
|
587
614
|
Per-site config.json options:
|
|
588
615
|
url: "site" or ["site1", "site2"] Single URL or list of URLs
|
|
@@ -748,7 +775,8 @@ const {
|
|
|
748
775
|
whois_server_mode = 'random',
|
|
749
776
|
ignore_similar = true,
|
|
750
777
|
ignore_similar_threshold = 80,
|
|
751
|
-
ignore_similar_ignored_domains = true,
|
|
778
|
+
ignore_similar_ignored_domains = true,
|
|
779
|
+
disable_ad_tagging = true,
|
|
752
780
|
max_concurrent_sites = 6,
|
|
753
781
|
resource_cleanup_interval = 80,
|
|
754
782
|
comments: globalComments,
|
|
@@ -1460,7 +1488,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1460
1488
|
'--disable-blink-features=AutomationControlled',
|
|
1461
1489
|
'--no-first-run',
|
|
1462
1490
|
'--disable-default-apps',
|
|
1463
|
-
'--disable-component-extensions-with-background-pages',
|
|
1491
|
+
...(keepBrowserOpen ? [] : ['--disable-component-extensions-with-background-pages']),
|
|
1464
1492
|
// HIGH IMPACT: Normal Chrome behavior simulation
|
|
1465
1493
|
'--password-store=basic',
|
|
1466
1494
|
'--use-mock-keychain',
|
|
@@ -1474,30 +1502,29 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1474
1502
|
'--disable-background-downloads',
|
|
1475
1503
|
// DISK I/O REDUCTION: Eliminate unnecessary Chrome disk writes
|
|
1476
1504
|
'--disable-breakpad', // No crash dump files
|
|
1477
|
-
'--disable-component-update', // No component update downloads
|
|
1505
|
+
...(keepBrowserOpen ? [] : ['--disable-component-update']), // No component update downloads
|
|
1478
1506
|
'--disable-logging', // No Chrome internal log files
|
|
1479
1507
|
'--log-level=3', // Fatal errors only (suppresses verbose disk logging)
|
|
1480
1508
|
'--no-service-autorun', // No background service disk activity
|
|
1481
1509
|
'--disable-domain-reliability', // No reliability monitor disk writes
|
|
1482
|
-
// PERFORMANCE:
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
'--disable-features=BackForwardCache,AcceptCHFrame',
|
|
1510
|
+
// PERFORMANCE: Disable non-essential Chrome features in a single flag
|
|
1511
|
+
// IMPORTANT: Chrome only reads the LAST --disable-features flag, so combine all into one
|
|
1512
|
+
`--disable-features=AudioServiceOutOfProcess,VizDisplayCompositor,TranslateUI,BlinkGenPropertyTrees,Translate,BackForwardCache,AcceptCHFrame,SafeBrowsing,HttpsFirstBalancedModeAutoEnable,site-per-process,PaintHolding${disable_ad_tagging ? ',AdTagging' : ''}`,
|
|
1486
1513
|
'--disable-ipc-flooding-protection',
|
|
1487
1514
|
'--aggressive-cache-discard',
|
|
1488
1515
|
'--memory-pressure-off',
|
|
1489
1516
|
'--max_old_space_size=2048', // V8 heap limit
|
|
1490
1517
|
'--disable-prompt-on-repost', // Fixes form popup on page reload
|
|
1491
|
-
'--disable-background-networking',
|
|
1518
|
+
...(keepBrowserOpen ? [] : ['--disable-background-networking']),
|
|
1492
1519
|
'--no-sandbox',
|
|
1493
1520
|
'--disable-setuid-sandbox',
|
|
1494
|
-
'--disable-features=SafeBrowsing',
|
|
1495
1521
|
'--disable-dev-shm-usage',
|
|
1496
|
-
'--disable-sync',
|
|
1522
|
+
...(keepBrowserOpen ? [] : ['--disable-sync']),
|
|
1497
1523
|
'--mute-audio',
|
|
1498
1524
|
'--disable-translate',
|
|
1499
1525
|
'--window-size=1920,1080',
|
|
1500
|
-
'--disable-extensions',
|
|
1526
|
+
...(keepBrowserOpen ? [] : ['--disable-extensions', '--disable-component-update']),
|
|
1527
|
+
...(loadExtensionPaths.length ? [`--load-extension=${loadExtensionPaths.join(',')}`, '--enable-extensions'] : []),
|
|
1501
1528
|
'--no-default-browser-check',
|
|
1502
1529
|
'--safebrowsing-disable-auto-update',
|
|
1503
1530
|
'--ignore-ssl-errors',
|
|
@@ -1506,18 +1533,15 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1506
1533
|
'--ignore-certificate-errors-ca-list',
|
|
1507
1534
|
'--disable-web-security',
|
|
1508
1535
|
'--allow-running-insecure-content',
|
|
1509
|
-
'--disable-features=HttpsFirstBalancedModeAutoEnable',
|
|
1510
1536
|
// Puppeteer 23.x: Enhanced performance and stability args
|
|
1511
1537
|
'--disable-renderer-backgrounding',
|
|
1512
1538
|
'--disable-backgrounding-occluded-windows',
|
|
1513
1539
|
'--disable-background-timer-throttling',
|
|
1514
|
-
'--disable-features=site-per-process', // Better for single-site scanning
|
|
1515
1540
|
'--no-zygote', // Better process isolation
|
|
1516
1541
|
// PERFORMANCE: Process and memory reduction for high concurrency
|
|
1517
1542
|
'--renderer-process-limit=10', // Cap renderer processes (default: unlimited)
|
|
1518
1543
|
'--disable-accelerated-2d-canvas', // Software canvas only (we spoof it anyway)
|
|
1519
1544
|
'--disable-hang-monitor', // Remove per-renderer hang check overhead
|
|
1520
|
-
'--disable-features=PaintHolding', // Don't hold frames in renderer memory
|
|
1521
1545
|
'--js-flags=--max-old-space-size=512', // Cap V8 heap per renderer to 512MB
|
|
1522
1546
|
...extraArgs,
|
|
1523
1547
|
],
|
|
@@ -4601,9 +4625,19 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
4601
4625
|
// Keep browser open if --keep-open flag is set (useful with --headful for inspection)
|
|
4602
4626
|
if (keepBrowserOpen && !launchHeadless) {
|
|
4603
4627
|
console.log(messageColors.info('Browser kept open.') + ' Close the browser window or press Ctrl+C to exit.');
|
|
4628
|
+
const cleanup = async () => {
|
|
4629
|
+
try {
|
|
4630
|
+
if (browser.isConnected()) await browser.close();
|
|
4631
|
+
} catch {}
|
|
4632
|
+
process.exit(0);
|
|
4633
|
+
};
|
|
4634
|
+
process.on('SIGINT', cleanup);
|
|
4635
|
+
process.on('SIGTERM', cleanup);
|
|
4604
4636
|
await new Promise((resolve) => {
|
|
4605
4637
|
browser.on('disconnected', resolve);
|
|
4606
4638
|
});
|
|
4639
|
+
process.removeListener('SIGINT', cleanup);
|
|
4640
|
+
process.removeListener('SIGTERM', cleanup);
|
|
4607
4641
|
}
|
|
4608
4642
|
|
|
4609
4643
|
// Perform comprehensive final cleanup using enhanced browserexit module
|
|
@@ -4680,6 +4714,24 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
4680
4714
|
if (ignoreCache && forceDebug) {
|
|
4681
4715
|
console.log(messageColors.info('Cache:') + ` Smart caching was disabled`);
|
|
4682
4716
|
}
|
|
4717
|
+
// DNS cache statistics
|
|
4718
|
+
const dnsStats = getDnsCacheStats();
|
|
4719
|
+
if (dnsStats.digHits + dnsStats.digMisses > 0 || dnsStats.whoisHits + dnsStats.whoisMisses > 0) {
|
|
4720
|
+
const parts = [];
|
|
4721
|
+
if (dnsStats.digHits + dnsStats.digMisses > 0) {
|
|
4722
|
+
parts.push(`${messageColors.success(dnsStats.digHits)} dig cached, ${messageColors.timing(dnsStats.digMisses)} fresh`);
|
|
4723
|
+
}
|
|
4724
|
+
if (dnsStats.whoisHits + dnsStats.whoisMisses > 0) {
|
|
4725
|
+
parts.push(`${messageColors.success(dnsStats.whoisHits)} whois cached, ${messageColors.timing(dnsStats.whoisMisses)} fresh`);
|
|
4726
|
+
}
|
|
4727
|
+
console.log(messageColors.info('DNS cache:') + ` ${parts.join(' | ')}`);
|
|
4728
|
+
if (dnsStats.freshDig.length > 0) {
|
|
4729
|
+
console.log(messageColors.info(' Fresh dig:') + ` ${dnsStats.freshDig.join(', ')}`);
|
|
4730
|
+
}
|
|
4731
|
+
if (dnsStats.freshWhois.length > 0) {
|
|
4732
|
+
console.log(messageColors.info(' Fresh whois:') + ` ${dnsStats.freshWhois.join(', ')}`);
|
|
4733
|
+
}
|
|
4734
|
+
}
|
|
4683
4735
|
}
|
|
4684
4736
|
|
|
4685
4737
|
// Clean process termination
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fanboynz/network-scanner",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.60",
|
|
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": {
|