@fanboynz/network-scanner 1.0.76 → 1.0.77

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/cloudflare.js CHANGED
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Cloudflare bypass and challenge handling module - Optimized with smart detection and adaptive timeouts
3
- * Version: 2.2.0 - Enhanced with retry logic, caching, and improved error handling
3
+ * Version: 2.3.0 - Support iframe CF, and better error handling
4
4
  * Handles phishing warnings, Turnstile challenges, and modern Cloudflare protections
5
5
  */
6
6
 
7
7
  /**
8
8
  * Module version information
9
9
  */
10
- const CLOUDFLARE_MODULE_VERSION = '2.2.0';
10
+ const CLOUDFLARE_MODULE_VERSION = '2.3.0';
11
11
 
12
12
  /**
13
13
  * Timeout constants for various operations (in milliseconds)
@@ -749,6 +749,144 @@ async function attemptChallengeSolve(page, currentUrl, challengeInfo, forceDebug
749
749
  return result;
750
750
  }
751
751
 
752
+ /**
753
+ * Enhanced embedded iframe challenge detection and interaction
754
+ */
755
+ async function handleEmbeddedIframeChallenge(page, forceDebug = false) {
756
+ const result = {
757
+ success: false,
758
+ error: null
759
+ };
760
+
761
+ try {
762
+ if (forceDebug) console.log(`[debug][cloudflare] Checking for embedded iframe challenges`);
763
+
764
+ // Enhanced iframe selectors including challenges.cloudflare.com
765
+ const iframeSelectors = [
766
+ 'iframe[src*="challenges.cloudflare.com"]',
767
+ 'iframe[title*="Verify you are human"]',
768
+ 'iframe[title*="Cloudflare security challenge"]',
769
+ 'iframe[title*="Widget containing a Cloudflare"]'
770
+ ];
771
+
772
+ // Wait for iframe to appear
773
+ let iframeFound = false;
774
+ for (const selector of iframeSelectors) {
775
+ try {
776
+ await Promise.race([
777
+ page.waitForSelector(selector, { timeout: FAST_TIMEOUTS.SELECTOR_WAIT }),
778
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), FAST_TIMEOUTS.SELECTOR_WAIT + 1000))
779
+ ]);
780
+ iframeFound = true;
781
+ if (forceDebug) console.log(`[debug][cloudflare] Found iframe: ${selector}`);
782
+ break;
783
+ } catch (e) {
784
+ continue;
785
+ }
786
+ }
787
+
788
+ if (!iframeFound) {
789
+ result.error = 'No embedded iframe found';
790
+ return result;
791
+ }
792
+
793
+ // Find challenge frame using existing frame detection logic
794
+ const frames = await page.frames();
795
+ const challengeFrame = frames.find(frame => {
796
+ const frameUrl = frame.url();
797
+ return frameUrl.includes('challenges.cloudflare.com') ||
798
+ frameUrl.includes('/turnstile/if/') ||
799
+ frameUrl.includes('captcha-delivery.com') ||
800
+ frameUrl.includes('/challenge-platform/') ||
801
+ frameUrl.includes('turnstile');
802
+ });
803
+
804
+ if (!challengeFrame) {
805
+ result.error = 'Challenge iframe not accessible';
806
+ return result;
807
+ }
808
+
809
+ if (forceDebug) console.log(`[debug][cloudflare] Interacting with iframe: ${challengeFrame.url()}`);
810
+
811
+ // Reuse existing checkbox interaction logic
812
+ const checkboxSelectors = [
813
+ 'input[type="checkbox"]',
814
+ '.ctp-checkbox',
815
+ 'input.ctp-checkbox',
816
+ '.cf-turnstile input',
817
+ '.ctp-checkbox-label'
818
+ ];
819
+
820
+ let checkboxInteractionSuccess = false;
821
+ for (const selector of checkboxSelectors) {
822
+ try {
823
+ await Promise.race([
824
+ challengeFrame.waitForSelector(selector, { timeout: FAST_TIMEOUTS.SELECTOR_WAIT }),
825
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), FAST_TIMEOUTS.SELECTOR_WAIT + 1000))
826
+ ]);
827
+
828
+ await waitForTimeout(page, FAST_TIMEOUTS.ELEMENT_INTERACTION_DELAY);
829
+ await challengeFrame.click(selector);
830
+
831
+ if (forceDebug) console.log(`[debug][cloudflare] Clicked iframe element: ${selector}`);
832
+ checkboxInteractionSuccess = true;
833
+ break;
834
+ } catch (e) {
835
+ continue;
836
+ }
837
+ }
838
+
839
+ // Try alternative interaction only if standard selectors failed
840
+ if (!checkboxInteractionSuccess) {
841
+ if (forceDebug) console.log(`[debug][cloudflare] Checkbox interactions failed, trying container fallback`);
842
+ await waitForTimeout(page, 1000);
843
+
844
+ try {
845
+ // Try clicking on the iframe container itself as fallback
846
+ const iframeElement = await page.$('iframe[src*="challenges.cloudflare.com"]');
847
+ if (iframeElement) {
848
+ await iframeElement.click();
849
+ if (forceDebug) console.log(`[debug][cloudflare] Clicked iframe container as fallback`);
850
+ }
851
+ } catch (containerClickError) {
852
+ if (forceDebug) console.log(`[debug][cloudflare] Container click failed: ${containerClickError.message}`);
853
+ }
854
+ } else {
855
+ if (forceDebug) console.log(`[debug][cloudflare] Checkbox interaction successful, skipping container fallback`);
856
+ }
857
+
858
+ // Reuse existing completion check pattern with error handling
859
+ try {
860
+ await Promise.race([
861
+ page.waitForFunction(
862
+ () => {
863
+ const responseInput = document.querySelector('input[name="cf-turnstile-response"]');
864
+ const hasResponse = responseInput && responseInput.value && responseInput.value.length > 0;
865
+ const hasClearance = document.cookie.includes('cf_clearance');
866
+ const noChallenge = !document.body.textContent.includes('Verify you are human');
867
+
868
+ return hasResponse || hasClearance || noChallenge;
869
+ },
870
+ { timeout: TIMEOUTS.TURNSTILE_COMPLETION }
871
+ ),
872
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Completion check timeout')), TIMEOUTS.TURNSTILE_COMPLETION_BUFFER))
873
+ ]);
874
+
875
+ result.success = true;
876
+ if (forceDebug) console.log(`[debug][cloudflare] Embedded iframe challenge completed`);
877
+ } catch (completionError) {
878
+ result.error = `Challenge completion check failed: ${completionError.message}`;
879
+ if (forceDebug) console.log(`[debug][cloudflare] Completion check failed: ${completionError.message}`);
880
+ }
881
+
882
+ } catch (error) {
883
+ result.error = `Embedded iframe handling failed: ${error.message}`;
884
+ if (forceDebug) console.log(`[debug][cloudflare] ${result.error}`);
885
+ }
886
+
887
+ return result;
888
+ }
889
+
752
890
  /**
753
891
  * Waits for JS challenge completion with timeout protection and enhanced debug logging
754
892
  */
