@js-recon/js-recon 1.4.3 → 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 +55 -25
- 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 +15 -7
- package/.nvmrc +1 -0
- package/.plumber.yaml +151 -0
- package/CHANGELOG.md +54 -0
- package/CONTRIBUTING.md +32 -0
- package/Dockerfile +1 -0
- package/README.md +55 -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 +42 -24
- 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 +245 -339
- 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 +494 -0
- package/build/config/applicationConfig.js.map +1 -0
- 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 +11 -21
- 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 +16 -555
- 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 +51 -40
- package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
- package/build/lazyLoad/downloadQueue.js +154 -50
- package/build/lazyLoad/downloadQueue.js.map +1 -1
- package/build/lazyLoad/downloadResponse.js +113 -0
- package/build/lazyLoad/downloadResponse.js.map +1 -0
- 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 +35 -0
- package/build/lazyLoad/globals.js.map +1 -1
- package/build/lazyLoad/index.js +311 -175
- 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 +39 -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 +21 -20
- package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
- package/build/lazyLoad/next_js/next_SubsequentRequests.js +100 -99
- 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/outputPath.js +92 -0
- package/build/lazyLoad/outputPath.js.map +1 -0
- package/build/lazyLoad/react/react_followImports.js +15 -5
- package/build/lazyLoad/react/react_followImports.js.map +1 -1
- package/build/lazyLoad/react/react_getScriptTags.js +11 -6
- package/build/lazyLoad/react/react_getScriptTags.js.map +1 -1
- package/build/lazyLoad/react/react_sourcemapUrls.js +3 -2
- package/build/lazyLoad/react/react_sourcemapUrls.js.map +1 -1
- package/build/lazyLoad/react/react_webpackChunkPaths.js +12 -203
- 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 +106 -60
- package/build/lazyLoad/techDetect/index.js.map +1 -1
- package/build/lazyLoad/vue/vue_RuntimeJs.js +20 -15
- package/build/lazyLoad/vue/vue_RuntimeJs.js.map +1 -1
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +10 -5
- package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -1
- package/build/lazyLoad/vue/vue_discoverJsFiles.js +20 -17
- package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -1
- package/build/lazyLoad/vue/vue_getClientSidePaths.js +70 -46
- package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -1
- package/build/lazyLoad/vue/vue_jsImports.js +3 -2
- package/build/lazyLoad/vue/vue_jsImports.js.map +1 -1
- package/build/lazyLoad/vue/vue_pageSrc.js +3 -2
- package/build/lazyLoad/vue/vue_pageSrc.js.map +1 -1
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js +6 -5
- package/build/lazyLoad/vue/vue_reconstructSourceMaps.js.map +1 -1
- package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +10 -21
- package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -1
- package/build/lazyLoad/vue/vue_severalJsFilesHome.js +5 -4
- package/build/lazyLoad/vue/vue_severalJsFilesHome.js.map +1 -1
- package/build/lazyLoad/vue/vue_stringJsFiles.js +28 -25
- package/build/lazyLoad/vue/vue_stringJsFiles.js.map +1 -1
- package/build/lazyLoad/vue/vue_viteMapDeps.js +8 -2
- package/build/lazyLoad/vue/vue_viteMapDeps.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/checkFeasibility.js +8 -4
- package/build/proxy/checkFeasibility.js.map +1 -1
- package/build/proxy/checkFireWallBlocking.js +23 -13
- package/build/proxy/checkFireWallBlocking.js.map +1 -1
- package/build/proxy/detectBlockedResponse.js +205 -0
- package/build/proxy/detectBlockedResponse.js.map +1 -0
- package/build/proxy/genReq.js +434 -127
- package/build/proxy/genReq.js.map +1 -1
- package/build/proxy/index.js +3 -3
- package/build/proxy/index.js.map +1 -1
- package/build/proxy/oxylabsFallback.js +110 -0
- package/build/proxy/oxylabsFallback.js.map +1 -0
- package/build/proxy/proxyFeasibilityRequest.js +11 -9
- package/build/proxy/proxyFeasibilityRequest.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/cancellableStep.js +27 -0
- package/build/run/cancellableStep.js.map +1 -0
- 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 +239 -204
- 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/run/outputDirectory.js +377 -0
- package/build/run/outputDirectory.js.map +1 -0
- package/build/sourcemaps/index.js +116 -29
- package/build/sourcemaps/index.js.map +1 -1
- package/build/strings/index.js +38 -28
- 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/downloadProgress.js +99 -0
- package/build/utility/downloadProgress.js.map +1 -0
- 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 +490 -257
- 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 +68 -7
- 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/build/utility/targetInputs.js +177 -0
- package/build/utility/targetInputs.js.map +1 -0
- package/build/utility/urlUtils.js +37 -1
- package/build/utility/urlUtils.js.map +1 -1
- package/config.dist.yaml +251 -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/.plumber.yaml
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Plumber configuration (https://github.com/getplumber/plumber)
|
|
2
|
+
# See js-recon-internal-docs/docs/dev-workflow/plumber-security-scanning.md for details.
|
|
3
|
+
|
|
4
|
+
version: "2.0"
|
|
5
|
+
github:
|
|
6
|
+
controls:
|
|
7
|
+
containerImageMustNotUseForbiddenTags:
|
|
8
|
+
enabled: true
|
|
9
|
+
tags:
|
|
10
|
+
- latest
|
|
11
|
+
- dev
|
|
12
|
+
- development
|
|
13
|
+
- staging
|
|
14
|
+
- main
|
|
15
|
+
- master
|
|
16
|
+
containerImagesMustBePinnedByDigest: true
|
|
17
|
+
branchMustBeProtected:
|
|
18
|
+
enabled: false # disabled: enabling real GitHub branch protection is a separate follow-up (would need to allow-list bot/PAT push automation first)
|
|
19
|
+
namePatterns:
|
|
20
|
+
- main
|
|
21
|
+
- dev
|
|
22
|
+
defaultMustBeProtected: true
|
|
23
|
+
allowForcePush: false
|
|
24
|
+
codeOwnerApprovalRequired: false
|
|
25
|
+
externalRefsMustNotCollide:
|
|
26
|
+
enabled: true
|
|
27
|
+
pipelineMustNotEnableDebugTrace:
|
|
28
|
+
enabled: true
|
|
29
|
+
forbiddenVariables:
|
|
30
|
+
- ACTIONS_STEP_DEBUG
|
|
31
|
+
- ACTIONS_RUNNER_DEBUG
|
|
32
|
+
securityJobsMustNotBeWeakened:
|
|
33
|
+
enabled: true
|
|
34
|
+
securityJobPatterns:
|
|
35
|
+
- "*codeql*"
|
|
36
|
+
- "*dependency-review*"
|
|
37
|
+
- "*trufflehog*"
|
|
38
|
+
- "*gitleaks*"
|
|
39
|
+
- "*osv-scanner*"
|
|
40
|
+
- "*-sast"
|
|
41
|
+
- "*-sast-*"
|
|
42
|
+
- "*-scan"
|
|
43
|
+
- "*scan*"
|
|
44
|
+
- "*-security"
|
|
45
|
+
- "*-security-*"
|
|
46
|
+
- "*-audit"
|
|
47
|
+
- "*-audit-*"
|
|
48
|
+
allowFailureMustBeFalse:
|
|
49
|
+
enabled: false
|
|
50
|
+
rulesMustNotBeRedefined:
|
|
51
|
+
enabled: false
|
|
52
|
+
whenMustNotBeManual:
|
|
53
|
+
enabled: false
|
|
54
|
+
pipelineMustNotUseDockerInDocker:
|
|
55
|
+
enabled: true
|
|
56
|
+
detectInsecureDaemon: true
|
|
57
|
+
actionsMustBePinnedByCommitSha:
|
|
58
|
+
enabled: true
|
|
59
|
+
trustedOwners:
|
|
60
|
+
- actions
|
|
61
|
+
- github
|
|
62
|
+
githubActionMustComeFromAuthorizedSources:
|
|
63
|
+
enabled: true
|
|
64
|
+
trustGithubOfficialActions: true
|
|
65
|
+
trustSameOrgActions: true
|
|
66
|
+
trustedGithubActions:
|
|
67
|
+
- shriyanss/verified-commit-action
|
|
68
|
+
- docker/login-action
|
|
69
|
+
- getplumber/plumber
|
|
70
|
+
workflowMustNotInjectUserInputInScripts:
|
|
71
|
+
enabled: true
|
|
72
|
+
workflowMustNotWriteUntrustedContentToGitHubEnv:
|
|
73
|
+
enabled: true
|
|
74
|
+
workflowMustNotUseDangerousTriggers:
|
|
75
|
+
enabled: true
|
|
76
|
+
pullRequestTargetMustNotCheckoutHead:
|
|
77
|
+
enabled: true
|
|
78
|
+
workflowsMustDeclarePermissions:
|
|
79
|
+
enabled: true
|
|
80
|
+
reusableWorkflowsMustNotInheritSecrets:
|
|
81
|
+
enabled: true
|
|
82
|
+
workflowMustNotExportEntireSecretsContext:
|
|
83
|
+
enabled: true
|
|
84
|
+
workflowMustNotGrantPermissionsWriteAll:
|
|
85
|
+
enabled: true
|
|
86
|
+
actionsMustNotBeArchived:
|
|
87
|
+
enabled: true
|
|
88
|
+
actionRefsMustExistUpstream:
|
|
89
|
+
enabled: true
|
|
90
|
+
actionsMustNotCarryKnownCVEs:
|
|
91
|
+
enabled: true
|
|
92
|
+
actionsMustNotExecuteMutableRemoteCode:
|
|
93
|
+
enabled: true
|
|
94
|
+
releaseWorkflowsMustNotRestoreUntrustedCache:
|
|
95
|
+
enabled: true
|
|
96
|
+
publishActions:
|
|
97
|
+
- pypa/gh-action-pypi-publish
|
|
98
|
+
- JS-DevTools/npm-publish
|
|
99
|
+
- gradle/publish-plugin
|
|
100
|
+
- softprops/action-gh-release
|
|
101
|
+
- ncipollo/release-action
|
|
102
|
+
- goreleaser/goreleaser-action
|
|
103
|
+
- crazy-max/ghaction-docker-buildx
|
|
104
|
+
- changesets/action
|
|
105
|
+
cacheActions:
|
|
106
|
+
- action: actions/cache
|
|
107
|
+
mode: always
|
|
108
|
+
- action: actions/cache/restore
|
|
109
|
+
mode: always
|
|
110
|
+
- action: Swatinem/rust-cache
|
|
111
|
+
mode: always
|
|
112
|
+
- action: actions/setup-go
|
|
113
|
+
mode: default
|
|
114
|
+
disableInput: cache
|
|
115
|
+
disableValue: false
|
|
116
|
+
- action: gradle/actions/setup-gradle
|
|
117
|
+
mode: default
|
|
118
|
+
disableInput: cache-disabled
|
|
119
|
+
disableValue: true
|
|
120
|
+
- action: actions/setup-node
|
|
121
|
+
mode: opt-in
|
|
122
|
+
enableInput: cache
|
|
123
|
+
- action: actions/setup-python
|
|
124
|
+
mode: opt-in
|
|
125
|
+
enableInput: cache
|
|
126
|
+
- action: actions/setup-java
|
|
127
|
+
mode: opt-in
|
|
128
|
+
enableInput: cache
|
|
129
|
+
- action: pnpm/action-setup
|
|
130
|
+
mode: opt-in
|
|
131
|
+
enableInput: cache
|
|
132
|
+
- action: docker/build-push-action
|
|
133
|
+
mode: opt-in
|
|
134
|
+
enableInput: cache-from
|
|
135
|
+
enableContains: type=gha
|
|
136
|
+
publishScriptPatterns:
|
|
137
|
+
- (?i)(npm|pnpm|yarn|bun)\s+publish
|
|
138
|
+
- (?i)cargo\s+publish
|
|
139
|
+
- (?i)twine\s+upload
|
|
140
|
+
- (?i)poetry\s+publish
|
|
141
|
+
- (?i)gh\s+release\s+create
|
|
142
|
+
- (?i)goreleaser\s+release
|
|
143
|
+
- (?i)semantic-release
|
|
144
|
+
- (?i)gradlew?\b[^\n]*\bpublish
|
|
145
|
+
- (?i)\bmvnw?\b[^\n]*\bdeploy\b
|
|
146
|
+
- (?i)dotnet\s+nuget\s+push
|
|
147
|
+
- (?i)gem\s+push
|
|
148
|
+
- (?i)docker\s+push
|
|
149
|
+
publishScriptExcludePatterns:
|
|
150
|
+
- (?i)--dry-run
|
|
151
|
+
- (?i)publishToMavenLocal
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 2.0.1-alpha.1 - (unreleased)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- New Next.js `lazyload` method `next_routerStateForge`: for every route the crawl finds redirecting an unauthenticated request (a session/auth gate), it retries the route as an RSC fetch with a forged `Next-Router-State-Tree` header claiming a known ancestor path segment is already client-rendered, plus the matching `_rsc` cache-busting key (SHA-256 of the four cache-busting inputs, truncated to 96 bits, base64url — not a secret, computable from headers the client itself sends). Some Next.js apps put their only auth check inside a layout component instead of middleware; Next.js skips re-executing that layout's component function when the client's router-state claims it's already mounted, which can return the protected child content — and any JS chunk references inside that Flight payload — for a request with no session at all. A response is only treated as a hit when it's `200`, has an RSC (`text/x-component`) content type, and does not contain a `NEXT_REDIRECT` record. Runs as the crawler's final phase, after brute-force `.map` discovery; opt out per-target via `--exclude-methods next_routerStateForge`. If no full-body ancestor claim succeeds for a candidate (e.g. a tenant-scoped layout the ancestor heuristic doesn't cleanly match), the method also tries marking the leaf segment `metadata-only` instead — this narrower claim can still leak dynamic `generateMetadata()` output even where the full-body claim doesn't apply, and is reported separately from full-body hits. Every forged request now tries the cheap legacy `_rsc` key (32-bit djb2 hash, base36, 5 characters — no SHA-256 needed) before falling back to the strong key; some Next.js builds accept the legacy key as a fallback when the strong-key check fails, so this can skip the crypto step entirely, and which key mode actually worked is reported as `next_routerStateForge_legacyKeyAccepted` in `--research-output` — a signal for which build line is running, since only builds with the legacy-key fallback path accept it at all. Ancestor claims also try common dynamic-route param-name guesses (`id`, `slug`, `org`, `tenant`, `username`) for the last ancestor segment: Next.js's `matchSegment` requires an exact `[paramName, value]` tuple for a dynamic route (e.g. `app/organizations/[org]/layout.js`) — a bare string never matches one — and a black-box crawl can only observe the URL's literal value, not the app's real param name. Chunk-path extraction from a bypassed Flight payload matches the actual wire format (`static/chunks/*.js`, no `_next/` prefix — the client resolves that against its own asset prefix at runtime) rather than assuming one. (`lazyload`)
|
|
8
|
+
- `next_routerStateForge`'s dynamic-route param-name guessing is expanded from 5 names (`id`, `slug`, `org`, `tenant`, `username`) to a larger fixed set (`orgId`, `organization`, `tenantId`, `userId`, `user`, `account`, `accountId`, `workspace`, `workspaceId`, `project`, `projectId`, `team`, `teamId`, `handle`, `name`, `key`) and gains a bounded fallback: when every fixed-list guess fails for a candidate ancestor segment, the Flight/RSC response bodies already fetched during those failed attempts are scanned (no extra requests — the bodies are already paid for) for the app's real param name via two anchored patterns — a value-anchored `"key":"value"` match against the ancestor's already-known literal value (Flight serializes plain-object Client Component props this way even though the payload isn't valid JSON/JS), and a dev-mode-only pattern that reads bracketed segment names straight out of embedded webpack module source paths (`.../[paramName]/...`). This fallback only runs after the fixed list fails, and only spends extra requests if harvesting actually finds a name not already tried — new `--rsc-param-bruteforce-limit <n>` (default `20`, `0` disables the fallback) caps how many harvested names get tried per candidate URL. (`lazyload`)
|
|
9
|
+
- New Next.js `lazyload` method `next_serverActionIdScan`: after every chunk is downloaded, scans each `.js` file for `createServerReference("<id>", ...)` call sites (matching the same ID-format validation `map`'s AST-based Server Action resolver already uses, `/^[0-9a-f]{40,}$/i`, but on raw chunk text — a lightweight signal available immediately at `lazyload` time, before `map` runs its full resolution) and writes any discovered IDs to `server_action_ids.json` in the target's output directory (`{ actionIdsByFile, allActionIds }`). This is endpoint enumeration only — no action is invoked; a Server Action ID shipped in a public chunk for a page the crawl couldn't reach unauthenticated is itself a disclosure signal (the same shape as the historical CVE-2026-64643 endpoint-ID disclosure). Opt out per-target via `--exclude-methods next_serverActionIdScan`. (`lazyload`)
|
|
10
|
+
- New `exploit` subcommand: `js-recon exploit -u <url> --cve <id>` attempts exploitation of known framework CVEs to surface hidden attack surface (e.g. bypassing Next.js middleware auth reveals admin-only JS chunks a normal crawl never sees), rather than just flagging vulnerabilities. `--list-cve` prints every supported CVE grouped by framework and sorted by ID. Covers CVE-2025-29927 and CVE-2026-64645 (Next.js), CVE-2025-30208 and CVE-2026-39363 (Vite), CVE-2026-71320 and CVE-2026-71315/CVE-2026-53721 (Nuxt), CVE-2026-68945 (Angular), and CVE-2025-55182 "React2Shell" (React RSC). Findings write both a rich `exploit.json` (with any newly discovered URLs) and an `EngineOutput`-compatible file consumable by `report`'s new `--exploit-json` flag, which renders exploit findings in the existing HTML/SQLite report alongside `analyze`'s findings. Two of the eight CVEs (`CVE-2026-71320`, `CVE-2025-55182`) are RCE-class — their proof executes a real command server-side via `--exec-cmd` (default `id`); this is intentional, active exploitation, not passive detection, and should only be run against targets you're authorized to test. (`exploit`, `report`)
|
|
11
|
+
|
|
12
|
+
- `--research`/`--research-output <file>` (`lazyload`, `run`) is now supported for every framework the tool detects, not just Next.js. Vue, Nuxt, Svelte, Angular, and React crawls now record a technique-name → discovered-URL-list mapping and write it to the research output file, mirroring the existing Next.js `NextJsCrawler.techniqueEfficiencyMapping` behavior. (`lazyload`)
|
|
13
|
+
- New `generic` fallback tech in `lazyload` for sites running no supported framework: previously an undetected framework triggered a separate Puppeteer pass just to watch loaded requests and retry framework detection, and if that still found nothing the target was otherwise left with only whatever the browser happened to load. `generic` now recursively crawls the site's own `<a href>`/`<iframe src>` links, plus absolute URLs embedded in any other attribute value such as an `onclick`-driven `window.open(...)` popup (breadth-first, capped by `--max-pages`, downloading JS incrementally per page) rather than stopping at the landing page, since the JS a site's homepage references is rarely all the JS the site has. Unless `-s`/`--strict-scope` is set, the crawl's default scope is now the host reached after following redirects from `-u` (new `--max-redirects` flag, default 20) instead of the unrestricted `*` default used elsewhere. On every page, `generic` extracts `<script src>`/inline scripts/`<link rel="modulepreload">` the same way the framework crawlers do (decoding `data:` URI script sources; skipping `<script type="...">` values that indicate non-JS content, e.g. `application/ld+json`/`speculationrules`), and additionally walks every HTML attribute value, resolving each with the `URL` constructor and — for any URL with a path segment ending in `.js` (catching cachebuster-suffixed paths like `.../beacon.min.js/v124/token` that don't end in `.js` themselves) — confirms it's actually JavaScript via its response `Content-Type` (accepting `text/javascript` per RFC 9239, plus RFC 4329's now-obsoleted `application/javascript`/`application/ecmascript` and other legacy variants) rather than trusting the extension alone. `generic` is also now seeded with every request tech detection's own Puppeteer session intercepted while live-rendering the page — this catches JS requested only because a runtime-injected script asked for it (e.g. a bot-mitigation script self-injecting its own next stage via `element.innerHTML`), which no static-fetch crawl could ever see. A new `--strings` flag chains the `strings` module into the crawl to catch JS referenced only as a string literal inside an already-downloaded file (e.g. a plugin config's `"pdfWorker": "https://.../pdf.worker.js"`), resolving each extracted string against the URL the file it was found in was itself downloaded from, and recursing (`--strings-max-iterations`, default 5) until a pass finds nothing new. `run` continues to only download JS for this tech, same as any other tech outside its supported list. (`lazyload`)
|
|
14
|
+
- `generic` tech now detects content stagnation on effectively unbounded sites (blogs, news feeds) that keep serving byte-identical JS under a different, cache-busted URL on every page — a pattern the existing URL-level dedup doesn't catch, which previously burned the full `--max-pages`/`--lazyload-timeout` budget on a site whose real JS surface was already fully mapped. New flags `--stagnation-timein <mins>` (default 30, `0` disables the feature), `--stagnation-percentage <percent>` (default 80), and `--stagnation-monitor <mins>` (default 1) control a debounced check: once one content hash accounts for `--stagnation-percentage`% of everything discovered so far, the crawl arms a pending state rather than stopping immediately — if a genuinely new content hash appears within the next `--stagnation-monitor` interval, monitoring resets; only if the same dominant hash persists with no new content does the crawl stop early. New exit code 30 if `--stagnation-timein` exceeds `--lazyload-timeout`, since stagnation monitoring could then never trigger before the whole crawl times out. (`lazyload`)
|
|
15
|
+
- New `--verbose` flag (`lazyload`, `run`) gates the file-write error message previously always printed when a downloaded JS chunk fails to write to disk (`[!] Failed to write file: <path>`). It is now silent by default and only shown with `--verbose`; no other error messages are affected. (`lazyload`)
|
|
16
|
+
- New `--determine-compatible-version`/`--apply-compatible-versions` flags (`analyze`) report or auto-correct the `js_recon_version`/`js_recon_max_version` a rule file actually requires, computed from a hand-maintained map (`src/utility/ruleVersionMap.ts`) of which tool version introduced each schema/engine feature (tech values, rule types, step sub-fields). Previously rule authors had to guess the compatibility string by hand, which could under- or over-restrict a rule relative to what it actually uses. Rules also now support an optional `js_recon_max_version` field for features that have since been retired; version-compatibility mismatches reported by `--determine-compatible-version` reuse exit code 20 ("invalid rules found"), same as schema errors. (`analyze`)
|
|
17
|
+
- `run`: added `--sj`/`--sj-bin`/`--sj-args` to integrate [swagger-jacker](https://github.com/AlexPistola/swagger-jacker) against the generated OpenAPI output after `report`; also available standalone on `report`. Exits with code 31 if the `sj` binary can't be found and `--sj-bin` wasn't given. (`run`, `report`)
|
|
18
|
+
- `run`: added `--web-stats-dashboard`/`--web-stats-port` — an optional local HTTP dashboard showing live per-target progress (current step, running/completed/skipped/errored) while a batch run is in flight. (`run`)
|
|
19
|
+
- `map`/`run`: `--ai-provider` now accepts `anthropic` in addition to `openai`; the option and its API key flag are renamed `--ai-api-key` (was `--openai-api-key`) to reflect the broader provider choice. (`map`, `run`)
|
|
20
|
+
- New CI workflow `.github/workflows/framework-detection-smoke-test.yaml` runs `fingerprint` against a matrix of lab apps (Next.js, Vue, Nuxt, SvelteKit, Angular, React/Vite, React/webpack) from `js-recon-labs/detection/*` and asserts each is correctly identified, verified by the new `scripts/framework-detect-smoke-test.js`. The existing `rules-smoke-test.yaml` only exercised the rule engine against a single Next.js app; this closes the gap for tech-detection regressions across every other supported framework/bundler. Runs on push/PR to `dev`/`main` and after a release is published. (`ci`)
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- `downloadFilesUtil.ts`/`DownloadQueue` (used by every framework crawler except `generic`) determined a downloaded file's on-disk name by checking only the URL's final `/`-separated path segment for a recognized extension, with a fallback loop that scanned every segment but was unreachable in practice — it lived in a `catch` block after a regex `.match()` call that returns `undefined` on no match rather than throwing. URLs where a token or cachebuster segment follows the actual filename (e.g. `.../beacon.min.js/v124/token`) were logged as `Could not determine filename for URL: ... Skipping.` and never downloaded, even though `generic`'s own downloader already handled this exact shape. Filename resolution is now handled by dev's `getSanitizedAssetFilename`/`resolveAssetOutputDirectory` helpers (`src/utility/outputPath.ts`), which already scan every path segment for the first one ending in a recognized extension. (`lazyload`)
|
|
25
|
+
- `run`'s Ctrl-C interrupt menu could show a stray leftover message from the step that was in flight when the interrupt fired: `Promise.race` doesn't cancel the loser, so the interrupted step's own promise kept running in the background and could still call `console.log`/`console.error` while the menu/prompt was on screen, interleaving its output with the prompt. All ad-hoc `console.log`/`console.error` calls across the CLI have been replaced with a new `printMsg(MSG.Level, message)` helper (`src/utility/printMsg.ts`) that funnels every message through one call site; `run/interruptHandler.ts` now calls `lockPrintMsg()` before showing the menu and `unlockPrintMsg()` after the choice is read, so any message from an orphaned in-flight step is silently discarded instead of printing over the prompt. (`run`)
|
|
26
|
+
- `checkAssignmentExist`/`findMemberExpressionAssignment` (used by rules like `detect_postMessage_innerHtml_sink` and `detect_postMessage_function_href`) crashed `analyze`/`run` entirely with `SES_UNHANDLED_REJECTION: Couldn't find a Program` when the resolved `postMessage` handler's sensitive assignment was nested inside an `if` block. The helper called `@babel/traverse`'s scope-aware form with a raw `File`/`Program` AST node passed in place of a real `Scope` instance, which broke Babel's internal scope-chain construction for some node shapes. Fixed by traversing with `noScope: true` instead, since the helper never reads `path.scope`. (`analyze`)
|
|
27
|
+
- The response cache (`makeReq.ts`) stored a live `Headers` object directly into data later passed to `JSON.stringify()`. `Headers` has no own enumerable properties, so this silently serialized to `{}` on every cache write, discarding all response headers (not just `Content-Type`) for any URL cached earlier in a run. Any header-dependent check that hit a cached URL a second time (e.g. `generic`'s Content-Type-based JS confirmation) could silently fail depending on whether something upstream had already cached that URL. Fixed by converting to a plain object (`Object.fromEntries(headers.entries())`) before serialization. (`utility`)
|
|
28
|
+
- `checkVueJS.ts`'s last-resort tech-detection fallback scanned every externally-referenced `<script src>`, including cross-origin third-party scripts, for the substring `__vue`. A third-party widget that internally bundles Vue for its own UI could cause a site with no Vue anywhere in its own code to be misclassified as Vue.js. The fallback now only scans same-origin scripts. (`lazyload`)
|
|
29
|
+
- `strings`: a single file that fails to parse as JS (e.g. non-JS content saved with a `.js` extension) no longer aborts extraction for every other file in the scan — the parse error is now caught, logged, and skipped per-file. (`strings`)
|
|
30
|
+
- `lazyload --strings` (generic tech): each recursive strings-discovery pass rescans the same (ever-growing) output directory, since the `strings` module has no incremental-scan mode. Every already-confirmed URL from a prior pass was being re-confirmed via a fresh live `GET` request on every subsequent pass, compounding badly on large multi-hundred-page crawls. Already-known URLs are now filtered out before the Content-Type confirmation step, not after. (`lazyload`)
|
|
31
|
+
- `DownloadQueue`'s write-error log interpolated the raw error object (`${writeErr}`). For a `prettier.format()` parse failure the thrown `SyntaxError`'s message has Babel's codeframe appended after the first line, and on minified JS (a single giant line) that codeframe is the entire file — dumping the whole source to the terminal instead of just the error. The logged message is now truncated to the first line (`String(writeErr).split("\n")[0]`), e.g. `SyntaxError: Missing semicolon. (2:4)`. (`lazyload`)
|
|
32
|
+
- `map`'s per-file size guard (`MAX_MAP_FILE_SIZE_BYTES`, present identically across `getReactConnections.ts`/`getViteConnections.ts`/`getAngularConnections.ts` and the shared fetch/XHR/HTTP-client resolvers) skipped any file over 1.5 MB with no fallback chunk, so a single large un-split app bundle vanished from `mapped.json` entirely — `refactor` then ran against whatever small chunks were left instead of the app, reporting near-zero recovery. Raised the cap to 8 MB; the guard's purpose is capping the many-large-files case (ad-heavy sites), not a single reasonably-large main bundle. Also hardens `run`'s CS-MAST-S bundler detection (react-webpack vs react-vite): adds a cheap literal bundler-runtime-marker pre-check that short-circuits the structural comparison when unambiguous, and raises the random sample size to cover the current signature bucket, since undersampling could previously flip which tech "won" between identical runs against the same bundle. (`map`, `run`)
|
|
33
|
+
- The startup banner logo rendered visibly distorted (stretched, overlapping the following text) in Kitty-protocol terminals (Kitty, Ghostty). Root cause was in `@shriyanss/cli-print-img`'s Kitty renderer, which specified both `c` (columns) and `r` (rows) in the same escape sequence — per the Kitty Graphics Protocol, giving both stretches the image to fill that exact cell box instead of preserving its aspect ratio, and it also suppressed cursor movement without advancing by the actual rendered height. Bumped `@shriyanss/cli-print-img` to `1.1.1`, which fixes both issues upstream. (`cli`, `banner`)
|
|
34
|
+
- `map`'s Next.js webpack chunk-code extraction (`getWebpackConnections.ts`) stripped a chunk's numeric-ID object-literal prefix (e.g. `0:function(e,t,n){...}` → `function webpack_0(e,t,n){...}`) via two regexes that both assumed the minifier inserts whitespace between the colon/`function` keyword and the following token. Real-world minified output commonly omits that whitespace, so the prefix was left in place — invalid syntax that failed to parse downstream in `refactor -t next-webpack`, silently dropping the module instead of processing it. Also affected `refactor`'s CS-MAST library classification, since a chunk that never parses can never be checked against the signature set either. Fixed by relaxing both regexes' whitespace assumption (`\s+` → `\s*`, plus a missing `\s` escape in the arrow-form regex). Verified against a real-world target: eliminated all parse failures on a previously 96%-failing chunk set and raised its library-classification rate from ~3% to 94%. Follow-up: the arrow-form regex still required a literal `(` immediately after the numeric-ID colon, missing JS's single-parameter arrow shorthand with no parens (`3562:e=>{...}`, common in lodash-style utility functions). Fixed by matching either `(` or a bare identifier followed by `=>` via lookahead, stripping only the `id:` prefix and leaving the arrow's own param syntax untouched. (`map`)
|
|
35
|
+
|
|
36
|
+
**Note:** `post-1.4.1`'s independent proxy rework (renaming `api-gateway` to `proxy`, subcommand-per-provider design) was superseded during the `post-1.4.1` → `dev` promotion merge by `dev`'s own concurrent proxy rework, which reached the same rename via a single `proxy` command with `--proxy-method <aws|socks|http|oxylabs>` plus CloudFront/Cloudflare firewall detection, crash-safe AWS Gateway cleanup, and full test coverage — see the `1.4.1-beta.2` entry below for the proxy rename actually shipped. (`proxy`)
|
|
37
|
+
|
|
38
|
+
## 1.4.4 - 2026-08-03
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- `run`, `lazyload`, `fingerprint`: `-u/--url` now accepts one URL, the flag repeated multiple times, a comma-separated list of URLs, or a target file (previously a single URL or a single target file). Precedence across environment variable, CLI flag, and YAML config is preserved for all forms. (`run`, `lazyload`, `fingerprint`)
|
|
43
|
+
- `run`: output directory handling is now non-destructive by default. An existing **empty** output directory is reused; an existing **non-empty** one is left untouched and js-recon allocates the next available sibling (`output-2`, `output-3`, ...) instead. `--output-overwrite` is now scoped to canonical, js-recon-owned directories — it rejects symlinked or otherwise protected paths rather than overwriting them. Concurrent runs targeting the same output coordinate via PID/host-aware atomic locks with stale-owner recovery and signal cleanup, so simultaneous invocations no longer race on the same directory. (`run`)
|
|
44
|
+
- Added application-level YAML configuration. On first use, js-recon creates `~/.config/js-recon/config.yaml` (restrictive permissions) with a key for every command option; an alternate file can be selected with the new top-level `--config <file>` flag (before the subcommand) or `JS_RECON_CONFIG`. Values resolve as environment variable → CLI flag → YAML config → built-in default, using `JS_RECON_<COMMAND>_<OPTION>` for any command option (e.g. `JS_RECON_RUN_THREADS=8`). Targets can also be configured as a YAML list under `commands.<command>.url`; an env value or CLI `-u` replaces the whole list per the usual precedence. See `config.dist.yaml` for the full schema. The existing command-specific `proxy --config` / `mcp --config` flags are unaffected — place the application-level `--config` before the subcommand to avoid ambiguity. (`config`, `run`, `lazyload`, `fingerprint`)
|
|
45
|
+
- `run`/`lazyload`: added opt-in Oxylabs recovery for strongly corroborated CDN/WAF blocks, enabled via the new `--oxylabs-waf-fallback` flag once `oxylabs.username`/`oxylabs.password` are set in an explicitly selected YAML config (`JS_RECON_OXYLABS_USERNAME`/`_PASSWORD`/`_COUNTRY` override the YAML values unless `--ignore-proxy-env` is set). Direct requests remain the default path; Oxylabs is only used after direct header-based strategies are exhausted, bounded by new `--oxylabs-fallback-max-requests` (default `10`, per origin), `--oxylabs-fallback-max-total` (default `100`, per run), and `--oxylabs-fallback-max-origins` (default `25`, per run) flags. (`run`, `lazyload`, `proxy`)
|
|
46
|
+
- React/webpack chunk downloads now show a responsive, TTY-aware aggregate progress bar; piped/CI output stays compact with no per-file error spam. Download/response/formatting/write failures are tracked independently and cooperative cancellation is honored throughout discovery, requests, browser fallback, cache access, and post-processing. URL host/path/filename sanitization is now centralized to prevent malformed JS-expression paths, queries, ports, IPv6 hosts, traversal attempts, or hostile source-map entries from escaping or overwriting output boundaries. (`lazyload`, `run`)
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- `run`: batch mode (`-u <target-file>`) aborted the entire run if any single line in the target file was malformed, even when other lines were valid targets that appeared before it — no output was produced at all. A malformed line is now logged with a `[!]` warning and skipped; the rest of the file's valid targets are still processed. The run only fails outright if the target file contains zero valid targets. (`run`)
|
|
51
|
+
- `checkFireWallBlocking` (used by `proxy --feasibility` and the AWS API Gateway request path in `makeReq.ts`) hardcoded a fake `503` status and never passed real response headers to `detectBlockedResponse`'s CDN-header-corroborated detection path, so a genuine `403` "Access Denied" WAF/CDN block (e.g. a real Cloudflare `cf-ray` header) was silently missed even though the underlying detector correctly flags it when given real inputs. `checkFireWallBlocking` now accepts the real HTTP status and headers at all three call sites; when they genuinely aren't available, the status-corroborated detection path is skipped rather than spoofed against the wrong status. (`proxy`)
|
|
52
|
+
- `strings`: the main per-file parse loop had no `try/catch`, unlike the `___subsequent_requests` branch a few lines above (and unlike `sourcemaps`/`cs-mast`). A single malformed or truncated `.js` file among otherwise-valid files threw an uncaught `SyntaxError` and aborted the entire strings extraction with no output at all — including for the `run` pipeline's steps 2/4/4.6. Unparseable files are now skipped with a warning instead of crashing the run. (`strings`, `run`)
|
|
53
|
+
- `run`: requesting `-o <path>` where `<path>` already exists as a regular file (not a directory) silently fell through to the output-reservation retry loop and created `<path>-2` instead of reporting the problem, unless `--output-overwrite` was passed — with `--output-overwrite` it already errored correctly, but without it (the default) there was no indication the requested path wasn't a directory at all. A file at the output path is now rejected outright regardless of `--output-overwrite`. (`run`)
|
|
54
|
+
- `lazyload`/`run`: the output-directory host-nesting heuristic (used to avoid double-nesting a batch target's already-host-owned per-target directory) was applied unconditionally at every call site instead of only the batch per-target root it was written for. A single-target `-o <dir>` run whose directory basename happened to match the sanitized target host silently collapsed the output layout instead of nesting under `<dir>/<host>/...`. The heuristic is now gated behind an explicit batch-only flag threaded through lazyload/crawler/download-queue internals, so single-target runs always nest correctly. (`lazyload`, `run`)
|
|
55
|
+
- `proxy`: the AWS API Gateway resource path (`resourcePathPart`) mixed a per-call random UUID into its hash, so it was never the same twice for the same URL — the existing-resource reuse lookup could never match a previously-provisioned resource, and every proxied request via the `aws` proxy method created a brand-new API Gateway resource instead of reusing one. It's now derived from the URL alone (still SHA-256) so resource reuse works across repeat requests to the same URL. (`proxy`)
|
|
56
|
+
|
|
3
57
|
## 1.4.3 - 2026-07-30
|
|
4
58
|
|
|
5
59
|
### Added
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Contributing to js-recon
|
|
2
|
+
|
|
3
|
+
For the full contributor guide — cloning, branch/PR workflow, codebase structure — see
|
|
4
|
+
[js-recon.io/contributing](https://js-recon.io/contributing). This file covers the policies that
|
|
5
|
+
apply once you're making a change here.
|
|
6
|
+
|
|
7
|
+
## Testing is required for new functionality
|
|
8
|
+
|
|
9
|
+
New functionality must ship with unit and/or smoke tests. See
|
|
10
|
+
[`contributing/testing.md`](contributing/testing.md) for how to write unit tests (Vitest), fuzz
|
|
11
|
+
tests (fast-check, for anything that parses untrusted bundle input), and smoke tests (the
|
|
12
|
+
`rules-smoke-test` CI workflow).
|
|
13
|
+
|
|
14
|
+
## Keep js-recon-docs in sync
|
|
15
|
+
|
|
16
|
+
Changes that affect user-facing behavior, CLI flags, exit codes, or install/usage instructions must
|
|
17
|
+
include a corresponding update to [`js-recon-docs`](https://github.com/js-recon/js-recon-docs) —
|
|
18
|
+
either in the same PR or a linked follow-up PR. Docs-only fixes don't need a corresponding js-recon
|
|
19
|
+
change.
|
|
20
|
+
|
|
21
|
+
## Static analysis
|
|
22
|
+
|
|
23
|
+
CI runs [ESLint](https://eslint.org/) (with
|
|
24
|
+
[`eslint-plugin-security`](https://github.com/eslint-community/eslint-plugin-security)) and
|
|
25
|
+
[CodeQL](https://codeql.github.com/) on every push and pull request. Run `npm run lint` locally
|
|
26
|
+
before pushing.
|
|
27
|
+
|
|
28
|
+
## Reporting vulnerabilities
|
|
29
|
+
|
|
30
|
+
Do not open a public issue for a security vulnerability — see [`SECURITY.md`](SECURITY.md) for the
|
|
31
|
+
reporting process and response SLAs. Bug reports and feature/tech-support requests use the GitHub
|
|
32
|
+
Issues templates linked from the [contributing page](https://js-recon.io/contributing).
|
package/Dockerfile
CHANGED
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# JS Recon
|
|
2
2
|
|
|
3
|
-
     
|
|
3
|
+
      [](https://score.getplumber.io/github.com/js-recon/js-recon) [](https://www.bestpractices.dev/projects/13954)
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
6
|
<a href="https://js-recon.io">
|
|
@@ -74,6 +74,58 @@ To launch a quick assesment against a target, the `run` module can be used to au
|
|
|
74
74
|
js-recon run -u https://app.example.com
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
+
`run`, `lazyload`, and `fingerprint` accept one target, repeated `-u` options, a comma-separated list,
|
|
78
|
+
or a text file containing one HTTP(S) URL per line:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
js-recon run -u https://one.example.com -u https://two.example.com
|
|
82
|
+
js-recon run -u 'https://one.example.com,https://two.example.com'
|
|
83
|
+
js-recon run -u ./targets.txt
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
For `run`, an existing empty output directory is reused. If it contains files, js-recon preserves it
|
|
87
|
+
and selects the next available sibling (`output-2`, `output-3`, and so on). Use
|
|
88
|
+
`--output-overwrite` only when the contents of a previously created js-recon output should be
|
|
89
|
+
replaced. Unowned directories are never recursively cleared.
|
|
90
|
+
|
|
91
|
+
## Configuration
|
|
92
|
+
|
|
93
|
+
On first use, js-recon creates `~/.config/js-recon/config.yaml` with restrictive permissions and a key for every command option. Values resolve in this order:
|
|
94
|
+
|
|
95
|
+
1. Environment variables
|
|
96
|
+
2. Command-line flags
|
|
97
|
+
3. YAML configuration
|
|
98
|
+
4. Built-in defaults
|
|
99
|
+
|
|
100
|
+
Use `JS_RECON_<COMMAND>_<OPTION>` for any command option—for example, `JS_RECON_RUN_THREADS=8`—or select another config file before the subcommand:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
js-recon --config ./operator.yaml run -u https://app.example.com
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Targets may be configured as a YAML list. An environment value or one or more command-line `-u`
|
|
107
|
+
flags replace the entire YAML list according to the precedence above:
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
commands:
|
|
111
|
+
run:
|
|
112
|
+
url:
|
|
113
|
+
- https://one.example.com
|
|
114
|
+
- https://two.example.com
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
See [`config.dist.yaml`](config.dist.yaml) for the complete schema. The existing `proxy --config` and `mcp --config` flags remain command-specific; place the application-level `--config` before those subcommands to avoid ambiguity.
|
|
118
|
+
|
|
119
|
+
Oxylabs CDN/WAF fallback is opt-in. Add non-empty `oxylabs.username` and `oxylabs.password` values to an explicitly selected YAML config, then enable `--oxylabs-waf-fallback` on `run` or `lazyload`. Direct requests remain the default; only strongly identified CDN/WAF blocks are retried through Oxylabs. The default paid-request limits are 10 per origin, 100 total, and 25 distinct origins per run:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
js-recon --config ./operator.yaml run \
|
|
123
|
+
--oxylabs-waf-fallback \
|
|
124
|
+
-u https://app.example.com
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`JS_RECON_OXYLABS_USERNAME`, `JS_RECON_OXYLABS_PASSWORD`, and `JS_RECON_OXYLABS_COUNTRY` override their YAML values unless `--ignore-proxy-env` is set.
|
|
128
|
+
|
|
77
129
|
## Commands
|
|
78
130
|
|
|
79
131
|
`js-recon` provides a suite of commands for comprehensive JavaScript analysis. For detailed usage and examples, please refer to its full documentation.
|
|
@@ -87,6 +139,7 @@ js-recon run -u https://app.example.com
|
|
|
87
139
|
| `proxy` | Routes requests through AWS API Gateway, SOCKS5/HTTP, or Oxylabs proxies. | [Read Docs](https://js-recon.io/docs/docs/modules/proxy) |
|
|
88
140
|
| `run` | Runs all analysis modules automatically on a target. | [Read Docs](https://js-recon.io/docs/docs/modules/run) |
|
|
89
141
|
| `analyze` | Analyzes the code. | [Read Docs](https://js-recon.io/docs/docs/modules/analyze) |
|
|
142
|
+
| `exploit` | Attempts exploitation of known framework CVEs to discover new attack surface. | [Read Docs](https://js-recon.io/docs/docs/modules/exploit) |
|
|
90
143
|
| `report` | Generates a report from the analysis modules. | [Read Docs](https://js-recon.io/docs/docs/modules/report) |
|
|
91
144
|
| `mcp` | AI-powered interactive CLI, one-shot chat, and MCP stdio server. | [Read Docs](https://js-recon.io/docs/docs/modules/mcp) |
|
|
92
145
|
| `fingerprint` | Detects the JavaScript framework used by a target URL (JSON/JSONL output). | [Read Docs](https://js-recon.io/docs/docs/modules/fingerprint) |
|
|
@@ -105,7 +158,7 @@ js-recon run -u https://app.example.com
|
|
|
105
158
|
- Map feature analyzes the JS files and outputs it to a JSON file. An interactive mode can be then used to analyze it
|
|
106
159
|
- Reconstruct HTTP requests that the app makes to the server, and output them to the OpenAPI spec
|
|
107
160
|
- Run analyze to find potential issues in JS code and the HTTP requests the app makes
|
|
108
|
-
- Generate a report from the analyze module
|
|
161
|
+
- Generate a report from the analyze module (optional active endpoint probing via `sj`/swagger-jacker integration using `--sj`)
|
|
109
162
|
|
|
110
163
|
## Example Scenario
|
|
111
164
|
|
package/SECURITY.md
CHANGED
|
@@ -17,7 +17,7 @@ Include in your report:
|
|
|
17
17
|
- Affected version(s)
|
|
18
18
|
- Any suggested mitigations, if known
|
|
19
19
|
|
|
20
|
-
You can expect an acknowledgement within **72 hours
|
|
20
|
+
You can expect an acknowledgement within **72 hours**, and no later than **14 days** from the initial report. If a vulnerability is confirmed, a fix will be prioritized based on severity, with a target of **60 days** to ship a patch for confirmed vulnerabilities affecting a publicly released version.
|
|
21
21
|
|
|
22
22
|
## Scope
|
|
23
23
|
|
|
@@ -7,7 +7,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import chalk from "chalk";
|
|
11
10
|
import parser from "@babel/parser";
|
|
12
11
|
import _traverse from "@babel/traverse";
|
|
13
12
|
import _generator from "@babel/generator";
|
|
@@ -19,6 +18,7 @@ import { resolveFunctionIdentifier } from "../helpers/engineHelpers/resolveFunct
|
|
|
19
18
|
import { findMemberExpressionAssignment } from "../helpers/engineHelpers/findMemberExpressionAssignment.js";
|
|
20
19
|
import { findDirectAssignment } from "../helpers/engineHelpers/findDirectAssignment.js";
|
|
21
20
|
import { computeTaint, sinkConsumesTaint } from "../helpers/engineHelpers/taintFlow.js";
|
|
21
|
+
import { printMsg, MSG } from "../../utility/printMsg.js";
|
|
22
22
|
/**
|
|
23
23
|
* ESQuery-based AST analysis engine for detecting code patterns using custom rules.
|
|
24
24
|
*
|
|
@@ -32,7 +32,7 @@ import { computeTaint, sinkConsumesTaint } from "../helpers/engineHelpers/taintF
|
|
|
32
32
|
*/
|
|
33
33
|
const esqueryEngine = (rule, mappedJsonData) => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
34
|
var _a, _b;
|
|
35
|
-
|
|
35
|
+
const findings = [];
|
|
36
36
|
for (const chunk of Object.values(mappedJsonData)) {
|
|
37
37
|
// first of all, load the code in ast
|
|
38
38
|
let ast;
|
|
@@ -46,7 +46,7 @@ const esqueryEngine = (rule, mappedJsonData) => __awaiter(void 0, void 0, void 0
|
|
|
46
46
|
catch (_c) {
|
|
47
47
|
continue;
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
const matchList = {};
|
|
50
50
|
const completedSteps = new Set();
|
|
51
51
|
// Cache taint info per "source step name" so we don't recompute when several
|
|
52
52
|
// sink steps share the same source step.
|
|
@@ -138,6 +138,7 @@ const esqueryEngine = (rule, mappedJsonData) => __awaiter(void 0, void 0, void 0
|
|
|
138
138
|
}
|
|
139
139
|
else if (step.regexMatch) {
|
|
140
140
|
// Scan all StringLiteral/TemplateLiteral nodes in the chunk for values matching the regex
|
|
141
|
+
// eslint-disable-next-line security/detect-non-literal-regexp -- pattern comes from a loaded rule YAML file — same trust model as the rest of the rule engine, not user/network input
|
|
141
142
|
const pattern = new RegExp(step.regexMatch.pattern);
|
|
142
143
|
const foundNodes = [];
|
|
143
144
|
_traverseDefault(ast, {
|
|
@@ -165,7 +166,7 @@ const esqueryEngine = (rule, mappedJsonData) => __awaiter(void 0, void 0, void 0
|
|
|
165
166
|
const toMatch = step.checkAssignmentExist.type;
|
|
166
167
|
const memberExpression = step.checkAssignmentExist.memberExpression;
|
|
167
168
|
if (selectedNode && memberExpression) {
|
|
168
|
-
const assignmentNode = findMemberExpressionAssignment(selectedNode, toMatch
|
|
169
|
+
const assignmentNode = findMemberExpressionAssignment(selectedNode, toMatch);
|
|
169
170
|
if (assignmentNode) {
|
|
170
171
|
matchList[step.name] = { node: assignmentNode, scope: ast };
|
|
171
172
|
completedSteps.add(step.name);
|
|
@@ -188,18 +189,18 @@ const esqueryEngine = (rule, mappedJsonData) => __awaiter(void 0, void 0, void 0
|
|
|
188
189
|
for (const reportNode of nodesToReport) {
|
|
189
190
|
const code = generator(reportNode).code;
|
|
190
191
|
if (rule.severity === "info") {
|
|
191
|
-
|
|
192
|
+
printMsg(MSG.Header, message);
|
|
192
193
|
}
|
|
193
194
|
else if (rule.severity === "low") {
|
|
194
|
-
|
|
195
|
+
printMsg(MSG.Warn, message);
|
|
195
196
|
}
|
|
196
197
|
else if (rule.severity === "medium") {
|
|
197
|
-
|
|
198
|
+
printMsg(MSG.Info, message);
|
|
198
199
|
}
|
|
199
200
|
else if (rule.severity === "high") {
|
|
200
|
-
|
|
201
|
+
printMsg(MSG.Err, message);
|
|
201
202
|
}
|
|
202
|
-
|
|
203
|
+
printMsg(MSG.Plain, highlight(code, {
|
|
203
204
|
language: "javascript",
|
|
204
205
|
ignoreIllegals: true,
|
|
205
206
|
theme: undefined,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"astEngine.js","sourceRoot":"","sources":["../../../src/analyze/engine/astEngine.ts"],"names":[],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"astEngine.js","sourceRoot":"","sources":["../../../src/analyze/engine/astEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,8 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import chalk from "chalk";
|
|
11
10
|
import { cs_mast_init, parseSignature, ParseError } from "@shriyanss/cs-mast";
|
|
11
|
+
import { printMsg, MSG } from "../../utility/printMsg.js";
|
|
12
12
|
/**
|
|
13
13
|
* Walk all AdapterNode descendants post-order and check if any node's
|
|
14
14
|
* computedHash equals the target hex hash. The _signatureMap built by
|
|
@@ -60,7 +60,7 @@ const csMastSEngine = (rule, mappedJsonData) => __awaiter(void 0, void 0, void 0
|
|
|
60
60
|
const { signature } = step.csMastS;
|
|
61
61
|
const parsed = parseSignature(signature);
|
|
62
62
|
if (!parsed) {
|
|
63
|
-
|
|
63
|
+
printMsg(MSG.Warn, `[!] cs-mast-s step "${step.name}" in rule "${rule.id}" has an invalid signature — skipping`);
|
|
64
64
|
continue;
|
|
65
65
|
}
|
|
66
66
|
const config = {
|
|
@@ -99,16 +99,16 @@ const csMastSEngine = (rule, mappedJsonData) => __awaiter(void 0, void 0, void 0
|
|
|
99
99
|
const matchedSigs = rule.steps.filter((s) => s.csMastS).map((s) => s.csMastS.signature);
|
|
100
100
|
const message = `[+] "${rule.name}" found in chunk ${chunk.id}`;
|
|
101
101
|
if (rule.severity === "info") {
|
|
102
|
-
|
|
102
|
+
printMsg(MSG.Header, message);
|
|
103
103
|
}
|
|
104
104
|
else if (rule.severity === "low") {
|
|
105
|
-
|
|
105
|
+
printMsg(MSG.Warn, message);
|
|
106
106
|
}
|
|
107
107
|
else if (rule.severity === "medium") {
|
|
108
|
-
|
|
108
|
+
printMsg(MSG.Info, message);
|
|
109
109
|
}
|
|
110
110
|
else if (rule.severity === "high") {
|
|
111
|
-
|
|
111
|
+
printMsg(MSG.Err, message);
|
|
112
112
|
}
|
|
113
113
|
findings.push({
|
|
114
114
|
ruleId: rule.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csMastSEngine.js","sourceRoot":"","sources":["../../../src/analyze/engine/csMastSEngine.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"csMastSEngine.js","sourceRoot":"","sources":["../../../src/analyze/engine/csMastSEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,7 +25,7 @@ import csMastSEngine from "./csMastSEngine.js";
|
|
|
25
25
|
*/
|
|
26
26
|
export const engine = (rule, mappedJsonData, openapiData, tech) => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
27
|
// first of all check what is rule type, and then check if the data for that is available or is undefined
|
|
28
|
-
|
|
28
|
+
const findings = [];
|
|
29
29
|
if (rule.type === "request") {
|
|
30
30
|
if (!openapiData) {
|
|
31
31
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyze/engine/index.ts"],"names":[],"mappings":";;;;;;;;;AAGA,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAG/C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAClB,IAAU,EACV,cAAkC,EAClC,WAAoC,EACpC,IAA6D,EAC1B,EAAE;IACrC,yGAAyG;IAEzG,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyze/engine/index.ts"],"names":[],"mappings":";;;;;;;;;AAGA,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAG/C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAClB,IAAU,EACV,cAAkC,EAClC,WAAoC,EACpC,IAA6D,EAC1B,EAAE;IACrC,yGAAyG;IAEzG,MAAM,QAAQ,GAAmB,EAAE,CAAC;IAEpC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,OAAO;QACX,CAAC;QAED,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,SAAS,GAAG,KAAK,CAAC;YACtB,CAAC;QACL,CAAC;QAED,IAAI,SAAS,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3D,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC;IACL,CAAC;SAAM,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,cAAc,EAAE,CAAC;YAClB,OAAO;QACX,CAAC;QAED,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,SAAS,GAAG,KAAK,CAAC;YACtB,CAAC;QACL,CAAC;QAED,IAAI,SAAS,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3D,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;QAC9D,CAAC;IACL,CAAC;SAAM,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACnC,IAAI,CAAC,cAAc,EAAE,CAAC;YAClB,OAAO;QACX,CAAC;QAED,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,SAAS,GAAG,KAAK,CAAC;YACtB,CAAC;QACL,CAAC;QAED,IAAI,SAAS,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3D,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;QAClE,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAA,CAAC;AAEF,eAAe,MAAM,CAAC"}
|