@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
package/build/run/index.js
CHANGED
|
@@ -19,10 +19,11 @@ import report from "../report/index.js";
|
|
|
19
19
|
import refactor from "../refactor/index.js";
|
|
20
20
|
import initGlobalReportDb from "../report/utility/initGlobalReportDb.js";
|
|
21
21
|
import mergeDomainIntoGlobalDb from "../report/utility/mergeDomainIntoGlobalDb.js";
|
|
22
|
-
import { clearJsUrls, clearJsonUrls, getJsUrls } from "../lazyLoad/globals.js";
|
|
22
|
+
import { clearJsUrls, clearJsonUrls, clearJsFileHashCounts, getJsUrls } from "../lazyLoad/globals.js";
|
|
23
23
|
import path from "path";
|
|
24
24
|
import { installSigintHandler, removeSigintHandler, getSkipStepPromise, resetSkipStep, shouldSkipTarget, resetSkipTarget, waitForPendingInterrupt, } from "./interruptHandler.js";
|
|
25
25
|
import { detectBundler } from "./bundler-detect.js";
|
|
26
|
+
import { printMsg, MSG, setHeaderListener } from "../utility/printMsg.js";
|
|
26
27
|
import configureProxy from "../utility/configureProxy.js";
|
|
27
28
|
import { getOxylabsFallbackConfiguration } from "../proxy/oxylabsFallback.js";
|
|
28
29
|
import { probeFeasibility } from "../proxy/checkFeasibility.js";
|
|
@@ -31,6 +32,8 @@ import { resolveHostOutputDirectory } from "../lazyLoad/outputPath.js";
|
|
|
31
32
|
import { awaitCancellableStep } from "./cancellableStep.js";
|
|
32
33
|
import { resolveTargetInputs } from "../utility/targetInputs.js";
|
|
33
34
|
import { clearRunOutputDirectory, getBatchTargetDirectoryName, reserveRunOutputDirectory } from "./outputDirectory.js";
|
|
35
|
+
import { startDashboardServer } from "./dashboard/server.js";
|
|
36
|
+
import * as dashboardState from "./dashboard/state.js";
|
|
34
37
|
/**
|
|
35
38
|
* Determines the directory for a Content Delivery Network (CDN) if used by the target.
|
|
36
39
|
*
|
|
@@ -78,10 +81,11 @@ const getCdnDir = (host, outputDir, isBatch) => __awaiter(void 0, void 0, void 0
|
|
|
78
81
|
const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_1) => __awaiter(void 0, [url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_1], void 0, function* (url, outputDir, workingDir, cmd, isBatch, includeMethods = [], excludeMethods = []) {
|
|
79
82
|
var _a, _b, _c, _d;
|
|
80
83
|
const targetHost = new URL(url).host;
|
|
81
|
-
|
|
84
|
+
printMsg(MSG.Run, `[+] Starting analysis for ${url}...`);
|
|
82
85
|
if (isBatch) {
|
|
83
86
|
clearJsUrls();
|
|
84
87
|
clearJsonUrls();
|
|
88
|
+
clearJsFileHashCounts();
|
|
85
89
|
globalsUtil.clearOpenapiOutput();
|
|
86
90
|
}
|
|
87
91
|
if (cmd.proxyWafFallback && cmd._proxyConfigured) {
|
|
@@ -92,39 +96,39 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
92
96
|
outcome = yield probeFeasibility(resolved, url);
|
|
93
97
|
}
|
|
94
98
|
catch (error) {
|
|
95
|
-
|
|
99
|
+
printMsg(MSG.Err, `[!] Proxy WAF fallback check failed: ${error}. ${isBatch ? "Skipping this target." : "Quitting."}`);
|
|
96
100
|
if (isBatch)
|
|
97
101
|
return;
|
|
98
102
|
process.exit(29);
|
|
99
103
|
}
|
|
100
|
-
|
|
104
|
+
printMsg(outcome.code === 0 ? MSG.Run : MSG.Warn, outcome.message);
|
|
101
105
|
if (outcome.code === 27) {
|
|
102
106
|
// no firewall detected without a proxy - don't use it for this target
|
|
103
107
|
globalsUtil.setUseProxy(false);
|
|
104
108
|
}
|
|
105
109
|
else if (outcome.code === 28) {
|
|
106
|
-
|
|
110
|
+
printMsg(MSG.Err, `[!] Proxy could not bypass the firewall for this target. ${isBatch ? "Skipping this target." : "Quitting."}`);
|
|
107
111
|
if (isBatch)
|
|
108
112
|
return;
|
|
109
113
|
process.exit(29);
|
|
110
114
|
}
|
|
111
115
|
// outcome.code === 0: firewall present, proxy bypasses it - keep using the proxy
|
|
112
116
|
}
|
|
113
|
-
|
|
117
|
+
printMsg(MSG.Header, "[1/8] Running lazyload to download JavaScript files...");
|
|
114
118
|
resetSkipStep();
|
|
115
|
-
yield awaitCancellableStep((signal) => lazyLoad(url, outputDir, cmd.strictScope, cmd.scope.split(","), cmd.threads, false, "", cmd.insecure, false, cmd.sourcemapDir, cmd.research, cmd.researchOutput, Number(cmd.maxIterations), Number(cmd.maxJsSize), Number(cmd.lazyloadTimeout) * 60 * 1000, Number(cmd.maxPages), includeMethods, excludeMethods, Number(cmd.detectionTimeout) * 1000, signal, isBatch), getSkipStepPromise());
|
|
116
|
-
|
|
119
|
+
yield awaitCancellableStep((signal) => lazyLoad(url, outputDir, cmd.strictScope, cmd.scope.split(","), cmd.threads, false, "", cmd.insecure, false, cmd.sourcemapDir, cmd.research, cmd.researchOutput, Number(cmd.maxIterations), Number(cmd.maxJsSize), Number(cmd.lazyloadTimeout) * 60 * 1000, Number(cmd.maxPages), includeMethods, excludeMethods, Number(cmd.detectionTimeout) * 1000, signal, isBatch, Number(cmd.maxRedirects), cmd.strings, Number(cmd.stringsMaxIterations), Number(cmd.stagnationTimein) * 60 * 1000, Number(cmd.stagnationPercentage), Number(cmd.stagnationMonitor) * 60 * 1000, Number(cmd.rscParamBruteforceLimit)), getSkipStepPromise());
|
|
120
|
+
printMsg(MSG.Run, "[+] Lazyload complete.");
|
|
117
121
|
if (shouldSkipTarget())
|
|
118
122
|
return;
|
|
119
123
|
if (globalsUtil.getTech() === "") {
|
|
120
|
-
|
|
124
|
+
printMsg(MSG.Err, `[!] Technology not detected. ${isBatch ? "Skipping this target." : "Quitting."}`);
|
|
121
125
|
if (isBatch) {
|
|
122
126
|
return;
|
|
123
127
|
}
|
|
124
128
|
process.exit(10);
|
|
125
129
|
}
|
|
126
130
|
if (!["next", "vue", "nuxt", "react", "svelte", "angular"].includes(globalsUtil.getTech())) {
|
|
127
|
-
|
|
131
|
+
printMsg(MSG.Warn, `[!] The tool supports Next.JS, Vue.JS, Nuxt.JS, React, Svelte/Astro, and Angular in the run module. For ${globalsUtil.getTech()}, only downloading JS files is supported`);
|
|
128
132
|
return;
|
|
129
133
|
}
|
|
130
134
|
// Capture the tech here — subsequent lazyload passes (steps 3, 4.5) re-run framework
|
|
@@ -140,7 +144,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
140
144
|
const reportDbFile = isBatch ? `${workingDir}/js-recon.db` : "js-recon.db";
|
|
141
145
|
const reportFile = isBatch ? `${workingDir}/report` : "report";
|
|
142
146
|
const endpointsFile = isBatch ? `${workingDir}/endpoints` : "endpoints";
|
|
143
|
-
|
|
147
|
+
printMsg(MSG.Header, "[2/4] Running map to find functions and API calls...");
|
|
144
148
|
globalsUtil.setOpenapi(true);
|
|
145
149
|
if (isBatch) {
|
|
146
150
|
globalsUtil.setOpenapiOutputFile(openapiFile);
|
|
@@ -155,40 +159,39 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
155
159
|
map(outputDir, mappedFileReact, ["json"], "react", false, false, cmd.command || []),
|
|
156
160
|
getSkipStepPromise(),
|
|
157
161
|
]);
|
|
158
|
-
|
|
162
|
+
printMsg(MSG.Run, "[+] Map complete.");
|
|
159
163
|
if (shouldSkipTarget())
|
|
160
164
|
return;
|
|
161
|
-
|
|
165
|
+
printMsg(MSG.Header, "[3/4] Running analyze...");
|
|
162
166
|
resetSkipStep();
|
|
163
|
-
// @ts-ignore
|
|
164
167
|
yield Promise.race([
|
|
165
|
-
analyze(cmd.rules || "", mappedJsonFileReact, "react", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
|
|
168
|
+
analyze(cmd.rules || "", mappedJsonFileReact, "react", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck, false, false),
|
|
166
169
|
getSkipStepPromise(),
|
|
167
170
|
]);
|
|
168
|
-
|
|
171
|
+
printMsg(MSG.Run, "[+] Analyze complete.");
|
|
169
172
|
if (shouldSkipTarget())
|
|
170
173
|
return;
|
|
171
|
-
|
|
174
|
+
printMsg(MSG.Header, "[4/4] Running report module...");
|
|
172
175
|
const endpointsJson = `${endpointsFile}.json`;
|
|
173
176
|
if (!fs.existsSync(endpointsJson)) {
|
|
174
177
|
fs.writeFileSync(endpointsJson, "[]");
|
|
175
178
|
}
|
|
176
179
|
resetSkipStep();
|
|
177
180
|
yield Promise.race([
|
|
178
|
-
report(reportDbFile, mappedJsonFileReact, analyzeFile, endpointsJson, openapiFile, reportFile),
|
|
181
|
+
report(reportDbFile, mappedJsonFileReact, analyzeFile, endpointsJson, openapiFile, reportFile, cmd.sj, cmd.sjBin, cmd.sjArgs),
|
|
179
182
|
getSkipStepPromise(),
|
|
180
183
|
]);
|
|
181
|
-
|
|
184
|
+
printMsg(MSG.Run, "[+] Report complete.");
|
|
182
185
|
if (shouldSkipTarget())
|
|
183
186
|
return;
|
|
184
187
|
if (!cmd.disableRefactor) {
|
|
185
|
-
|
|
188
|
+
printMsg(MSG.Header, "[*] Detecting bundler via CS-MAST-S for refactor...");
|
|
186
189
|
const detectedBundlerTechReact = yield detectBundler(mappedJsonFileReact, "react", Number((_a = cmd.csMastTechDetectThreshold) !== null && _a !== void 0 ? _a : 50));
|
|
187
190
|
if (detectedBundlerTechReact) {
|
|
188
191
|
const refactorOutputDirReact = isBatch ? `${workingDir}/refactored` : "refactored";
|
|
189
192
|
if (fs.existsSync(refactorOutputDirReact))
|
|
190
193
|
fs.rmSync(refactorOutputDirReact, { recursive: true });
|
|
191
|
-
|
|
194
|
+
printMsg(MSG.Header, `[*] Running refactor (${detectedBundlerTechReact})...`);
|
|
192
195
|
// Vendor chunks may have been downloaded under a different host than the target
|
|
193
196
|
// (CDN) — resolve the assets dir from an actual downloaded JS URL's host instead
|
|
194
197
|
// of always assuming targetHost, mirroring getCdnDir's approach for the map step.
|
|
@@ -207,16 +210,16 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
207
210
|
]);
|
|
208
211
|
if (shouldSkipTarget())
|
|
209
212
|
return;
|
|
210
|
-
|
|
213
|
+
printMsg(MSG.Run, "[+] Refactor complete.");
|
|
211
214
|
}
|
|
212
215
|
else {
|
|
213
|
-
|
|
216
|
+
printMsg(MSG.Warn, "[!] Bundler not detected via CS-MAST-S, skipping refactor.");
|
|
214
217
|
}
|
|
215
218
|
}
|
|
216
219
|
else {
|
|
217
|
-
|
|
220
|
+
printMsg(MSG.Warn, "[!] Refactor step disabled via --disable-refactor, skipping.");
|
|
218
221
|
}
|
|
219
|
-
|
|
222
|
+
printMsg(MSG.Run, `[+] Analysis complete for ${url}.`);
|
|
220
223
|
return;
|
|
221
224
|
}
|
|
222
225
|
if (detectedTech === "vue") {
|
|
@@ -230,7 +233,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
230
233
|
const reportDbFile = isBatch ? `${workingDir}/js-recon.db` : "js-recon.db";
|
|
231
234
|
const reportFile = isBatch ? `${workingDir}/report` : "report";
|
|
232
235
|
const endpointsFile = isBatch ? `${workingDir}/endpoints` : "endpoints";
|
|
233
|
-
|
|
236
|
+
printMsg(MSG.Header, "[2/4] Running map to find functions and API calls...");
|
|
234
237
|
globalsUtil.setOpenapi(true);
|
|
235
238
|
if (isBatch) {
|
|
236
239
|
globalsUtil.setOpenapiOutputFile(openapiFile);
|
|
@@ -245,20 +248,19 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
245
248
|
map(outputDir, mappedFileVue, ["json"], "vue", false, false, cmd.command || []),
|
|
246
249
|
getSkipStepPromise(),
|
|
247
250
|
]);
|
|
248
|
-
|
|
251
|
+
printMsg(MSG.Run, "[+] Map complete.");
|
|
249
252
|
if (shouldSkipTarget())
|
|
250
253
|
return;
|
|
251
|
-
|
|
254
|
+
printMsg(MSG.Header, "[3/4] Running analyze...");
|
|
252
255
|
resetSkipStep();
|
|
253
|
-
// @ts-ignore
|
|
254
256
|
yield Promise.race([
|
|
255
|
-
analyze(cmd.rules || "", mappedJsonFileVue, "vue", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
|
|
257
|
+
analyze(cmd.rules || "", mappedJsonFileVue, "vue", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck, false, false),
|
|
256
258
|
getSkipStepPromise(),
|
|
257
259
|
]);
|
|
258
|
-
|
|
260
|
+
printMsg(MSG.Run, "[+] Analyze complete.");
|
|
259
261
|
if (shouldSkipTarget())
|
|
260
262
|
return;
|
|
261
|
-
|
|
263
|
+
printMsg(MSG.Header, "[4/4] Running report module...");
|
|
262
264
|
// Endpoints extraction isn't implemented for Vue yet; pass an empty file if absent.
|
|
263
265
|
const endpointsJson = `${endpointsFile}.json`;
|
|
264
266
|
if (!fs.existsSync(endpointsJson)) {
|
|
@@ -266,20 +268,20 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
266
268
|
}
|
|
267
269
|
resetSkipStep();
|
|
268
270
|
yield Promise.race([
|
|
269
|
-
report(reportDbFile, mappedJsonFileVue, analyzeFile, endpointsJson, openapiFile, reportFile),
|
|
271
|
+
report(reportDbFile, mappedJsonFileVue, analyzeFile, endpointsJson, openapiFile, reportFile, cmd.sj, cmd.sjBin, cmd.sjArgs),
|
|
270
272
|
getSkipStepPromise(),
|
|
271
273
|
]);
|
|
272
|
-
|
|
274
|
+
printMsg(MSG.Run, "[+] Report complete.");
|
|
273
275
|
if (shouldSkipTarget())
|
|
274
276
|
return;
|
|
275
277
|
if (!cmd.disableRefactor) {
|
|
276
|
-
|
|
278
|
+
printMsg(MSG.Header, "[*] Detecting bundler via CS-MAST-S for refactor...");
|
|
277
279
|
const detectedBundlerTechVue = yield detectBundler(mappedJsonFileVue, "vue", Number((_b = cmd.csMastTechDetectThreshold) !== null && _b !== void 0 ? _b : 50));
|
|
278
280
|
if (detectedBundlerTechVue) {
|
|
279
281
|
const refactorOutputDirVue = isBatch ? `${workingDir}/refactored` : "refactored";
|
|
280
282
|
if (fs.existsSync(refactorOutputDirVue))
|
|
281
283
|
fs.rmSync(refactorOutputDirVue, { recursive: true });
|
|
282
|
-
|
|
284
|
+
printMsg(MSG.Header, `[*] Running refactor (${detectedBundlerTechVue})...`);
|
|
283
285
|
resetSkipStep();
|
|
284
286
|
yield Promise.race([
|
|
285
287
|
refactor(mappedJsonFileVue, refactorOutputDirVue, detectedBundlerTechVue, false),
|
|
@@ -287,16 +289,16 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
287
289
|
]);
|
|
288
290
|
if (shouldSkipTarget())
|
|
289
291
|
return;
|
|
290
|
-
|
|
292
|
+
printMsg(MSG.Run, "[+] Refactor complete.");
|
|
291
293
|
}
|
|
292
294
|
else {
|
|
293
|
-
|
|
295
|
+
printMsg(MSG.Warn, "[!] Bundler not detected via CS-MAST-S, skipping refactor.");
|
|
294
296
|
}
|
|
295
297
|
}
|
|
296
298
|
else {
|
|
297
|
-
|
|
299
|
+
printMsg(MSG.Warn, "[!] Refactor step disabled via --disable-refactor, skipping.");
|
|
298
300
|
}
|
|
299
|
-
|
|
301
|
+
printMsg(MSG.Run, `[+] Analysis complete for ${url}.`);
|
|
300
302
|
return;
|
|
301
303
|
}
|
|
302
304
|
if (detectedTech === "nuxt") {
|
|
@@ -308,7 +310,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
308
310
|
const reportDbFile = isBatch ? `${workingDir}/js-recon.db` : "js-recon.db";
|
|
309
311
|
const reportFile = isBatch ? `${workingDir}/report` : "report";
|
|
310
312
|
const endpointsFile = isBatch ? `${workingDir}/endpoints` : "endpoints";
|
|
311
|
-
|
|
313
|
+
printMsg(MSG.Header, "[2/4] Running map to find functions and API calls...");
|
|
312
314
|
globalsUtil.setOpenapi(true);
|
|
313
315
|
if (isBatch) {
|
|
314
316
|
globalsUtil.setOpenapiOutputFile(openapiFile);
|
|
@@ -323,40 +325,39 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
323
325
|
map(outputDir, mappedFileNuxt, ["json"], "vue", false, false, cmd.command || []),
|
|
324
326
|
getSkipStepPromise(),
|
|
325
327
|
]);
|
|
326
|
-
|
|
328
|
+
printMsg(MSG.Run, "[+] Map complete.");
|
|
327
329
|
if (shouldSkipTarget())
|
|
328
330
|
return;
|
|
329
|
-
|
|
331
|
+
printMsg(MSG.Header, "[3/4] Running analyze...");
|
|
330
332
|
resetSkipStep();
|
|
331
|
-
// @ts-ignore
|
|
332
333
|
yield Promise.race([
|
|
333
|
-
analyze(cmd.rules || "", mappedJsonFileNuxt, "vue", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
|
|
334
|
+
analyze(cmd.rules || "", mappedJsonFileNuxt, "vue", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck, false, false),
|
|
334
335
|
getSkipStepPromise(),
|
|
335
336
|
]);
|
|
336
|
-
|
|
337
|
+
printMsg(MSG.Run, "[+] Analyze complete.");
|
|
337
338
|
if (shouldSkipTarget())
|
|
338
339
|
return;
|
|
339
|
-
|
|
340
|
+
printMsg(MSG.Header, "[4/4] Running report module...");
|
|
340
341
|
const endpointsJson = `${endpointsFile}.json`;
|
|
341
342
|
if (!fs.existsSync(endpointsJson)) {
|
|
342
343
|
fs.writeFileSync(endpointsJson, "[]");
|
|
343
344
|
}
|
|
344
345
|
resetSkipStep();
|
|
345
346
|
yield Promise.race([
|
|
346
|
-
report(reportDbFile, mappedJsonFileNuxt, analyzeFile, endpointsJson, openapiFile, reportFile),
|
|
347
|
+
report(reportDbFile, mappedJsonFileNuxt, analyzeFile, endpointsJson, openapiFile, reportFile, cmd.sj, cmd.sjBin, cmd.sjArgs),
|
|
347
348
|
getSkipStepPromise(),
|
|
348
349
|
]);
|
|
349
|
-
|
|
350
|
+
printMsg(MSG.Run, "[+] Report complete.");
|
|
350
351
|
if (shouldSkipTarget())
|
|
351
352
|
return;
|
|
352
353
|
if (!cmd.disableRefactor) {
|
|
353
|
-
|
|
354
|
+
printMsg(MSG.Header, "[*] Detecting bundler via CS-MAST-S for refactor...");
|
|
354
355
|
const detectedBundlerTechNuxt = yield detectBundler(mappedJsonFileNuxt, "nuxt", Number((_c = cmd.csMastTechDetectThreshold) !== null && _c !== void 0 ? _c : 50));
|
|
355
356
|
if (detectedBundlerTechNuxt) {
|
|
356
357
|
const refactorOutputDirNuxt = isBatch ? `${workingDir}/refactored` : "refactored";
|
|
357
358
|
if (fs.existsSync(refactorOutputDirNuxt))
|
|
358
359
|
fs.rmSync(refactorOutputDirNuxt, { recursive: true });
|
|
359
|
-
|
|
360
|
+
printMsg(MSG.Header, `[*] Running refactor (${detectedBundlerTechNuxt})...`);
|
|
360
361
|
resetSkipStep();
|
|
361
362
|
yield Promise.race([
|
|
362
363
|
refactor(mappedJsonFileNuxt, refactorOutputDirNuxt, detectedBundlerTechNuxt, false),
|
|
@@ -364,16 +365,16 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
364
365
|
]);
|
|
365
366
|
if (shouldSkipTarget())
|
|
366
367
|
return;
|
|
367
|
-
|
|
368
|
+
printMsg(MSG.Run, "[+] Refactor complete.");
|
|
368
369
|
}
|
|
369
370
|
else {
|
|
370
|
-
|
|
371
|
+
printMsg(MSG.Warn, "[!] Bundler not detected via CS-MAST-S, skipping refactor.");
|
|
371
372
|
}
|
|
372
373
|
}
|
|
373
374
|
else {
|
|
374
|
-
|
|
375
|
+
printMsg(MSG.Warn, "[!] Refactor step disabled via --disable-refactor, skipping.");
|
|
375
376
|
}
|
|
376
|
-
|
|
377
|
+
printMsg(MSG.Run, `[+] Analysis complete for ${url}.`);
|
|
377
378
|
return;
|
|
378
379
|
}
|
|
379
380
|
if (detectedTech === "svelte") {
|
|
@@ -384,7 +385,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
384
385
|
const reportDbFile = isBatch ? `${workingDir}/js-recon.db` : "js-recon.db";
|
|
385
386
|
const reportFile = isBatch ? `${workingDir}/report` : "report";
|
|
386
387
|
const endpointsFile = isBatch ? `${workingDir}/endpoints` : "endpoints";
|
|
387
|
-
|
|
388
|
+
printMsg(MSG.Header, "[2/4] Running map to find functions and API calls...");
|
|
388
389
|
globalsUtil.setOpenapi(true);
|
|
389
390
|
if (isBatch) {
|
|
390
391
|
globalsUtil.setOpenapiOutputFile(openapiFile);
|
|
@@ -399,31 +400,30 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
399
400
|
map(outputDir, mappedFileSvelte, ["json"], "svelte", false, false, cmd.command || []),
|
|
400
401
|
getSkipStepPromise(),
|
|
401
402
|
]);
|
|
402
|
-
|
|
403
|
+
printMsg(MSG.Run, "[+] Map complete.");
|
|
403
404
|
if (shouldSkipTarget())
|
|
404
405
|
return;
|
|
405
|
-
|
|
406
|
+
printMsg(MSG.Header, "[3/4] Running analyze...");
|
|
406
407
|
resetSkipStep();
|
|
407
|
-
// @ts-ignore
|
|
408
408
|
yield Promise.race([
|
|
409
|
-
analyze(cmd.rules || "", mappedJsonFileSvelte, "svelte", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
|
|
409
|
+
analyze(cmd.rules || "", mappedJsonFileSvelte, "svelte", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck, false, false),
|
|
410
410
|
getSkipStepPromise(),
|
|
411
411
|
]);
|
|
412
|
-
|
|
412
|
+
printMsg(MSG.Run, "[+] Analyze complete.");
|
|
413
413
|
if (shouldSkipTarget())
|
|
414
414
|
return;
|
|
415
|
-
|
|
415
|
+
printMsg(MSG.Header, "[4/4] Running report module...");
|
|
416
416
|
const endpointsJson = `${endpointsFile}.json`;
|
|
417
417
|
if (!fs.existsSync(endpointsJson)) {
|
|
418
418
|
fs.writeFileSync(endpointsJson, "[]");
|
|
419
419
|
}
|
|
420
420
|
resetSkipStep();
|
|
421
421
|
yield Promise.race([
|
|
422
|
-
report(reportDbFile, mappedJsonFileSvelte, analyzeFile, endpointsJson, openapiFile, reportFile),
|
|
422
|
+
report(reportDbFile, mappedJsonFileSvelte, analyzeFile, endpointsJson, openapiFile, reportFile, cmd.sj, cmd.sjBin, cmd.sjArgs),
|
|
423
423
|
getSkipStepPromise(),
|
|
424
424
|
]);
|
|
425
|
-
|
|
426
|
-
|
|
425
|
+
printMsg(MSG.Run, "[+] Report complete.");
|
|
426
|
+
printMsg(MSG.Run, `[+] Analysis complete for ${url}.`);
|
|
427
427
|
return;
|
|
428
428
|
}
|
|
429
429
|
if (detectedTech === "angular") {
|
|
@@ -438,7 +438,7 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
438
438
|
const reportFile = isBatch ? `${workingDir}/report` : "report";
|
|
439
439
|
const endpointsFile = isBatch ? `${workingDir}/endpoints` : "endpoints";
|
|
440
440
|
const angularHostDir = resolveHostOutputDirectory(outputDir, targetHost, isBatch);
|
|
441
|
-
|
|
441
|
+
printMsg(MSG.Header, "[2/4] Running map to find functions and API calls...");
|
|
442
442
|
globalsUtil.setOpenapi(true);
|
|
443
443
|
if (isBatch) {
|
|
444
444
|
globalsUtil.setOpenapiOutputFile(openapiFile);
|
|
@@ -453,31 +453,30 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
453
453
|
map(angularHostDir, mappedFileAngular, ["json"], "angular", false, false, cmd.command || []),
|
|
454
454
|
getSkipStepPromise(),
|
|
455
455
|
]);
|
|
456
|
-
|
|
456
|
+
printMsg(MSG.Run, "[+] Map complete.");
|
|
457
457
|
if (shouldSkipTarget())
|
|
458
458
|
return;
|
|
459
|
-
|
|
459
|
+
printMsg(MSG.Header, "[3/4] Running analyze...");
|
|
460
460
|
resetSkipStep();
|
|
461
|
-
// @ts-ignore
|
|
462
461
|
yield Promise.race([
|
|
463
|
-
analyze(cmd.rules || "", mappedJsonFileAngular, "angular", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
|
|
462
|
+
analyze(cmd.rules || "", mappedJsonFileAngular, "angular", false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck, false, false),
|
|
464
463
|
getSkipStepPromise(),
|
|
465
464
|
]);
|
|
466
|
-
|
|
465
|
+
printMsg(MSG.Run, "[+] Analyze complete.");
|
|
467
466
|
if (shouldSkipTarget())
|
|
468
467
|
return;
|
|
469
|
-
|
|
468
|
+
printMsg(MSG.Header, "[4/4] Running report module...");
|
|
470
469
|
const endpointsJson = `${endpointsFile}.json`;
|
|
471
470
|
if (!fs.existsSync(endpointsJson)) {
|
|
472
471
|
fs.writeFileSync(endpointsJson, "[]");
|
|
473
472
|
}
|
|
474
473
|
resetSkipStep();
|
|
475
474
|
yield Promise.race([
|
|
476
|
-
report(reportDbFile, mappedJsonFileAngular, analyzeFile, endpointsJson, openapiFile, reportFile),
|
|
475
|
+
report(reportDbFile, mappedJsonFileAngular, analyzeFile, endpointsJson, openapiFile, reportFile, cmd.sj, cmd.sjBin, cmd.sjArgs),
|
|
477
476
|
getSkipStepPromise(),
|
|
478
477
|
]);
|
|
479
|
-
|
|
480
|
-
|
|
478
|
+
printMsg(MSG.Run, "[+] Report complete.");
|
|
479
|
+
printMsg(MSG.Run, `[+] Analysis complete for ${url}.`);
|
|
481
480
|
return;
|
|
482
481
|
}
|
|
483
482
|
const stringsFile = isBatch ? `${workingDir}/strings.json` : "strings.json";
|
|
@@ -494,50 +493,50 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
494
493
|
// One IMPORTANT thing: this is only meant for modules that rely on just the code (map)
|
|
495
494
|
const cdnDir = yield getCdnDir(url, outputDir, isBatch);
|
|
496
495
|
const cdnOutputDir = cdnDir ? cdnDir : resolveHostOutputDirectory(outputDir, targetHost, isBatch);
|
|
497
|
-
|
|
496
|
+
printMsg(MSG.Header, "[2/8] Running strings to extract endpoints...");
|
|
498
497
|
resetSkipStep();
|
|
499
498
|
yield Promise.race([
|
|
500
499
|
strings(outputDir, stringsFile, true, extractedUrlsFile, false, false, false, false),
|
|
501
500
|
getSkipStepPromise(),
|
|
502
501
|
]);
|
|
503
|
-
|
|
502
|
+
printMsg(MSG.Run, "[+] Strings complete.");
|
|
504
503
|
if (shouldSkipTarget())
|
|
505
504
|
return;
|
|
506
|
-
|
|
505
|
+
printMsg(MSG.Header, "[3/8] Running lazyload with subsequent requests to download JavaScript files...");
|
|
507
506
|
resetSkipStep();
|
|
508
|
-
yield awaitCancellableStep((signal) => lazyLoad(url, outputDir, cmd.strictScope, cmd.scope.split(","), cmd.threads, true, `${extractedUrlsFile}.json`, cmd.insecure, true, cmd.sourcemapDir, cmd.research, cmd.researchOutput, Number(cmd.maxIterations), Number(cmd.maxJsSize), Number(cmd.lazyloadTimeout) * 60 * 1000, Number(cmd.maxPages), includeMethods, excludeMethods, Number(cmd.detectionTimeout) * 1000, signal, isBatch), getSkipStepPromise());
|
|
509
|
-
|
|
507
|
+
yield awaitCancellableStep((signal) => lazyLoad(url, outputDir, cmd.strictScope, cmd.scope.split(","), cmd.threads, true, `${extractedUrlsFile}.json`, cmd.insecure, true, cmd.sourcemapDir, cmd.research, cmd.researchOutput, Number(cmd.maxIterations), Number(cmd.maxJsSize), Number(cmd.lazyloadTimeout) * 60 * 1000, Number(cmd.maxPages), includeMethods, excludeMethods, Number(cmd.detectionTimeout) * 1000, signal, isBatch, Number(cmd.maxRedirects), cmd.strings, Number(cmd.stringsMaxIterations), Number(cmd.stagnationTimein) * 60 * 1000, Number(cmd.stagnationPercentage), Number(cmd.stagnationMonitor) * 60 * 1000, Number(cmd.rscParamBruteforceLimit)), getSkipStepPromise());
|
|
508
|
+
printMsg(MSG.Run, "[+] Lazyload with subsequent requests complete.");
|
|
510
509
|
if (shouldSkipTarget())
|
|
511
510
|
return;
|
|
512
|
-
|
|
511
|
+
printMsg(MSG.Header, "[4/8] Running strings again to extract endpoints...");
|
|
513
512
|
resetSkipStep();
|
|
514
513
|
yield Promise.race([
|
|
515
|
-
strings(outputDir, stringsFile, true, extractedUrlsFile, cmd.secrets, true, true, cmd.trufflehog),
|
|
514
|
+
strings(outputDir, stringsFile, true, extractedUrlsFile, cmd.secrets, true, true, cmd.trufflehog, cmd.trufflehogBin, cmd.trufflehogAcceptTerms),
|
|
516
515
|
getSkipStepPromise(),
|
|
517
516
|
]);
|
|
518
|
-
|
|
517
|
+
printMsg(MSG.Run, "[+] Strings complete.");
|
|
519
518
|
if (shouldSkipTarget())
|
|
520
519
|
return;
|
|
521
520
|
// a second subsequent_requests pass: the first strings pass only sees initial chunks,
|
|
522
521
|
// so dynamic routes such as `/post/1` are only discovered after the first subsequent
|
|
523
522
|
// crawl + second strings extraction. Re-running subsequent_requests with the freshly
|
|
524
523
|
// updated paths picks up chunks for those dynamic routes (e.g. the post page).
|
|
525
|
-
|
|
524
|
+
printMsg(MSG.Header, "[4.5/8] Re-running lazyload with subsequent requests for newly discovered paths...");
|
|
526
525
|
resetSkipStep();
|
|
527
|
-
yield awaitCancellableStep((signal) => lazyLoad(url, outputDir, cmd.strictScope, cmd.scope.split(","), cmd.threads, true, `${extractedUrlsFile}.json`, cmd.insecure, false, cmd.sourcemapDir, cmd.research, cmd.researchOutput, Number(cmd.maxIterations), Number(cmd.maxJsSize), Number(cmd.lazyloadTimeout) * 60 * 1000, Number(cmd.maxPages), includeMethods, excludeMethods, Number(cmd.detectionTimeout) * 1000, signal, isBatch), getSkipStepPromise());
|
|
528
|
-
|
|
526
|
+
yield awaitCancellableStep((signal) => lazyLoad(url, outputDir, cmd.strictScope, cmd.scope.split(","), cmd.threads, true, `${extractedUrlsFile}.json`, cmd.insecure, false, cmd.sourcemapDir, cmd.research, cmd.researchOutput, Number(cmd.maxIterations), Number(cmd.maxJsSize), Number(cmd.lazyloadTimeout) * 60 * 1000, Number(cmd.maxPages), includeMethods, excludeMethods, Number(cmd.detectionTimeout) * 1000, signal, isBatch, Number(cmd.maxRedirects), cmd.strings, Number(cmd.stringsMaxIterations), Number(cmd.stagnationTimein) * 60 * 1000, Number(cmd.stagnationPercentage), Number(cmd.stagnationMonitor) * 60 * 1000, Number(cmd.rscParamBruteforceLimit)), getSkipStepPromise());
|
|
527
|
+
printMsg(MSG.Run, "[+] Lazyload re-pass complete.");
|
|
529
528
|
if (shouldSkipTarget())
|
|
530
529
|
return;
|
|
531
|
-
|
|
530
|
+
printMsg(MSG.Header, "[4.6/8] Re-running strings for chunks from the re-pass...");
|
|
532
531
|
resetSkipStep();
|
|
533
532
|
yield Promise.race([
|
|
534
|
-
strings(outputDir, stringsFile, true, extractedUrlsFile, cmd.secrets, true, true, cmd.trufflehog),
|
|
533
|
+
strings(outputDir, stringsFile, true, extractedUrlsFile, cmd.secrets, true, true, cmd.trufflehog, cmd.trufflehogBin, cmd.trufflehogAcceptTerms),
|
|
535
534
|
getSkipStepPromise(),
|
|
536
535
|
]);
|
|
537
|
-
|
|
536
|
+
printMsg(MSG.Run, "[+] Strings re-pass complete.");
|
|
538
537
|
if (shouldSkipTarget())
|
|
539
538
|
return;
|
|
540
|
-
|
|
539
|
+
printMsg(MSG.Header, "[5/8] Running map to find functions...");
|
|
541
540
|
globalsUtil.setOpenapi(true);
|
|
542
541
|
if (isBatch) {
|
|
543
542
|
globalsUtil.setOpenapiOutputFile(openapiFile);
|
|
@@ -555,10 +554,10 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
555
554
|
map(cdnOutputDir, mappedFile, ["json"], detectedTech, false, false, cmd.command || []),
|
|
556
555
|
getSkipStepPromise(),
|
|
557
556
|
]);
|
|
558
|
-
|
|
557
|
+
printMsg(MSG.Run, "[+] Map complete.");
|
|
559
558
|
if (shouldSkipTarget())
|
|
560
559
|
return;
|
|
561
|
-
|
|
560
|
+
printMsg(MSG.Header, "[6/8] Running endpoints to extract endpoints...");
|
|
562
561
|
resetSkipStep();
|
|
563
562
|
const targetOutputDir = resolveHostOutputDirectory(outputDir, targetHost, isBatch);
|
|
564
563
|
if (fs.existsSync(path.join(targetOutputDir, "___subsequent_requests"))) {
|
|
@@ -573,35 +572,35 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
573
572
|
getSkipStepPromise(),
|
|
574
573
|
]);
|
|
575
574
|
}
|
|
576
|
-
|
|
575
|
+
printMsg(MSG.Run, "[+] Endpoints complete.");
|
|
577
576
|
if (shouldSkipTarget())
|
|
578
577
|
return;
|
|
579
|
-
|
|
578
|
+
printMsg(MSG.Header, "[7/8] Running analyze to extract endpoints...");
|
|
580
579
|
resetSkipStep();
|
|
581
580
|
yield Promise.race([
|
|
582
|
-
analyze(cmd.rules || "", mappedJsonFile, detectedTech, false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck),
|
|
581
|
+
analyze(cmd.rules || "", mappedJsonFile, detectedTech, false, openapiFile, false, analyzeFile, !!cmd.disableRulesVersionCheck, false, false),
|
|
583
582
|
getSkipStepPromise(),
|
|
584
583
|
]);
|
|
585
|
-
|
|
584
|
+
printMsg(MSG.Run, "[+] Analyze complete.");
|
|
586
585
|
if (shouldSkipTarget())
|
|
587
586
|
return;
|
|
588
|
-
|
|
587
|
+
printMsg(MSG.Header, "[8/8] Running report module...");
|
|
589
588
|
resetSkipStep();
|
|
590
589
|
yield Promise.race([
|
|
591
|
-
report(reportDbFile, mappedJsonFile, analyzeFile, `${endpointsFile}.json`, openapiFile, reportFile),
|
|
590
|
+
report(reportDbFile, mappedJsonFile, analyzeFile, `${endpointsFile}.json`, openapiFile, reportFile, cmd.sj, cmd.sjBin, cmd.sjArgs),
|
|
592
591
|
getSkipStepPromise(),
|
|
593
592
|
]);
|
|
594
|
-
|
|
593
|
+
printMsg(MSG.Run, "[+] Report complete.");
|
|
595
594
|
if (shouldSkipTarget())
|
|
596
595
|
return;
|
|
597
596
|
if (!cmd.disableRefactor) {
|
|
598
|
-
|
|
597
|
+
printMsg(MSG.Header, "[*] Detecting bundler via CS-MAST-S for refactor...");
|
|
599
598
|
const detectedBundlerTechNext = yield detectBundler(mappedJsonFile, detectedTech, Number((_d = cmd.csMastTechDetectThreshold) !== null && _d !== void 0 ? _d : 50));
|
|
600
599
|
if (detectedBundlerTechNext) {
|
|
601
600
|
const refactorOutputDirNext = isBatch ? `${workingDir}/refactored` : "refactored";
|
|
602
601
|
if (fs.existsSync(refactorOutputDirNext))
|
|
603
602
|
fs.rmSync(refactorOutputDirNext, { recursive: true });
|
|
604
|
-
|
|
603
|
+
printMsg(MSG.Header, `[*] Running refactor (${detectedBundlerTechNext})...`);
|
|
605
604
|
resetSkipStep();
|
|
606
605
|
yield Promise.race([
|
|
607
606
|
refactor(mappedJsonFile, refactorOutputDirNext, detectedBundlerTechNext, false),
|
|
@@ -609,16 +608,16 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
609
608
|
]);
|
|
610
609
|
if (shouldSkipTarget())
|
|
611
610
|
return;
|
|
612
|
-
|
|
611
|
+
printMsg(MSG.Run, "[+] Refactor complete.");
|
|
613
612
|
}
|
|
614
613
|
else {
|
|
615
|
-
|
|
614
|
+
printMsg(MSG.Warn, "[!] Bundler not detected via CS-MAST-S, skipping refactor.");
|
|
616
615
|
}
|
|
617
616
|
}
|
|
618
617
|
else {
|
|
619
|
-
|
|
618
|
+
printMsg(MSG.Warn, "[!] Refactor step disabled via --disable-refactor, skipping.");
|
|
620
619
|
}
|
|
621
|
-
|
|
620
|
+
printMsg(MSG.Run, `[+] Analysis complete for ${url}.`);
|
|
622
621
|
});
|
|
623
622
|
/**
|
|
624
623
|
* Main handler for the 'run' command that executes the complete js-recon analysis pipeline.
|
|
@@ -630,6 +629,32 @@ const processUrl = (url_1, outputDir_1, workingDir_1, cmd_1, isBatch_1, ...args_
|
|
|
630
629
|
* @param cmd - The command-line options object from commander.js
|
|
631
630
|
* @returns Promise that resolves when all URL processing is complete
|
|
632
631
|
*/
|
|
632
|
+
/**
|
|
633
|
+
* Parses a batch/single `cmd.url` into the `{ url, hostDir, dir }` entries the
|
|
634
|
+
* dashboard state store needs, mirroring the hostDir/dir resolution the batch
|
|
635
|
+
* loop and single-target path use below. Invalid URLs are dropped — they're
|
|
636
|
+
* reported (and skipped) by the existing validation further down.
|
|
637
|
+
*/
|
|
638
|
+
const buildDashboardTargetEntries = (cmd, isBatch) => {
|
|
639
|
+
const toEntry = (url, dir) => {
|
|
640
|
+
try {
|
|
641
|
+
return { url, hostDir: new URL(url).host.replace(":", "_"), dir };
|
|
642
|
+
}
|
|
643
|
+
catch (_a) {
|
|
644
|
+
return null;
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
if (!isBatch) {
|
|
648
|
+
const entry = toEntry(cmd.url, cmd.output);
|
|
649
|
+
return entry ? [entry] : [];
|
|
650
|
+
}
|
|
651
|
+
return fs
|
|
652
|
+
.readFileSync(cmd.url, "utf-8")
|
|
653
|
+
.split("\n")
|
|
654
|
+
.filter((url) => url !== "")
|
|
655
|
+
.map((url) => toEntry(url, `${cmd.output}/${new URL(url).host.replace(":", "_")}`))
|
|
656
|
+
.filter((e) => e !== null);
|
|
657
|
+
};
|
|
633
658
|
export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
634
659
|
var _a, _b, _c, _d, _e, _f;
|
|
635
660
|
const resolvedTargets = resolveTargetInputs(cmd.url);
|
|
@@ -653,9 +678,29 @@ export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
653
678
|
clearRunOutputDirectory(runCommand.output);
|
|
654
679
|
}
|
|
655
680
|
installSigintHandler(isBatch);
|
|
681
|
+
let dashboard = null;
|
|
682
|
+
if (cmd.webStatsDashboard) {
|
|
683
|
+
dashboardState.registerTargets(buildDashboardTargetEntries(cmd, isBatch));
|
|
684
|
+
dashboard = yield startDashboardServer(Number(cmd.webStatsPort));
|
|
685
|
+
printMsg(MSG.Run, `[+] Web stats dashboard running at ${dashboard.url}`);
|
|
686
|
+
setHeaderListener((msg) => dashboardState.markStep(msg));
|
|
687
|
+
}
|
|
656
688
|
try {
|
|
657
689
|
if (!isBatch) {
|
|
658
|
-
|
|
690
|
+
if (cmd.webStatsDashboard) {
|
|
691
|
+
dashboardState.setCurrentUrl(resolvedTargets.targets[0]);
|
|
692
|
+
dashboardState.markRunning(resolvedTargets.targets[0]);
|
|
693
|
+
}
|
|
694
|
+
try {
|
|
695
|
+
yield processUrl(resolvedTargets.targets[0], runCommand.output, ".", runCommand, false, (_a = runCommand._includeMethods) !== null && _a !== void 0 ? _a : [], (_b = runCommand._excludeMethods) !== null && _b !== void 0 ? _b : []);
|
|
696
|
+
if (cmd.webStatsDashboard)
|
|
697
|
+
dashboardState.markCompleted(resolvedTargets.targets[0]);
|
|
698
|
+
}
|
|
699
|
+
catch (e) {
|
|
700
|
+
if (cmd.webStatsDashboard)
|
|
701
|
+
dashboardState.markError(resolvedTargets.targets[0], e instanceof Error ? e.message : String(e));
|
|
702
|
+
throw e;
|
|
703
|
+
}
|
|
659
704
|
}
|
|
660
705
|
else {
|
|
661
706
|
const globalDbPath = `${runCommand.output}/js-recon.db`;
|
|
@@ -677,12 +722,30 @@ export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
677
722
|
else if (targetReservation.redirected) {
|
|
678
723
|
console.log(chalk.yellow(`[i] Target output already exists; using ${thisTargetDir} for ${url}.`));
|
|
679
724
|
}
|
|
725
|
+
if (cmd.webStatsDashboard && dashboardState.isSkipRequested(url)) {
|
|
726
|
+
printMsg(MSG.Warn, `[!] Skipping ${url} (skipped from the web dashboard).`);
|
|
727
|
+
dashboardState.markSkipped(url);
|
|
728
|
+
targetReservation.release();
|
|
729
|
+
continue;
|
|
730
|
+
}
|
|
731
|
+
if (cmd.webStatsDashboard) {
|
|
732
|
+
dashboardState.setCurrentUrl(url);
|
|
733
|
+
dashboardState.markRunning(url);
|
|
734
|
+
}
|
|
680
735
|
try {
|
|
681
736
|
try {
|
|
682
737
|
yield processUrl(url, thisTargetDir, thisTargetDir, runCommand, true, (_d = runCommand._includeMethods) !== null && _d !== void 0 ? _d : [], (_e = runCommand._excludeMethods) !== null && _e !== void 0 ? _e : []);
|
|
738
|
+
if (cmd.webStatsDashboard) {
|
|
739
|
+
if (shouldSkipTarget())
|
|
740
|
+
dashboardState.markSkipped(url);
|
|
741
|
+
else
|
|
742
|
+
dashboardState.markCompleted(url);
|
|
743
|
+
}
|
|
683
744
|
}
|
|
684
745
|
catch (error) {
|
|
685
|
-
|
|
746
|
+
if (cmd.webStatsDashboard)
|
|
747
|
+
dashboardState.markError(url, error instanceof Error ? error.message : String(error));
|
|
748
|
+
printMsg(MSG.Err, `[!] Unhandled error while processing ${url}: ${error}`);
|
|
686
749
|
process.exitCode = 1;
|
|
687
750
|
continue;
|
|
688
751
|
}
|
|
@@ -692,11 +755,11 @@ export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
692
755
|
mergeDomainIntoGlobalDb(globalDbPath, domainDbPath, hostDir);
|
|
693
756
|
}
|
|
694
757
|
catch (error) {
|
|
695
|
-
|
|
758
|
+
printMsg(MSG.Warn, `[!] Failed to merge ${hostDir} into the global js-recon.db: ${error}`);
|
|
696
759
|
}
|
|
697
760
|
}
|
|
698
761
|
else {
|
|
699
|
-
|
|
762
|
+
printMsg(MSG.Warn, `[i] No js-recon.db found for ${hostDir}, skipping merge into the global database.`);
|
|
700
763
|
}
|
|
701
764
|
}
|
|
702
765
|
finally {
|
|
@@ -706,10 +769,14 @@ export default (cmd) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
706
769
|
}
|
|
707
770
|
}
|
|
708
771
|
catch (error) {
|
|
709
|
-
|
|
772
|
+
printMsg(MSG.Err, `[!] Unhandled error: ${error}`);
|
|
710
773
|
process.exitCode = 1;
|
|
711
774
|
}
|
|
712
775
|
finally {
|
|
776
|
+
if (dashboard) {
|
|
777
|
+
setHeaderListener(null);
|
|
778
|
+
yield dashboard.stop();
|
|
779
|
+
}
|
|
713
780
|
try {
|
|
714
781
|
yield waitForPendingInterrupt();
|
|
715
782
|
}
|