@@ -796,6 +934,14 @@ async function handleTurnstileChallenge(page, forceDebug = false) {
796
934
  error: null
797
935
  };
798
936
 
937
+ // Try embedded iframe approach first
938
+ const iframeResult = await handleEmbeddedIframeChallenge(page, forceDebug);
939
+ if (iframeResult.success) {
940
+ return { ...result, success: true };
941
+ }
942
+
943
+ if (forceDebug) console.log(`[debug][cloudflare] Embedded iframe failed: ${iframeResult.error}, trying legacy method`);
944
+
799
945
  try {
800
946
  // Use fast timeout for Turnstile operations
801
947
  const turnstileTimeout = FAST_TIMEOUTS.TURNSTILE_OPERATION;
@@ -1276,6 +1422,29 @@ async function parallelChallengeDetection(page, forceDebug = false) {
1276
1422
  };
1277
1423
  }
1278
1424
 
1425
+ /**
1426
+ * Enhanced parallel detection including embedded iframe challenges
1427
+ */
1428
+ async function enhancedParallelChallengeDetection(page, forceDebug = false) {
1429
+ const existingDetection = await parallelChallengeDetection(page, forceDebug);
1430
+
1431
+ try {
1432
+ const hasEmbeddedIframe = await page.evaluate(() => {
1433
+ return document.querySelector('iframe[src*="challenges.cloudflare.com"]') !== null ||
1434
+ document.querySelector('iframe[title*="Verify you are human"]') !== null;
1435
+ });
1436
+
1437
+ if (hasEmbeddedIframe && !existingDetection.challenges.includes('embedded_iframe')) {
1438
+ existingDetection.challenges.push('embedded_iframe');
1439
+ existingDetection.hasAnyChallenge = true;
1440
+ }
1441
+ } catch (e) {
1442
+ // Ignore detection errors
1443
+ }
1444
+
1445
+ return existingDetection;
1446
+ }
1447
+
1279
1448
  /**
1280
1449
  * Gets cache statistics for performance monitoring
1281
1450
  */
@@ -1300,6 +1469,8 @@ module.exports = {
1300
1469
  waitForJSChallengeCompletion,
1301
1470
  handleLegacyCheckbox,
1302
1471
  checkChallengeCompletion,
1472
+ handleEmbeddedIframeChallenge,
1473
+ enhancedParallelChallengeDetection,
1303
1474
  quickCloudflareDetection,
1304
1475
  getModuleInfo,
1305
1476
  CLOUDFLARE_MODULE_VERSION,
package/nwss.js CHANGED
@@ -1,4 +1,4 @@
1
- // === Network scanner script (nwss.js) v1.0.76 ===
1
+ // === Network scanner script (nwss.js) v1.0.77 ===
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
@@ -123,7 +123,7 @@ const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/r
123
123
  const { monitorBrowserHealth, isBrowserHealthy } = require('./lib/browserhealth');
124
124
 
125
125
  // --- Script Configuration & Constants ---
126
- const VERSION = '1.0.76'; // Script version
126
+ const VERSION = '1.0.77'; // Script version
127
127
 
128
128
  // get startTime
129
129
  const startTime = Date.now();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fanboynz/network-scanner",
3
- "version": "1.0.76",
3
+ "version": "1.0.77",
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": {