@js-recon/js-recon 1.4.4 → 2.0.1-alpha.1
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/.claude-sync/sync.sh +1 -1
- package/.github/workflows/build-and-prettify.yaml +49 -19
- package/.github/workflows/codeql.yml +33 -0
- package/.github/workflows/exploit-smoke-test.yaml +160 -0
- package/.github/workflows/framework-detection-smoke-test.yaml +135 -0
- package/.github/workflows/plumber.yml +20 -0
- package/.github/workflows/promote-js-recon.yml +5 -3
- package/.github/workflows/publish-js-recon.yml +6 -1
- package/.github/workflows/rules-smoke-test.yaml +13 -5
- package/.nvmrc +1 -0
- package/.plumber.yaml +151 -0
- package/CHANGELOG.md +35 -0
- package/CONTRIBUTING.md +32 -0
- package/Dockerfile +1 -0
- package/README.md +3 -2
- package/SECURITY.md +1 -1
- package/build/analyze/engine/astEngine.js +10 -9
- package/build/analyze/engine/astEngine.js.map +1 -1
- package/build/analyze/engine/csMastSEngine.js +6 -6
- package/build/analyze/engine/csMastSEngine.js.map +1 -1
- package/build/analyze/engine/index.js +1 -1
- package/build/analyze/engine/index.js.map +1 -1
- package/build/analyze/engine/requestEngine.js +6 -6
- package/build/analyze/engine/requestEngine.js.map +1 -1
- package/build/analyze/helpers/determineCompatibleVersion.js +70 -0
- package/build/analyze/helpers/determineCompatibleVersion.js.map +1 -0
- package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js +9 -3
- package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js.map +1 -1
- package/build/analyze/helpers/initRules.js +9 -9
- package/build/analyze/helpers/initRules.js.map +1 -1
- package/build/analyze/helpers/outputHelper.js +3 -3
- package/build/analyze/helpers/outputHelper.js.map +1 -1
- package/build/analyze/helpers/schemas.js +1 -0
- package/build/analyze/helpers/schemas.js.map +1 -1
- package/build/analyze/helpers/validate.js +9 -5
- package/build/analyze/helpers/validate.js.map +1 -1
- package/build/analyze/index.js +26 -16
- package/build/analyze/index.js.map +1 -1
- package/build/cliProgram.js +710 -0
- package/build/cliProgram.js.map +1 -0
- package/build/completion/index.js +247 -382
- package/build/completion/index.js.map +1 -1
- package/build/completion/introspect.js +17 -0
- package/build/completion/introspect.js.map +1 -0
- package/build/config/applicationConfig.js +3 -2
- package/build/config/applicationConfig.js.map +1 -1
- package/build/cs_mast/index.js +18 -17
- package/build/cs_mast/index.js.map +1 -1
- package/build/endpoints/gen_report/gen_json.js +2 -2
- package/build/endpoints/gen_report/gen_json.js.map +1 -1
- package/build/endpoints/gen_report/utility/iterate_n_store.js +1 -1
- package/build/endpoints/gen_report/utility/iterate_n_store.js.map +1 -1
- package/build/endpoints/index.js +12 -12
- package/build/endpoints/index.js.map +1 -1
- package/build/endpoints/next_js/client_jsFilesHref.js +3 -3
- package/build/endpoints/next_js/client_jsFilesHref.js.map +1 -1
- package/build/endpoints/next_js/client_jsonParse.js +4 -4
- package/build/endpoints/next_js/client_jsonParse.js.map +1 -1
- package/build/endpoints/next_js/client_mappedJsonFile.js +6 -6
- package/build/endpoints/next_js/client_mappedJsonFile.js.map +1 -1
- package/build/endpoints/next_js/client_subsequentRequests.js +5 -5
- package/build/endpoints/next_js/client_subsequentRequests.js.map +1 -1
- package/build/exploit/angular/cve-2026-68945.js +61 -0
- package/build/exploit/angular/cve-2026-68945.js.map +1 -0
- package/build/exploit/index.js +60 -0
- package/build/exploit/index.js.map +1 -0
- package/build/exploit/next/cve-2025-29927.js +65 -0
- package/build/exploit/next/cve-2025-29927.js.map +1 -0
- package/build/exploit/next/cve-2026-64645.js +51 -0
- package/build/exploit/next/cve-2026-64645.js.map +1 -0
- package/build/exploit/nuxt/cve-2026-71315.js +47 -0
- package/build/exploit/nuxt/cve-2026-71315.js.map +1 -0
- package/build/exploit/nuxt/cve-2026-71320.js +114 -0
- package/build/exploit/nuxt/cve-2026-71320.js.map +1 -0
- package/build/exploit/react/cve-2025-55182.js +116 -0
- package/build/exploit/react/cve-2025-55182.js.map +1 -0
- package/build/exploit/registry/cveRegistry.js +115 -0
- package/build/exploit/registry/cveRegistry.js.map +1 -0
- package/build/exploit/types.js +2 -0
- package/build/exploit/types.js.map +1 -0
- package/build/exploit/utility/compareResponses.js +29 -0
- package/build/exploit/utility/compareResponses.js.map +1 -0
- package/build/exploit/utility/outputHelper.js +22 -0
- package/build/exploit/utility/outputHelper.js.map +1 -0
- package/build/exploit/utility/rawRequest.js +54 -0
- package/build/exploit/utility/rawRequest.js.map +1 -0
- package/build/exploit/utility/sandboxRce.js +49 -0
- package/build/exploit/utility/sandboxRce.js.map +1 -0
- package/build/exploit/utility/toEngineOutput.js +28 -0
- package/build/exploit/utility/toEngineOutput.js.map +1 -0
- package/build/exploit/utility/wsClient.js +78 -0
- package/build/exploit/utility/wsClient.js.map +1 -0
- package/build/exploit/vite/cve-2025-30208.js +44 -0
- package/build/exploit/vite/cve-2025-30208.js.map +1 -0
- package/build/exploit/vite/cve-2026-39363.js +60 -0
- package/build/exploit/vite/cve-2026-39363.js.map +1 -0
- package/build/fingerprint/index.js +3 -2
- package/build/fingerprint/index.js.map +1 -1
- package/build/globalConfig.js +2 -2
- package/build/globalConfig.js.map +1 -1
- package/build/index.js +5 -596
- package/build/index.js.map +1 -1
- package/build/lazyLoad/angular/angular_getFromPageSource.js +3 -3
- package/build/lazyLoad/angular/angular_getFromPageSource.js.map +1 -1
- package/build/lazyLoad/downloadFilesUtil.js +14 -11
- package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
- package/build/lazyLoad/downloadQueue.js +5 -1
- package/build/lazyLoad/downloadQueue.js.map +1 -1
- package/build/lazyLoad/downloadResponse.js +1 -0
- package/build/lazyLoad/downloadResponse.js.map +1 -1
- package/build/lazyLoad/generic/generic_crawlPages.js +186 -0
- package/build/lazyLoad/generic/generic_crawlPages.js.map +1 -0
- package/build/lazyLoad/generic/generic_downloadFiles.js +81 -0
- package/build/lazyLoad/generic/generic_downloadFiles.js.map +1 -0
- package/build/lazyLoad/generic/generic_extractLinks.js +79 -0
- package/build/lazyLoad/generic/generic_extractLinks.js.map +1 -0
- package/build/lazyLoad/generic/generic_getScriptTags.js +152 -0
- package/build/lazyLoad/generic/generic_getScriptTags.js.map +1 -0
- package/build/lazyLoad/generic/generic_importMapDiscovery.js +87 -0
- package/build/lazyLoad/generic/generic_importMapDiscovery.js.map +1 -0
- package/build/lazyLoad/generic/generic_resolveScope.js +61 -0
- package/build/lazyLoad/generic/generic_resolveScope.js.map +1 -0
- package/build/lazyLoad/generic/generic_scanAttributesForJs.js +122 -0
- package/build/lazyLoad/generic/generic_scanAttributesForJs.js.map +1 -0
- package/build/lazyLoad/generic/generic_stringsDiscovery.js +103 -0
- package/build/lazyLoad/generic/generic_stringsDiscovery.js.map +1 -0
- package/build/lazyLoad/generic/generic_webpackChunkPaths.js +56 -0
- package/build/lazyLoad/generic/generic_webpackChunkPaths.js.map +1 -0
- package/build/lazyLoad/globals.js +31 -0
- package/build/lazyLoad/globals.js.map +1 -1
- package/build/lazyLoad/index.js +129 -66
- package/build/lazyLoad/index.js.map +1 -1
- package/build/lazyLoad/methodFilter.js +2 -0
- package/build/lazyLoad/methodFilter.js.map +1 -1
- package/build/lazyLoad/next_js/NextJsCrawler.js +38 -14
- package/build/lazyLoad/next_js/NextJsCrawler.js.map +1 -1
- package/build/lazyLoad/next_js/next_GetJSScript.js +3 -3
- package/build/lazyLoad/next_js/next_GetJSScript.js.map +1 -1
- package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js +4 -4
- package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +13 -11
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_SubsequentRequests.js +7 -6
- package/build/lazyLoad/next_js/next_SubsequentRequests.js.map +1 -1
- package/build/lazyLoad/next_js/next_bruteForceJsFiles.js +1 -1
- package/build/lazyLoad/next_js/next_bruteForceJsFiles.js.map +1 -1
- package/build/lazyLoad/next_js/next_buildId.js +2 -2
- package/build/lazyLoad/next_js/next_buildId.js.map +1 -1
- package/build/lazyLoad/next_js/next_getClientSidePaths.js +2 -2
- package/build/lazyLoad/next_js/next_getClientSidePaths.js.map +1 -1
- package/build/lazyLoad/next_js/next_parseLayoutJs.js +6 -6
- package/build/lazyLoad/next_js/next_parseLayoutJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_promiseResolve.js +1 -1
- package/build/lazyLoad/next_js/next_promiseResolve.js.map +1 -1
- package/build/lazyLoad/next_js/next_routerStateForge.js +341 -0
- package/build/lazyLoad/next_js/next_routerStateForge.js.map +1 -0
- package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js +1 -1
- package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js.map +1 -1
- package/build/lazyLoad/next_js/next_serverActionIdScan.js +77 -0
- package/build/lazyLoad/next_js/next_serverActionIdScan.js.map +1 -0
- package/build/lazyLoad/nuxt_js/nuxt_astParse.js +15 -13
- package/build/lazyLoad/nuxt_js/nuxt_astParse.js.map +1 -1
- package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js +2 -2
- package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js.map +1 -1
- package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +3 -3
- package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js.map +1 -1
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +2 -2
- package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -1
- package/build/lazyLoad/react/react_webpackChunkPaths.js +10 -202
- package/build/lazyLoad/react/react_webpackChunkPaths.js.map +1 -1
- package/build/lazyLoad/researchUtils.js +15 -0
- package/build/lazyLoad/researchUtils.js.map +1 -0
- package/build/lazyLoad/shared/webpackChunkParsers.js +218 -0
- package/build/lazyLoad/shared/webpackChunkParsers.js.map +1 -0
- package/build/lazyLoad/stagnation/stagnationMonitor.js +63 -0
- package/build/lazyLoad/stagnation/stagnationMonitor.js.map +1 -0
- package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js +1 -0
- package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_getFromPageSource.js +5 -5
- package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_getVersionJson.js +2 -2
- package/build/lazyLoad/svelte/svelte_getVersionJson.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js +6 -6
- package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js.map +1 -1
- package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +2 -2
- package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -1
- package/build/lazyLoad/techDetect/checkAngularJS.js +1 -1
- package/build/lazyLoad/techDetect/checkAngularJS.js.map +1 -1
- package/build/lazyLoad/techDetect/checkNuxtJS.js +3 -3
- package/build/lazyLoad/techDetect/checkNuxtJS.js.map +1 -1
- package/build/lazyLoad/techDetect/checkSvelte.js +0 -1
- package/build/lazyLoad/techDetect/checkSvelte.js.map +1 -1
- package/build/lazyLoad/techDetect/checkVueJS.js +6 -6
- package/build/lazyLoad/techDetect/checkVueJS.js.map +1 -1
- package/build/lazyLoad/techDetect/index.js +13 -1
- package/build/lazyLoad/techDetect/index.js.map +1 -1
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +2 -2
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -1
- package/build/lazyLoad/vue/vue_discoverJsFiles.js +12 -10
- package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -1
- package/build/lazyLoad/vue/vue_getClientSidePaths.js +1 -1
- package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -1
- package/build/lazyLoad/vue/vue_pageSrc.js +1 -1
- package/build/lazyLoad/vue/vue_pageSrc.js.map +1 -1
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js +2 -2
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js.map +1 -1
- package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +2 -2
- package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -1
- package/build/lazyLoad/vue/vue_severalJsFilesHome.js +3 -3
- package/build/lazyLoad/vue/vue_severalJsFilesHome.js.map +1 -1
- package/build/load/index.js +8 -7
- package/build/load/index.js.map +1 -1
- package/build/map/angular_js/getAngularConnections.js +6 -6
- package/build/map/angular_js/getAngularConnections.js.map +1 -1
- package/build/map/graphql/resolveGraphql.js +6 -6
- package/build/map/graphql/resolveGraphql.js.map +1 -1
- package/build/map/index.js +17 -17
- package/build/map/index.js.map +1 -1
- package/build/map/interactive-mode/commandHandler.js +278 -0
- package/build/map/interactive-mode/commandHandler.js.map +1 -0
- package/build/map/interactive-mode/commandHelpers.js +189 -0
- package/build/map/interactive-mode/commandHelpers.js.map +1 -0
- package/build/map/interactive-mode/esqueryGen.js.map +1 -0
- package/build/map/interactive-mode/helpMenu.js +11 -0
- package/build/map/interactive-mode/helpMenu.js.map +1 -0
- package/build/map/interactive-mode/inputPatch.js.map +1 -0
- package/build/map/interactive-mode/interactive.js +71 -0
- package/build/map/interactive-mode/interactive.js.map +1 -0
- package/build/map/interactive-mode/keybindings.js.map +1 -0
- package/build/map/interactive-mode/printer.js.map +1 -0
- package/build/map/interactive-mode/ui.js.map +1 -0
- package/build/map/next_js/getAxiosInstances.js +5 -5
- package/build/map/next_js/getAxiosInstances.js.map +1 -1
- package/build/map/next_js/getExports.js +4 -4
- package/build/map/next_js/getExports.js.map +1 -1
- package/build/map/next_js/getFetchInstances.js +10 -10
- package/build/map/next_js/getFetchInstances.js.map +1 -1
- package/build/map/next_js/getTurbopackConnections.js +8 -8
- package/build/map/next_js/getTurbopackConnections.js.map +1 -1
- package/build/map/next_js/getWebpackConnections.js +27 -16
- package/build/map/next_js/getWebpackConnections.js.map +1 -1
- package/build/map/next_js/interactive.js +3 -65
- package/build/map/next_js/interactive.js.map +1 -1
- package/build/map/next_js/interactive_helpers/commandHandler.js +38 -290
- package/build/map/next_js/interactive_helpers/commandHandler.js.map +1 -1
- package/build/map/next_js/interactive_helpers/commandHelpers.js +0 -184
- package/build/map/next_js/interactive_helpers/commandHelpers.js.map +1 -1
- package/build/map/next_js/interactive_helpers/helpMenu.js +2 -10
- package/build/map/next_js/interactive_helpers/helpMenu.js.map +1 -1
- package/build/map/next_js/resolveAxios.js +6 -6
- package/build/map/next_js/resolveAxios.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js +4 -4
- package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js +2 -2
- package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +5 -5
- package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +10 -10
- package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +13 -9
- package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js +12 -8
- package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js +12 -8
- package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +11 -11
- package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -1
- package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +16 -16
- package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -1
- package/build/map/next_js/resolveFetch.js +23 -23
- package/build/map/next_js/resolveFetch.js.map +1 -1
- package/build/map/next_js/resolveNewRequest.js +10 -10
- package/build/map/next_js/resolveNewRequest.js.map +1 -1
- package/build/map/next_js/resolveServerActions.js +4 -4
- package/build/map/next_js/resolveServerActions.js.map +1 -1
- package/build/map/next_js/utils.js +8 -2
- package/build/map/next_js/utils.js.map +1 -1
- package/build/map/react_js/getReactConnections.js +21 -14
- package/build/map/react_js/getReactConnections.js.map +1 -1
- package/build/map/svelte_js/interactive.js +3 -54
- package/build/map/svelte_js/interactive.js.map +1 -1
- package/build/map/vue_js/getViteConnections.js +23 -16
- package/build/map/vue_js/getViteConnections.js.map +1 -1
- package/build/map/vue_js/interactive.js +3 -63
- package/build/map/vue_js/interactive.js.map +1 -1
- package/build/map/vue_js/interactive_helpers/commandHandler.js +34 -283
- package/build/map/vue_js/interactive_helpers/commandHandler.js.map +1 -1
- package/build/map/vue_js/interactive_helpers/helpMenu.js +2 -10
- package/build/map/vue_js/interactive_helpers/helpMenu.js.map +1 -1
- package/build/map/vue_js/taint_utils.js +1 -1
- package/build/map/vue_js/taint_utils.js.map +1 -1
- package/build/map/vue_js/vue_resolveFetch.js +12 -12
- package/build/map/vue_js/vue_resolveFetch.js.map +1 -1
- package/build/map/vue_js/vue_resolveHttpClient.js +18 -18
- package/build/map/vue_js/vue_resolveHttpClient.js.map +1 -1
- package/build/map/vue_js/vue_resolveXhr.js +11 -11
- package/build/map/vue_js/vue_resolveXhr.js.map +1 -1
- package/build/mcp/chatOneShot.js +7 -7
- package/build/mcp/chatOneShot.js.map +1 -1
- package/build/mcp/claudeCodeCreds.js +5 -5
- package/build/mcp/claudeCodeCreds.js.map +1 -1
- package/build/mcp/cli.js +36 -35
- package/build/mcp/cli.js.map +1 -1
- package/build/mcp/config.js +4 -4
- package/build/mcp/config.js.map +1 -1
- package/build/mcp/index.js +7 -7
- package/build/mcp/index.js.map +1 -1
- package/build/mcp/mcpServer.js +3 -2
- package/build/mcp/mcpServer.js.map +1 -1
- package/build/mcp/skills.js +1 -0
- package/build/mcp/skills.js.map +1 -1
- package/build/mcp/tools.js +5 -4
- package/build/mcp/tools.js.map +1 -1
- package/build/proxy/detectBlockedResponse.js +2 -0
- package/build/proxy/detectBlockedResponse.js.map +1 -1
- package/build/proxy/index.js +3 -3
- package/build/proxy/index.js.map +1 -1
- package/build/refactor/index.js +83 -79
- package/build/refactor/index.js.map +1 -1
- package/build/refactor/next/index.js +69 -26
- package/build/refactor/next/index.js.map +1 -1
- package/build/refactor/next/transform.js +11 -4
- package/build/refactor/next/transform.js.map +1 -1
- package/build/refactor/next/validator.js +7 -7
- package/build/refactor/next/validator.js.map +1 -1
- package/build/refactor/react/index.js +13 -13
- package/build/refactor/react/index.js.map +1 -1
- package/build/refactor/react/validator.js +7 -7
- package/build/refactor/react/validator.js.map +1 -1
- package/build/refactor/react-vite/index.js +3 -3
- package/build/refactor/react-vite/index.js.map +1 -1
- package/build/refactor/remote/hf-client.js +1 -0
- package/build/refactor/remote/hf-client.js.map +1 -1
- package/build/refactor/remote/version-detect.js +12 -12
- package/build/refactor/remote/version-detect.js.map +1 -1
- package/build/refactor/vue/index.js +6 -6
- package/build/refactor/vue/index.js.map +1 -1
- package/build/refactor/vue/vite.js +6 -6
- package/build/refactor/vue/vite.js.map +1 -1
- package/build/report/index.js +30 -8
- package/build/report/index.js.map +1 -1
- package/build/report/swaggerJacker.js +63 -0
- package/build/report/swaggerJacker.js.map +1 -0
- package/build/report/utility/genHtml.js +7 -7
- package/build/report/utility/genHtml.js.map +1 -1
- package/build/report/utility/populateDb/populateAnalysisFindings.js +2 -2
- package/build/report/utility/populateDb/populateAnalysisFindings.js.map +1 -1
- package/build/report/utility/populateDb/populateEndpoints.js +3 -3
- package/build/report/utility/populateDb/populateEndpoints.js.map +1 -1
- package/build/report/utility/populateDb/populateMappedJson.js +2 -2
- package/build/report/utility/populateDb/populateMappedJson.js.map +1 -1
- package/build/report/utility/populateDb/populateMappedOpenapi.js +3 -3
- package/build/report/utility/populateDb/populateMappedOpenapi.js.map +1 -1
- package/build/run/bundler-detect.js +45 -9
- package/build/run/bundler-detect.js.map +1 -1
- package/build/run/dashboard/dashboardHtml.js +150 -0
- package/build/run/dashboard/dashboardHtml.js.map +1 -0
- package/build/run/dashboard/fsBrowser.js +43 -0
- package/build/run/dashboard/fsBrowser.js.map +1 -0
- package/build/run/dashboard/server.js +123 -0
- package/build/run/dashboard/server.js.map +1 -0
- package/build/run/dashboard/state.js +97 -0
- package/build/run/dashboard/state.js.map +1 -0
- package/build/run/index.js +177 -110
- package/build/run/index.js.map +1 -1
- package/build/run/interruptHandler.js +18 -0
- package/build/run/interruptHandler.js.map +1 -1
- package/build/sourcemaps/index.js +7 -6
- package/build/sourcemaps/index.js.map +1 -1
- package/build/strings/index.js +27 -24
- package/build/strings/index.js.map +1 -1
- package/build/strings/openapi.js +4 -4
- package/build/strings/openapi.js.map +1 -1
- package/build/strings/permutate.js +4 -4
- package/build/strings/permutate.js.map +1 -1
- package/build/strings/secrets.js +1 -0
- package/build/strings/secrets.js.map +1 -1
- package/build/strings/trufflehog.js +66 -19
- package/build/strings/trufflehog.js.map +1 -1
- package/build/strings/trufflehogConfig.js +36 -0
- package/build/strings/trufflehogConfig.js.map +1 -0
- package/build/strings/trufflehogDownload.js +115 -0
- package/build/strings/trufflehogDownload.js.map +1 -0
- package/build/utility/ai.js +33 -4
- package/build/utility/ai.js.map +1 -1
- package/build/utility/banner.js +4 -3
- package/build/utility/banner.js.map +1 -1
- package/build/utility/configureSandbox.js +2 -2
- package/build/utility/configureSandbox.js.map +1 -1
- package/build/utility/globals.js +19 -11
- package/build/utility/globals.js.map +1 -1
- package/build/utility/heap.js +2 -1
- package/build/utility/heap.js.map +1 -1
- package/build/utility/makeReq.js +1 -1
- package/build/utility/makeReq.js.map +1 -1
- package/build/utility/openapiGenerator.js +2 -2
- package/build/utility/openapiGenerator.js.map +1 -1
- package/build/utility/printMsg.js +53 -0
- package/build/utility/printMsg.js.map +1 -0
- package/build/utility/progressLog.js +4 -3
- package/build/utility/progressLog.js.map +1 -1
- package/build/utility/resolvePath.js +2 -1
- package/build/utility/resolvePath.js.map +1 -1
- package/build/utility/ruleVersionMap.js +73 -0
- package/build/utility/ruleVersionMap.js.map +1 -0
- package/contributing/testing.md +106 -0
- package/eslint.config.js +24 -0
- package/package.json +22 -5
- package/scripts/exploit-smoke-test.js +82 -0
- package/scripts/framework-detect-smoke-test.js +64 -0
- package/scripts/postinstall-completion.mjs +40 -0
- package/scripts/smoke-test.js +12 -0
- package/build/lazyLoad/downloadLoadedJsUtil.js +0 -98
- package/build/lazyLoad/downloadLoadedJsUtil.js.map +0 -1
- package/build/map/next_js/interactive_helpers/esqueryGen.js.map +0 -1
- package/build/map/next_js/interactive_helpers/inputPatch.js.map +0 -1
- package/build/map/next_js/interactive_helpers/keybindings.js.map +0 -1
- package/build/map/next_js/interactive_helpers/printer.js.map +0 -1
- package/build/map/next_js/interactive_helpers/ui.js.map +0 -1
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/esqueryGen.js +0 -0
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/inputPatch.js +0 -0
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/keybindings.js +0 -0
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/printer.js +0 -0
- /package/build/map/{next_js/interactive_helpers → interactive-mode}/ui.js +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import path from "path";
|
|
12
|
+
import { extractWebpackChunkUrls } from "../shared/webpackChunkParsers.js";
|
|
13
|
+
import { extractFileSourceUrl } from "./generic_stringsDiscovery.js";
|
|
14
|
+
import { confirmJsContentType } from "./generic_scanAttributesForJs.js";
|
|
15
|
+
/**
|
|
16
|
+
* Scans every JS file `generic` tech has already downloaded under outputDir for the
|
|
17
|
+
* same webpack chunk-path-builder patterns the React crawler already resolves (see
|
|
18
|
+
* `src/lazyLoad/shared/webpackChunkParsers.ts`). Internal#75: without this, a webpack
|
|
19
|
+
* or module-federation entry chunk downloaded under `generic` tech only ever yields the
|
|
20
|
+
* chunks that happened to fire live during the crawl — its own async-chunk hash-map is
|
|
21
|
+
* never statically enumerated the way React's `react_webpackChunkPaths.ts` already does.
|
|
22
|
+
*
|
|
23
|
+
* Reads from disk (recovering each file's source URL via the same
|
|
24
|
+
* `// File Source: <url>` header `generic_stringsDiscovery.ts` relies on) rather than
|
|
25
|
+
* re-fetching over the network, since the file is already on disk from an earlier
|
|
26
|
+
* download pass.
|
|
27
|
+
*/
|
|
28
|
+
const generic_webpackChunkPaths = (outputDir_1, ...args_1) => __awaiter(void 0, [outputDir_1, ...args_1], void 0, function* (outputDir, alreadyKnownUrls = new Set(), threads = 1) {
|
|
29
|
+
if (!fs.existsSync(outputDir))
|
|
30
|
+
return [];
|
|
31
|
+
const files = fs.readdirSync(outputDir, { recursive: true, encoding: "utf8" });
|
|
32
|
+
const jsFiles = files.filter((f) => f.endsWith(".js") || f.endsWith(".mjs"));
|
|
33
|
+
const candidates = new Set();
|
|
34
|
+
for (const relPath of jsFiles) {
|
|
35
|
+
const filePath = path.join(outputDir, relPath);
|
|
36
|
+
let content;
|
|
37
|
+
try {
|
|
38
|
+
content = fs.readFileSync(filePath, "utf-8");
|
|
39
|
+
}
|
|
40
|
+
catch (_a) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const sourceUrl = extractFileSourceUrl(content);
|
|
44
|
+
if (!sourceUrl)
|
|
45
|
+
continue;
|
|
46
|
+
for (const url of extractWebpackChunkUrls(content, sourceUrl)) {
|
|
47
|
+
if (!alreadyKnownUrls.has(url))
|
|
48
|
+
candidates.add(url);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (candidates.size === 0)
|
|
52
|
+
return [];
|
|
53
|
+
return confirmJsContentType([...candidates], threads);
|
|
54
|
+
});
|
|
55
|
+
export default generic_webpackChunkPaths;
|
|
56
|
+
//# sourceMappingURL=generic_webpackChunkPaths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic_webpackChunkPaths.js","sourceRoot":"","sources":["../../../src/lazyLoad/generic/generic_webpackChunkPaths.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAExE;;;;;;;;;;;;GAYG;AACH,MAAM,yBAAyB,GAAG,yBAIb,EAAE,gEAHnB,SAAiB,EACjB,mBAAgC,IAAI,GAAG,EAAE,EACzC,UAAkB,CAAC;IAEnB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,CAAC;IAEzC,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAa,CAAC;IAC3F,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAE7E,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,MAAM,OAAO,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC/C,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACD,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;QAAC,WAAM,CAAC;YACL,SAAS;QACb,CAAC;QAED,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,CAAC,SAAS;YAAE,SAAS;QAEzB,KAAK,MAAM,GAAG,IAAI,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;YAC5D,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACxD,CAAC;IACL,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,OAAO,oBAAoB,CAAC,CAAC,GAAG,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;AAC1D,CAAC,CAAA,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
|
|
@@ -8,6 +8,10 @@ let json_urls = [];
|
|
|
8
8
|
let max_req_queue;
|
|
9
9
|
/** List of URLs which has been crawled */
|
|
10
10
|
let crawled_urls = [];
|
|
11
|
+
/** Global map of JS file content hash -> count of files seen with that hash (used by generic-tech stagnation detection) */
|
|
12
|
+
let js_file_hash_counts = new Map();
|
|
13
|
+
/** Total number of JS files whose content hash has been recorded */
|
|
14
|
+
let js_file_total_count = 0;
|
|
11
15
|
/**
|
|
12
16
|
* Gets the current scope configuration.
|
|
13
17
|
* @returns Array of domains in scope
|
|
@@ -108,4 +112,31 @@ export const addCrawledUrl = (url) => {
|
|
|
108
112
|
export const clearCrawledUrls = () => {
|
|
109
113
|
crawled_urls = [];
|
|
110
114
|
};
|
|
115
|
+
/**
|
|
116
|
+
* Records a JS file's content hash, incrementing both its per-hash count and the total count.
|
|
117
|
+
* Used by generic-tech stagnation detection to track how much discovered content is duplicate.
|
|
118
|
+
* @param hash - Content hash (e.g. sha256) of a discovered JS file
|
|
119
|
+
*/
|
|
120
|
+
export const recordJsFileHash = (hash) => {
|
|
121
|
+
var _a;
|
|
122
|
+
js_file_hash_counts.set(hash, ((_a = js_file_hash_counts.get(hash)) !== null && _a !== void 0 ? _a : 0) + 1);
|
|
123
|
+
js_file_total_count++;
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Gets the current map of JS file content hash -> count.
|
|
127
|
+
* @returns Map of content hash to occurrence count
|
|
128
|
+
*/
|
|
129
|
+
export const getJsFileHashCounts = () => js_file_hash_counts;
|
|
130
|
+
/**
|
|
131
|
+
* Gets the total number of JS files whose content hash has been recorded.
|
|
132
|
+
* @returns Total recorded JS file count
|
|
133
|
+
*/
|
|
134
|
+
export const getJsFileTotalCount = () => js_file_total_count;
|
|
135
|
+
/**
|
|
136
|
+
* Clears all recorded JS file content hashes and resets the total count.
|
|
137
|
+
*/
|
|
138
|
+
export const clearJsFileHashCounts = () => {
|
|
139
|
+
js_file_hash_counts = new Map();
|
|
140
|
+
js_file_total_count = 0;
|
|
141
|
+
};
|
|
111
142
|
//# sourceMappingURL=globals.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"globals.js","sourceRoot":"","sources":["../../src/lazyLoad/globals.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,IAAI,KAAK,GAAa,EAAE,CAAC;AACzB,qEAAqE;AACrE,IAAI,OAAO,GAAa,EAAE,CAAC;AAC3B,+DAA+D;AAC/D,IAAI,SAAS,GAAa,EAAE,CAAC;AAC7B,oDAAoD;AACpD,IAAI,aAAqB,CAAC;AAC1B,0CAA0C;AAC1C,IAAI,YAAY,GAAa,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"globals.js","sourceRoot":"","sources":["../../src/lazyLoad/globals.ts"],"names":[],"mappings":"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"}
|
package/build/lazyLoad/index.js
CHANGED
|
@@ -10,13 +10,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
var _a;
|
|
11
11
|
import chalk from "chalk";
|
|
12
12
|
import fs from "fs";
|
|
13
|
-
import frameworkDetect from "./techDetect/index.js";
|
|
14
|
-
import CONFIG from "../globalConfig.js";
|
|
13
|
+
import frameworkDetect, { getLastInterceptedUrls } from "./techDetect/index.js";
|
|
15
14
|
import _traverse from "@babel/traverse";
|
|
16
15
|
const traverse = ((_a = _traverse.default) !== null && _a !== void 0 ? _a : _traverse);
|
|
17
16
|
import { URL } from "url";
|
|
18
17
|
// Next.js
|
|
19
18
|
import NextJsCrawler from "./next_js/NextJsCrawler.js";
|
|
19
|
+
import next_serverActionIdScan from "./next_js/next_serverActionIdScan.js";
|
|
20
20
|
import { next_buildId_RSC } from "./next_js/next_buildId.js";
|
|
21
21
|
// Nuxt.js
|
|
22
22
|
import nuxt_getFromPageSource from "./nuxt_js/nuxt_getFromPageSource.js";
|
|
@@ -41,8 +41,9 @@ import react_getScriptTags from "./react/react_getScriptTags.js";
|
|
|
41
41
|
import react_webpackChunkPaths from "./react/react_webpackChunkPaths.js";
|
|
42
42
|
import react_sourcemapUrls from "./react/react_sourcemapUrls.js";
|
|
43
43
|
import react_followImports from "./react/react_followImports.js";
|
|
44
|
-
import downloadLoadedJs from "./downloadLoadedJsUtil.js";
|
|
45
44
|
import { DownloadQueue } from "./downloadQueue.js";
|
|
45
|
+
import generic_crawlPages from "./generic/generic_crawlPages.js";
|
|
46
|
+
import resolveGenericScope from "./generic/generic_resolveScope.js";
|
|
46
47
|
import path from "path";
|
|
47
48
|
import { join } from "path";
|
|
48
49
|
import { extractSourceMaps } from "../sourcemaps/index.js";
|
|
@@ -55,6 +56,8 @@ import { progressLog, progressWarn } from "../utility/progressLog.js";
|
|
|
55
56
|
import { resolveHostOutputDirectory } from "./outputPath.js";
|
|
56
57
|
import { withRequestSignal } from "../utility/makeReq.js";
|
|
57
58
|
import { resolveTargetInputs } from "../utility/targetInputs.js";
|
|
59
|
+
import { accumulateTechnique, createTechniqueRecorder } from "./researchUtils.js";
|
|
60
|
+
import { printMsg, MSG } from "../utility/printMsg.js";
|
|
58
61
|
/**
|
|
59
62
|
* Downloads the required JavaScript files for a given URL
|
|
60
63
|
* @param {string} url The URL to download the JS files from
|
|
@@ -67,7 +70,7 @@ import { resolveTargetInputs } from "../utility/targetInputs.js";
|
|
|
67
70
|
* @param {boolean} insecure If true, then disable SSL certificate verification
|
|
68
71
|
* @returns {Promise<void>} A Promise that resolves when the download is complete
|
|
69
72
|
*/
|
|
70
|
-
const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subsequentRequestsFlag_1, urlsFile_1, insecure_1, buildId_1, sourcemapDir_1, research_1, researchOutput_1, maxIterations_1, ...args_1) => __awaiter(void 0, [url_1, output_1, strictScope_1, inputScope_1, threads_1, subsequentRequestsFlag_1, urlsFile_1, insecure_1, buildId_1, sourcemapDir_1, research_1, researchOutput_1, maxIterations_1, ...args_1], void 0, function* (url, output, strictScope, inputScope, threads, subsequentRequestsFlag, urlsFile, insecure, buildId, sourcemapDir, research, researchOutput, maxIterations, maxJsSizeMb = 2, hardTimeoutMs = 30 * 60 * 1000, maxPageVisits = 200, includeMethods = [], excludeMethods = [], detectionTimeoutMs = 30 * 1000, cancellationSignal, isBatch = false) {
|
|
73
|
+
const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subsequentRequestsFlag_1, urlsFile_1, insecure_1, buildId_1, sourcemapDir_1, research_1, researchOutput_1, maxIterations_1, ...args_1) => __awaiter(void 0, [url_1, output_1, strictScope_1, inputScope_1, threads_1, subsequentRequestsFlag_1, urlsFile_1, insecure_1, buildId_1, sourcemapDir_1, research_1, researchOutput_1, maxIterations_1, ...args_1], void 0, function* (url, output, strictScope, inputScope, threads, subsequentRequestsFlag, urlsFile, insecure, buildId, sourcemapDir, research, researchOutput, maxIterations, maxJsSizeMb = 2, hardTimeoutMs = 30 * 60 * 1000, maxPageVisits = 200, includeMethods = [], excludeMethods = [], detectionTimeoutMs = 30 * 1000, cancellationSignal, isBatch = false, maxRedirects = 20, stringsEnabled = false, stringsMaxIterations = 5, stagnationTimeinMs = 0, stagnationPercentage = 80, stagnationMonitorMs = 60 * 1000, rscParamBruteforceLimit = 20) {
|
|
71
74
|
const resolvedTargets = resolveTargetInputs(url);
|
|
72
75
|
// Hoisted so the timeout handler can stop discovery and drain downloads.
|
|
73
76
|
let activeCrawler = null;
|
|
@@ -99,14 +102,14 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
99
102
|
if (cancellationSignal === null || cancellationSignal === void 0 ? void 0 : cancellationSignal.aborted)
|
|
100
103
|
requestCancellation();
|
|
101
104
|
const work = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
102
|
-
|
|
105
|
+
printMsg(MSG.Header, "[i] Loading 'Lazy Load' module");
|
|
103
106
|
if (globals.getDisableSandbox()) {
|
|
104
|
-
|
|
107
|
+
printMsg(MSG.Warn, "[!] Browser sandbox disabled");
|
|
105
108
|
}
|
|
106
109
|
globals.setInsecure(insecure);
|
|
107
110
|
if (insecure) {
|
|
108
111
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
109
|
-
|
|
112
|
+
printMsg(MSG.Warn, "[!] Running in insecure mode. SSL certificate verification disabled");
|
|
110
113
|
}
|
|
111
114
|
// if cache enabled, check if the cache file exists or not. If no, then create a new one
|
|
112
115
|
if (!globals.getDisableCache()) {
|
|
@@ -117,7 +120,7 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
117
120
|
for (const url of resolvedTargets.targets) {
|
|
118
121
|
if (hardTimeoutReached)
|
|
119
122
|
break;
|
|
120
|
-
|
|
123
|
+
printMsg(MSG.Header, `[i] Processing ${url}`);
|
|
121
124
|
lazyLoadGlobals.clearJsUrls();
|
|
122
125
|
lazyLoadGlobals.clearJsonUrls();
|
|
123
126
|
lazyLoadGlobals.clearCrawledUrls();
|
|
@@ -149,15 +152,15 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
149
152
|
activeDetectionController = null;
|
|
150
153
|
}
|
|
151
154
|
if (detectionTimedOut) {
|
|
152
|
-
|
|
155
|
+
printMsg(MSG.Warn, `[!] Framework detection timed out after ${detectionTimeoutMs}ms; treating as not detected`);
|
|
153
156
|
}
|
|
154
157
|
if (hardTimeoutReached)
|
|
155
158
|
break;
|
|
156
159
|
globals.setTech(tech ? tech.name : "");
|
|
157
160
|
if (tech) {
|
|
158
161
|
if (tech.name === "next") {
|
|
159
|
-
|
|
160
|
-
|
|
162
|
+
printMsg(MSG.Run, "[✓] Next.js detected");
|
|
163
|
+
printMsg(MSG.Warn, `Evidence: ${tech.evidence}`);
|
|
161
164
|
activeQueue = new DownloadQueue(output, threads, { alreadyBatchTargetRoot: isBatch });
|
|
162
165
|
const crawler = new NextJsCrawler({
|
|
163
166
|
url,
|
|
@@ -168,6 +171,7 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
168
171
|
research,
|
|
169
172
|
maxIterations,
|
|
170
173
|
maxPageVisits,
|
|
174
|
+
rscParamBruteforceLimit,
|
|
171
175
|
onUrlsDiscovered: (urls) => enqueue(activeQueue, urls),
|
|
172
176
|
includeMethods,
|
|
173
177
|
excludeMethods,
|
|
@@ -187,6 +191,14 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
187
191
|
return;
|
|
188
192
|
activeQueue.printSummary();
|
|
189
193
|
activeQueue = null;
|
|
194
|
+
if (shouldRunMethod("next_serverActionIdScan", includeMethods, excludeMethods)) {
|
|
195
|
+
const scanDir = resolveHostOutputDirectory(output, new URL(url).host, isBatch);
|
|
196
|
+
const scanResult = yield next_serverActionIdScan(scanDir);
|
|
197
|
+
if (scanResult.allActionIds.length > 0) {
|
|
198
|
+
printMsg(MSG.Run, `[✓] Found ${scanResult.allActionIds.length} Server Action ID(s) referenced in downloaded chunks (disclosure only — not invoked)`);
|
|
199
|
+
fs.writeFileSync(path.join(scanDir, "server_action_ids.json"), JSON.stringify(scanResult, null, 4));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
190
202
|
if (buildId) {
|
|
191
203
|
// get the buildId
|
|
192
204
|
// the directory is the output <output>/<host.replace(":", "_")>/___subsequent_requests
|
|
@@ -195,7 +207,7 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
195
207
|
if (hardTimeoutReached)
|
|
196
208
|
return;
|
|
197
209
|
if (buildId) {
|
|
198
|
-
|
|
210
|
+
printMsg(MSG.Header, "[+] Found buildId: " + buildId);
|
|
199
211
|
// now, write it to a file
|
|
200
212
|
fs.writeFileSync(path.join(targetOutputDir, "BUILD_ID"), buildId);
|
|
201
213
|
}
|
|
@@ -204,75 +216,97 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
204
216
|
if (research) {
|
|
205
217
|
// prettify the JSON and write
|
|
206
218
|
fs.writeFileSync(researchOutput, JSON.stringify(crawler.techniqueEfficiencyMapping, null, 4));
|
|
207
|
-
|
|
219
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
208
220
|
}
|
|
209
221
|
// extract the source maps
|
|
210
222
|
yield extractSourceMaps(output, join(output, sourcemapDir));
|
|
211
223
|
}
|
|
212
224
|
else if (tech.name === "vue") {
|
|
213
|
-
|
|
214
|
-
|
|
225
|
+
printMsg(MSG.Run, "[✓] Vue.js detected");
|
|
226
|
+
printMsg(MSG.Warn, `Evidence: ${tech.evidence}`);
|
|
215
227
|
activeQueue = new DownloadQueue(output, threads, { alreadyBatchTargetRoot: isBatch });
|
|
216
228
|
const queue = activeQueue;
|
|
217
229
|
const onFilesDiscovered = (files) => enqueue(queue, files);
|
|
230
|
+
const vueResearchMap = {};
|
|
231
|
+
const vueOnTechnique = research ? createTechniqueRecorder(vueResearchMap) : undefined;
|
|
218
232
|
// run the full discovery pipeline against the entry URL
|
|
219
|
-
const { clientSidePaths } = yield vue_discoverJsFiles(url, maxJsSizeMb, onFilesDiscovered, includeMethods, excludeMethods, threads);
|
|
233
|
+
const { clientSidePaths } = yield vue_discoverJsFiles(url, maxJsSizeMb, onFilesDiscovered, includeMethods, excludeMethods, threads, true, true, vueOnTechnique);
|
|
220
234
|
if (hardTimeoutReached)
|
|
221
235
|
return;
|
|
222
236
|
// recurse the same pipeline through every client-side path we found
|
|
223
|
-
yield vue_recursiveClientSidePathDownload(clientSidePaths, threads, maxJsSizeMb, onFilesDiscovered, includeMethods, excludeMethods);
|
|
237
|
+
yield vue_recursiveClientSidePathDownload(clientSidePaths, threads, maxJsSizeMb, onFilesDiscovered, includeMethods, excludeMethods, vueOnTechnique);
|
|
224
238
|
if (hardTimeoutReached)
|
|
225
239
|
return;
|
|
226
240
|
yield queue.drain();
|
|
227
241
|
if (hardTimeoutReached)
|
|
228
242
|
return;
|
|
229
243
|
queue.printSummary();
|
|
244
|
+
if (research) {
|
|
245
|
+
fs.writeFileSync(researchOutput, JSON.stringify(vueResearchMap, null, 4));
|
|
246
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
247
|
+
}
|
|
230
248
|
// extract the source maps
|
|
231
249
|
yield extractSourceMaps(output, join(output, sourcemapDir));
|
|
232
250
|
}
|
|
233
251
|
else if (tech.name === "nuxt") {
|
|
234
|
-
|
|
235
|
-
|
|
252
|
+
printMsg(MSG.Run, "[✓] Nuxt.js detected");
|
|
253
|
+
printMsg(MSG.Warn, `Evidence: ${tech.evidence}`);
|
|
236
254
|
const queue = new DownloadQueue(output, threads, { alreadyBatchTargetRoot: isBatch });
|
|
237
255
|
activeQueue = queue;
|
|
256
|
+
const nuxtResearchMap = {};
|
|
238
257
|
// find the files from the page source
|
|
239
258
|
const jsFilesFromPageSource = shouldRunMethod("nuxt_getFromPageSource", includeMethods, excludeMethods)
|
|
240
259
|
? yield nuxt_getFromPageSource(url)
|
|
241
260
|
: [];
|
|
242
261
|
enqueue(queue, jsFilesFromPageSource);
|
|
262
|
+
if (research)
|
|
263
|
+
accumulateTechnique(nuxtResearchMap, "nuxt_getFromPageSource", jsFilesFromPageSource);
|
|
243
264
|
const jsFilesFromStringAnalysis = shouldRunMethod("nuxt_stringAnalysisJSFiles", includeMethods, excludeMethods)
|
|
244
265
|
? yield nuxt_stringAnalysisJSFiles(url, threads)
|
|
245
266
|
: [];
|
|
246
267
|
enqueue(queue, jsFilesFromStringAnalysis);
|
|
268
|
+
if (research)
|
|
269
|
+
accumulateTechnique(nuxtResearchMap, "nuxt_stringAnalysisJSFiles", jsFilesFromStringAnalysis);
|
|
247
270
|
const firstBatch = [...new Set([...jsFilesFromPageSource, ...jsFilesFromStringAnalysis])];
|
|
248
|
-
|
|
271
|
+
const jsFilesFromAST = [];
|
|
249
272
|
if (shouldRunMethod("nuxt_astParse", includeMethods, excludeMethods)) {
|
|
250
|
-
|
|
273
|
+
printMsg(MSG.Header, "[i] Analyzing functions in the files found");
|
|
251
274
|
for (const jsFile of firstBatch) {
|
|
252
275
|
jsFilesFromAST.push(...(yield nuxt_astParse(jsFile)));
|
|
253
276
|
}
|
|
254
277
|
}
|
|
255
278
|
enqueue(queue, jsFilesFromAST);
|
|
279
|
+
if (research)
|
|
280
|
+
accumulateTechnique(nuxtResearchMap, "nuxt_astParse", jsFilesFromAST);
|
|
256
281
|
enqueue(queue, lazyLoadGlobals.getJsUrls());
|
|
257
282
|
const buildsManifestFiles = shouldRunMethod("nuxt_getBuildsManifest", includeMethods, excludeMethods)
|
|
258
283
|
? yield nuxt_getBuildsManifest(url)
|
|
259
284
|
: [];
|
|
260
285
|
enqueue(queue, buildsManifestFiles);
|
|
286
|
+
if (research)
|
|
287
|
+
accumulateTechnique(nuxtResearchMap, "nuxt_getBuildsManifest", buildsManifestFiles);
|
|
261
288
|
yield queue.drain();
|
|
262
289
|
if (hardTimeoutReached)
|
|
263
290
|
return;
|
|
264
291
|
queue.printSummary();
|
|
292
|
+
if (research) {
|
|
293
|
+
fs.writeFileSync(researchOutput, JSON.stringify(nuxtResearchMap, null, 4));
|
|
294
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
295
|
+
}
|
|
265
296
|
}
|
|
266
297
|
else if (tech.name === "svelte") {
|
|
267
|
-
|
|
268
|
-
|
|
298
|
+
printMsg(MSG.Run, "[✓] Svelte detected");
|
|
299
|
+
printMsg(MSG.Warn, `Evidence: ${tech.evidence}`);
|
|
269
300
|
const queue = new DownloadQueue(output, threads, { alreadyBatchTargetRoot: isBatch });
|
|
270
301
|
activeQueue = queue;
|
|
302
|
+
const svelteResearchMap = {};
|
|
271
303
|
// find the files from the page source
|
|
272
304
|
const jsFilesFromPageSource = shouldRunMethod("svelte_getFromPageSource", includeMethods, excludeMethods)
|
|
273
305
|
? yield svelte_getFromPageSource(url)
|
|
274
306
|
: [];
|
|
275
307
|
enqueue(queue, jsFilesFromPageSource);
|
|
308
|
+
if (research)
|
|
309
|
+
accumulateTechnique(svelteResearchMap, "svelte_getFromPageSource", jsFilesFromPageSource);
|
|
276
310
|
// probe /<appDir>/version.json — SvelteKit serves this for the `updated` store
|
|
277
311
|
// but never references it from HTML or JS, so it is invisible to all other steps
|
|
278
312
|
const appDir = (() => {
|
|
@@ -292,6 +326,8 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
292
326
|
if (versionJsonFiles.length > 0) {
|
|
293
327
|
enqueue(queue, versionJsonFiles);
|
|
294
328
|
}
|
|
329
|
+
if (research)
|
|
330
|
+
accumulateTechnique(svelteResearchMap, "svelte_getVersionJson", versionJsonFiles);
|
|
295
331
|
// analyze the strings now
|
|
296
332
|
let jsFilesFromStringAnalysis = [];
|
|
297
333
|
let mapFilesFromStringAnalysis = [];
|
|
@@ -303,16 +339,23 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
303
339
|
if (mapFilesFromStringAnalysis.length > 0) {
|
|
304
340
|
enqueue(queue, mapFilesFromStringAnalysis);
|
|
305
341
|
}
|
|
342
|
+
if (research) {
|
|
343
|
+
accumulateTechnique(svelteResearchMap, "svelte_stringAnalysisJSFiles", jsFilesFromStringAnalysis);
|
|
344
|
+
accumulateTechnique(svelteResearchMap, "svelte_stringAnalysisJSFiles", mapFilesFromStringAnalysis);
|
|
345
|
+
}
|
|
306
346
|
}
|
|
307
347
|
// recursively follow ESM static imports (import ... from "./chunk.js")
|
|
348
|
+
// svelte_followImports reuses react_followImports — tracked under react_followImports key
|
|
308
349
|
const visited = new Set();
|
|
309
350
|
let toFollow = [...new Set([...jsFilesFromPageSource, ...jsFilesFromStringAnalysis])];
|
|
310
351
|
while (toFollow.length > 0) {
|
|
311
352
|
const newFiles = yield react_followImports(toFollow, maxJsSizeMb, url, visited, threads);
|
|
312
353
|
if (newFiles.length === 0)
|
|
313
354
|
break;
|
|
314
|
-
|
|
355
|
+
printMsg(MSG.Run, `[✓] Discovered ${newFiles.length} more JS file(s) via imports`);
|
|
315
356
|
enqueue(queue, newFiles);
|
|
357
|
+
if (research)
|
|
358
|
+
accumulateTechnique(svelteResearchMap, "react_followImports", newFiles);
|
|
316
359
|
toFollow = newFiles;
|
|
317
360
|
}
|
|
318
361
|
// crawl same-origin HTML pages found via <a href> and <link href>,
|
|
@@ -320,6 +363,8 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
320
363
|
const jsFilesFromPageCrawl = shouldRunMethod("svelte_recursivePageCrawl", includeMethods, excludeMethods)
|
|
321
364
|
? yield svelte_recursivePageCrawl(url, maxJsSizeMb, (files) => enqueue(queue, files))
|
|
322
365
|
: [];
|
|
366
|
+
if (research)
|
|
367
|
+
accumulateTechnique(svelteResearchMap, "svelte_recursivePageCrawl", jsFilesFromPageCrawl);
|
|
323
368
|
// Svelte/Astro apps use client-side routing — the home page rarely has
|
|
324
369
|
// <a href> links in its server-rendered HTML. Scan downloaded JS for
|
|
325
370
|
// embedded page path strings (e.g. "/admin", "/debug") and visit each
|
|
@@ -331,6 +376,8 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
331
376
|
if (jsFilesFromPathScan.length > 0) {
|
|
332
377
|
enqueue(queue, jsFilesFromPathScan);
|
|
333
378
|
}
|
|
379
|
+
if (research)
|
|
380
|
+
accumulateTechnique(svelteResearchMap, "svelte_discoverPagesFromJs", jsFilesFromPathScan);
|
|
334
381
|
// run string analysis once more to catch JS files discovered during page crawl
|
|
335
382
|
if ((jsFilesFromPageCrawl.length > 0 || jsFilesFromPathScan.length > 0) &&
|
|
336
383
|
shouldRunMethod("svelte_stringAnalysisJSFiles", includeMethods, excludeMethods)) {
|
|
@@ -339,23 +386,34 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
339
386
|
if (mapFilesFromStringAnalysis2.length > 0) {
|
|
340
387
|
enqueue(queue, mapFilesFromStringAnalysis2);
|
|
341
388
|
}
|
|
389
|
+
if (research) {
|
|
390
|
+
accumulateTechnique(svelteResearchMap, "svelte_stringAnalysisJSFiles", jsFilesFromStringAnalysis2);
|
|
391
|
+
accumulateTechnique(svelteResearchMap, "svelte_stringAnalysisJSFiles", mapFilesFromStringAnalysis2);
|
|
392
|
+
}
|
|
342
393
|
}
|
|
343
394
|
yield queue.drain();
|
|
344
395
|
if (hardTimeoutReached)
|
|
345
396
|
return;
|
|
346
397
|
queue.printSummary();
|
|
398
|
+
if (research) {
|
|
399
|
+
fs.writeFileSync(researchOutput, JSON.stringify(svelteResearchMap, null, 4));
|
|
400
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
401
|
+
}
|
|
347
402
|
yield extractSourceMaps(output, join(output, sourcemapDir));
|
|
348
403
|
}
|
|
349
404
|
else if (tech.name === "angular") {
|
|
350
|
-
|
|
351
|
-
|
|
405
|
+
printMsg(MSG.Run, "[✓] Angular detected");
|
|
406
|
+
printMsg(MSG.Warn, `Evidence: ${tech.evidence}`);
|
|
352
407
|
const queue = new DownloadQueue(output, threads, { alreadyBatchTargetRoot: isBatch });
|
|
353
408
|
activeQueue = queue;
|
|
409
|
+
const angularResearchMap = {};
|
|
354
410
|
// find the files from the page source
|
|
355
411
|
const jsFilesFromPageSource = shouldRunMethod("angular_getFromPageSource", includeMethods, excludeMethods)
|
|
356
412
|
? yield angular_getFromPageSource(url)
|
|
357
413
|
: [];
|
|
358
414
|
enqueue(queue, jsFilesFromPageSource);
|
|
415
|
+
if (research)
|
|
416
|
+
accumulateTechnique(angularResearchMap, "angular_getFromPageSource", jsFilesFromPageSource);
|
|
359
417
|
// files using the main.js
|
|
360
418
|
if (shouldRunMethod("angular_getFromMainJs", includeMethods, excludeMethods)) {
|
|
361
419
|
let mainJsUrl;
|
|
@@ -368,10 +426,14 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
368
426
|
if (mainJsUrl) {
|
|
369
427
|
const jsFilesFromMainJs = yield angular_getFromMainJs(mainJsUrl);
|
|
370
428
|
enqueue(queue, jsFilesFromMainJs);
|
|
429
|
+
if (research)
|
|
430
|
+
accumulateTechnique(angularResearchMap, "angular_getFromMainJs", jsFilesFromMainJs);
|
|
371
431
|
// recursively follow chunk-to-chunk imports beyond the first hop
|
|
372
432
|
if (shouldRunMethod("angular_recursiveChunkImports", includeMethods, excludeMethods)) {
|
|
373
433
|
const transitiveChunks = yield angular_recursiveChunkImports(jsFilesFromMainJs, threads);
|
|
374
434
|
enqueue(queue, transitiveChunks);
|
|
435
|
+
if (research)
|
|
436
|
+
accumulateTechnique(angularResearchMap, "angular_recursiveChunkImports", transitiveChunks);
|
|
375
437
|
}
|
|
376
438
|
}
|
|
377
439
|
}
|
|
@@ -379,16 +441,21 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
379
441
|
if (hardTimeoutReached)
|
|
380
442
|
return;
|
|
381
443
|
queue.printSummary();
|
|
444
|
+
if (research) {
|
|
445
|
+
fs.writeFileSync(researchOutput, JSON.stringify(angularResearchMap, null, 4));
|
|
446
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
447
|
+
}
|
|
382
448
|
}
|
|
383
449
|
else if (tech.name === "react") {
|
|
384
|
-
|
|
385
|
-
|
|
450
|
+
printMsg(MSG.Run, "[✓] React detected");
|
|
451
|
+
printMsg(MSG.Warn, `Evidence: ${tech.evidence}`);
|
|
386
452
|
const queue = new DownloadQueue(output, threads, {
|
|
387
453
|
compactOutput: true,
|
|
388
454
|
onProgress: (progress) => activeDownloadProgress === null || activeDownloadProgress === void 0 ? void 0 : activeDownloadProgress.update(progress),
|
|
389
455
|
alreadyBatchTargetRoot: isBatch,
|
|
390
456
|
});
|
|
391
457
|
activeQueue = queue;
|
|
458
|
+
const reactResearchMap = {};
|
|
392
459
|
// Seed: <script src> tags + <link rel="modulepreload"> (Vite vendor chunks)
|
|
393
460
|
const jsFilesFromPageSource = shouldRunMethod("react_getScriptTags", includeMethods, excludeMethods)
|
|
394
461
|
? yield react_getScriptTags(url, maxJsSizeMb, output, isBatch)
|
|
@@ -396,6 +463,8 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
396
463
|
if (hardTimeoutReached)
|
|
397
464
|
return;
|
|
398
465
|
enqueue(queue, jsFilesFromPageSource);
|
|
466
|
+
if (research)
|
|
467
|
+
accumulateTechnique(reactResearchMap, "react_getScriptTags", jsFilesFromPageSource);
|
|
399
468
|
// webpack-style chunk path builders (CRA / custom webpack configs)
|
|
400
469
|
const webpackChunkPaths = shouldRunMethod("react_webpackChunkPaths", includeMethods, excludeMethods)
|
|
401
470
|
? yield react_webpackChunkPaths(url, maxJsSizeMb, jsFilesFromPageSource, threads)
|
|
@@ -406,6 +475,8 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
406
475
|
activeDownloadProgress.update(queue.progress);
|
|
407
476
|
try {
|
|
408
477
|
enqueue(queue, webpackChunkPaths);
|
|
478
|
+
if (research)
|
|
479
|
+
accumulateTechnique(reactResearchMap, "react_webpackChunkPaths", webpackChunkPaths);
|
|
409
480
|
// Recursively follow ESM imports and Vite __vite_mapDeps references.
|
|
410
481
|
// visited starts empty so the seed files are fetched and parsed in the first round.
|
|
411
482
|
const visited = new Set();
|
|
@@ -419,6 +490,8 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
419
490
|
break;
|
|
420
491
|
progressLog(chalk.green(`[✓] Discovered ${newFiles.length} more JS file(s) via imports`));
|
|
421
492
|
enqueue(queue, newFiles);
|
|
493
|
+
if (research)
|
|
494
|
+
accumulateTechnique(reactResearchMap, "react_followImports", newFiles);
|
|
422
495
|
toFollow = newFiles;
|
|
423
496
|
}
|
|
424
497
|
}
|
|
@@ -427,6 +500,8 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
427
500
|
shouldRunMethod("react_sourcemapUrls", includeMethods, excludeMethods)) {
|
|
428
501
|
const sourcemapUrls = yield react_sourcemapUrls([...visited], threads);
|
|
429
502
|
enqueue(queue, sourcemapUrls);
|
|
503
|
+
if (research)
|
|
504
|
+
accumulateTechnique(reactResearchMap, "react_sourcemapUrls", sourcemapUrls);
|
|
430
505
|
}
|
|
431
506
|
yield queue.drain();
|
|
432
507
|
}
|
|
@@ -437,50 +512,38 @@ const lazyLoad = (url_1, output_1, strictScope_1, inputScope_1, threads_1, subse
|
|
|
437
512
|
if (hardTimeoutReached)
|
|
438
513
|
return;
|
|
439
514
|
queue.printSummary();
|
|
515
|
+
if (research) {
|
|
516
|
+
fs.writeFileSync(researchOutput, JSON.stringify(reactResearchMap, null, 4));
|
|
517
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
518
|
+
}
|
|
440
519
|
yield extractSourceMaps(output, join(output, sourcemapDir));
|
|
441
520
|
}
|
|
442
521
|
}
|
|
443
522
|
else {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
523
|
+
printMsg(MSG.Warn, "[i] Framework not detected — falling back to generic JS extraction");
|
|
524
|
+
globals.setTech("generic");
|
|
525
|
+
// If the caller didn't customize scope (still the "*" default) and isn't
|
|
526
|
+
// using --strict-scope, default the generic crawl's scope to the origin
|
|
527
|
+
// reached after following redirects, rather than crawling the whole web.
|
|
528
|
+
if (!strictScope && inputScope.length === 1 && inputScope[0] === "*") {
|
|
529
|
+
const resolvedScope = yield resolveGenericScope(url, maxRedirects);
|
|
530
|
+
lazyLoadGlobals.setScope(resolvedScope);
|
|
531
|
+
}
|
|
532
|
+
// Downloads JS incrementally as pages are crawled (see generic_crawlPages.ts) —
|
|
533
|
+
// the returned list is only used for the final summary count.
|
|
534
|
+
const genericResearchMap = {};
|
|
535
|
+
const allUrls = yield generic_crawlPages(url, maxJsSizeMb, output, maxPageVisits, threads, research ? genericResearchMap : undefined, stringsEnabled, stringsMaxIterations, getLastInterceptedUrls(), stagnationTimeinMs, stagnationPercentage, stagnationMonitorMs);
|
|
448
536
|
if (hardTimeoutReached)
|
|
449
537
|
return;
|
|
450
|
-
if (
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
secondChanceTech = "next";
|
|
460
|
-
secondChanceEvidence = u;
|
|
461
|
-
break;
|
|
462
|
-
}
|
|
463
|
-
if (u.includes("/_nuxt/")) {
|
|
464
|
-
secondChanceTech = "nuxt";
|
|
465
|
-
secondChanceEvidence = u;
|
|
466
|
-
break;
|
|
467
|
-
}
|
|
468
|
-
if (u.includes("/_app/immutable/")) {
|
|
469
|
-
secondChanceTech = "svelte";
|
|
470
|
-
secondChanceEvidence = u;
|
|
471
|
-
break;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
if (secondChanceTech) {
|
|
475
|
-
console.log(chalk.green(`[✓] Detected ${secondChanceTech} from downloaded file paths (evidence: ${secondChanceEvidence})`));
|
|
476
|
-
globals.setTech(secondChanceTech);
|
|
477
|
-
}
|
|
478
|
-
const queue = new DownloadQueue(output, threads, { alreadyBatchTargetRoot: isBatch });
|
|
479
|
-
enqueue(queue, js_urls);
|
|
480
|
-
yield queue.drain();
|
|
481
|
-
if (hardTimeoutReached)
|
|
482
|
-
return;
|
|
483
|
-
queue.printSummary();
|
|
538
|
+
if (allUrls.length > 0) {
|
|
539
|
+
printMsg(MSG.Run, `[✓] Found ${allUrls.length} JS file(s)`);
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
printMsg(MSG.Warn, "[i] No JS files discovered");
|
|
543
|
+
}
|
|
544
|
+
if (research) {
|
|
545
|
+
fs.writeFileSync(researchOutput, JSON.stringify(genericResearchMap, null, 4));
|
|
546
|
+
printMsg(MSG.Run, "[✓] Research mode enabled. Technique efficiency written to " + researchOutput);
|
|
484
547
|
}
|
|
485
548
|
}
|
|
486
549
|
}
|