(url)
| 811 | } |
| 812 | |
| 813 | async function checkPaths(url) { |
| 814 | const settings = await getSettings(); |
| 815 | |
| 816 | try { |
| 817 | const urlObj = new URL(url); |
| 818 | const baseUrl = `${urlObj.protocol}//${urlObj.hostname}`; |
| 819 | |
| 820 | // Get cached domain baseline |
| 821 | const baseline = await getDomainBaseline(baseUrl); |
| 822 | if (!baseline) return; |
| 823 | |
| 824 | // Flatten paths with severity, checking critical first |
| 825 | const allPaths = [ |
| 826 | ...sensitivePaths.critical.map(p => ({ path: p, severity: 'critical' })), |
| 827 | ...sensitivePaths.high.map(p => ({ path: p, severity: 'high' })), |
| 828 | ...sensitivePaths.medium.map(p => ({ path: p, severity: 'medium' })), |
| 829 | ]; |
| 830 | |
| 831 | // Check paths in batches to reduce concurrent requests |
| 832 | const batchSize = 3; |
| 833 | for (let i = 0; i < allPaths.length; i += batchSize) { |
| 834 | const batch = allPaths.slice(i, i + batchSize); |
| 835 | |
| 836 | const results = await Promise.all( |
| 837 | batch.map(({ path, severity }) => |
| 838 | checkPathWithHead(baseUrl, path, settings).then(result => |
| 839 | result ? { ...result, severity, path } : null |
| 840 | ) |
| 841 | ) |
| 842 | ); |
| 843 | |
| 844 | for (const result of results.filter(Boolean)) { |
| 845 | try { |
| 846 | const pathText = await result.response.text(); |
| 847 | |
| 848 | // Skip if matches soft-404 fingerprint |
| 849 | if (matchesSoft404(result.response, pathText, baseline.soft404Fingerprint)) { |
| 850 | continue; |
| 851 | } |
| 852 | |
| 853 | // Skip common soft-404 indicators |
| 854 | if (isSoft404(pathText)) continue; |
| 855 | if (pathText.length < 50) continue; |
| 856 | |
| 857 | // Check for debug indicators (upgrades severity if found) |
| 858 | const debugCheck = containsDebugIndicators(pathText); |
| 859 | const severity = debugCheck.found ? debugCheck.level : result.severity; |
| 860 | |
| 861 | // Path exists and is not soft-404 - report it! |
| 862 | // No diff comparison needed since these are different paths |
| 863 | await addFinding('paths', { |
| 864 | path: result.url, |
| 865 | severity, |
| 866 | contentLength: pathText.length, |
| 867 | hasDebugInfo: debugCheck.found, |
| 868 | modifiedResponse: truncateForStorage(pathText), |
| 869 | }); |
| 870 | } catch (e) { |
no test coverage detected