@js-recon/js-recon 1.4.4 → 2.0.1-alpha.2

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.
Files changed (440) hide show
  1. package/.claude-sync/sync.sh +1 -1
  2. package/.github/dependabot.yml +50 -0
  3. package/.github/workflows/build-and-prettify.yaml +49 -19
  4. package/.github/workflows/codeql.yml +33 -0
  5. package/.github/workflows/exploit-smoke-test.yaml +160 -0
  6. package/.github/workflows/framework-detection-smoke-test.yaml +135 -0
  7. package/.github/workflows/plumber.yml +20 -0
  8. package/.github/workflows/promote-js-recon.yml +5 -3
  9. package/.github/workflows/publish-js-recon.yml +31 -2
  10. package/.github/workflows/rules-smoke-test.yaml +13 -5
  11. package/.nvmrc +1 -0
  12. package/.plumber.yaml +151 -0
  13. package/CHANGELOG.md +55 -0
  14. package/CONTRIBUTING.md +32 -0
  15. package/Dockerfile +1 -0
  16. package/README.md +3 -2
  17. package/SECURITY.md +1 -1
  18. package/build/analyze/engine/astEngine.js +10 -9
  19. package/build/analyze/engine/astEngine.js.map +1 -1
  20. package/build/analyze/engine/csMastSEngine.js +6 -6
  21. package/build/analyze/engine/csMastSEngine.js.map +1 -1
  22. package/build/analyze/engine/index.js +1 -1
  23. package/build/analyze/engine/index.js.map +1 -1
  24. package/build/analyze/engine/requestEngine.js +6 -6
  25. package/build/analyze/engine/requestEngine.js.map +1 -1
  26. package/build/analyze/helpers/determineCompatibleVersion.js +70 -0
  27. package/build/analyze/helpers/determineCompatibleVersion.js.map +1 -0
  28. package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js +9 -3
  29. package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js.map +1 -1
  30. package/build/analyze/helpers/initRules.js +9 -9
  31. package/build/analyze/helpers/initRules.js.map +1 -1
  32. package/build/analyze/helpers/outputHelper.js +3 -3
  33. package/build/analyze/helpers/outputHelper.js.map +1 -1
  34. package/build/analyze/helpers/schemas.js +1 -0
  35. package/build/analyze/helpers/schemas.js.map +1 -1
  36. package/build/analyze/helpers/validate.js +9 -5
  37. package/build/analyze/helpers/validate.js.map +1 -1
  38. package/build/analyze/index.js +26 -16
  39. package/build/analyze/index.js.map +1 -1
  40. package/build/cliProgram.js +733 -0
  41. package/build/cliProgram.js.map +1 -0
  42. package/build/completion/index.js +247 -382
  43. package/build/completion/index.js.map +1 -1
  44. package/build/completion/introspect.js +17 -0
  45. package/build/completion/introspect.js.map +1 -0
  46. package/build/config/applicationConfig.js +3 -2
  47. package/build/config/applicationConfig.js.map +1 -1
  48. package/build/cs_mast/index.js +18 -17
  49. package/build/cs_mast/index.js.map +1 -1
  50. package/build/endpoints/gen_report/gen_json.js +2 -2
  51. package/build/endpoints/gen_report/gen_json.js.map +1 -1
  52. package/build/endpoints/gen_report/utility/iterate_n_store.js +1 -1
  53. package/build/endpoints/gen_report/utility/iterate_n_store.js.map +1 -1
  54. package/build/endpoints/index.js +12 -12
  55. package/build/endpoints/index.js.map +1 -1
  56. package/build/endpoints/next_js/client_jsFilesHref.js +3 -3
  57. package/build/endpoints/next_js/client_jsFilesHref.js.map +1 -1
  58. package/build/endpoints/next_js/client_jsonParse.js +4 -4
  59. package/build/endpoints/next_js/client_jsonParse.js.map +1 -1
  60. package/build/endpoints/next_js/client_mappedJsonFile.js +6 -6
  61. package/build/endpoints/next_js/client_mappedJsonFile.js.map +1 -1
  62. package/build/endpoints/next_js/client_subsequentRequests.js +5 -5
  63. package/build/endpoints/next_js/client_subsequentRequests.js.map +1 -1
  64. package/build/exploit/angular/cve-2026-68945.js +61 -0
  65. package/build/exploit/angular/cve-2026-68945.js.map +1 -0
  66. package/build/exploit/index.js +60 -0
  67. package/build/exploit/index.js.map +1 -0
  68. package/build/exploit/next/cve-2025-29927.js +65 -0
  69. package/build/exploit/next/cve-2025-29927.js.map +1 -0
  70. package/build/exploit/next/cve-2026-64645.js +51 -0
  71. package/build/exploit/next/cve-2026-64645.js.map +1 -0
  72. package/build/exploit/nuxt/cve-2026-71315.js +47 -0
  73. package/build/exploit/nuxt/cve-2026-71315.js.map +1 -0
  74. package/build/exploit/nuxt/cve-2026-71320.js +114 -0
  75. package/build/exploit/nuxt/cve-2026-71320.js.map +1 -0
  76. package/build/exploit/react/cve-2025-55182.js +116 -0
  77. package/build/exploit/react/cve-2025-55182.js.map +1 -0
  78. package/build/exploit/registry/cveRegistry.js +115 -0
  79. package/build/exploit/registry/cveRegistry.js.map +1 -0
  80. package/build/exploit/types.js +2 -0
  81. package/build/exploit/types.js.map +1 -0
  82. package/build/exploit/utility/compareResponses.js +29 -0
  83. package/build/exploit/utility/compareResponses.js.map +1 -0
  84. package/build/exploit/utility/outputHelper.js +22 -0
  85. package/build/exploit/utility/outputHelper.js.map +1 -0
  86. package/build/exploit/utility/rawRequest.js +56 -0
  87. package/build/exploit/utility/rawRequest.js.map +1 -0
  88. package/build/exploit/utility/sandboxRce.js +49 -0
  89. package/build/exploit/utility/sandboxRce.js.map +1 -0
  90. package/build/exploit/utility/toEngineOutput.js +28 -0
  91. package/build/exploit/utility/toEngineOutput.js.map +1 -0
  92. package/build/exploit/utility/wsClient.js +78 -0
  93. package/build/exploit/utility/wsClient.js.map +1 -0
  94. package/build/exploit/vite/cve-2025-30208.js +44 -0
  95. package/build/exploit/vite/cve-2025-30208.js.map +1 -0
  96. package/build/exploit/vite/cve-2026-39363.js +60 -0
  97. package/build/exploit/vite/cve-2026-39363.js.map +1 -0
  98. package/build/fingerprint/index.js +3 -2
  99. package/build/fingerprint/index.js.map +1 -1
  100. package/build/globalConfig.js +2 -2
  101. package/build/globalConfig.js.map +1 -1
  102. package/build/index.js +5 -596
  103. package/build/index.js.map +1 -1
  104. package/build/lazyLoad/angular/angular_getFromPageSource.js +3 -3
  105. package/build/lazyLoad/angular/angular_getFromPageSource.js.map +1 -1
  106. package/build/lazyLoad/downloadFilesUtil.js +14 -11
  107. package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
  108. package/build/lazyLoad/downloadQueue.js +9 -1
  109. package/build/lazyLoad/downloadQueue.js.map +1 -1
  110. package/build/lazyLoad/downloadResponse.js +1 -0
  111. package/build/lazyLoad/downloadResponse.js.map +1 -1
  112. package/build/lazyLoad/generic/generic_crawlPages.js +186 -0
  113. package/build/lazyLoad/generic/generic_crawlPages.js.map +1 -0
  114. package/build/lazyLoad/generic/generic_downloadFiles.js +81 -0
  115. package/build/lazyLoad/generic/generic_downloadFiles.js.map +1 -0
  116. package/build/lazyLoad/generic/generic_extractLinks.js +79 -0
  117. package/build/lazyLoad/generic/generic_extractLinks.js.map +1 -0
  118. package/build/lazyLoad/generic/generic_getScriptTags.js +152 -0
  119. package/build/lazyLoad/generic/generic_getScriptTags.js.map +1 -0
  120. package/build/lazyLoad/generic/generic_importMapDiscovery.js +87 -0
  121. package/build/lazyLoad/generic/generic_importMapDiscovery.js.map +1 -0
  122. package/build/lazyLoad/generic/generic_resolveScope.js +66 -0
  123. package/build/lazyLoad/generic/generic_resolveScope.js.map +1 -0
  124. package/build/lazyLoad/generic/generic_scanAttributesForJs.js +122 -0
  125. package/build/lazyLoad/generic/generic_scanAttributesForJs.js.map +1 -0
  126. package/build/lazyLoad/generic/generic_stringsDiscovery.js +103 -0
  127. package/build/lazyLoad/generic/generic_stringsDiscovery.js.map +1 -0
  128. package/build/lazyLoad/generic/generic_webpackChunkPaths.js +56 -0
  129. package/build/lazyLoad/generic/generic_webpackChunkPaths.js.map +1 -0
  130. package/build/lazyLoad/globals.js +31 -0
  131. package/build/lazyLoad/globals.js.map +1 -1
  132. package/build/lazyLoad/index.js +172 -75
  133. package/build/lazyLoad/index.js.map +1 -1
  134. package/build/lazyLoad/methodFilter.js +9 -1
  135. package/build/lazyLoad/methodFilter.js.map +1 -1
  136. package/build/lazyLoad/next_js/NextJsCrawler.js +98 -14
  137. package/build/lazyLoad/next_js/NextJsCrawler.js.map +1 -1
  138. package/build/lazyLoad/next_js/next_GetJSScript.js +3 -3
  139. package/build/lazyLoad/next_js/next_GetJSScript.js.map +1 -1
  140. package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js +4 -4
  141. package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js.map +1 -1
  142. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +17 -11
  143. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
  144. package/build/lazyLoad/next_js/next_SubsequentRequests.js +7 -6
  145. package/build/lazyLoad/next_js/next_SubsequentRequests.js.map +1 -1
  146. package/build/lazyLoad/next_js/next_bruteForceJsFiles.js +1 -1
  147. package/build/lazyLoad/next_js/next_bruteForceJsFiles.js.map +1 -1
  148. package/build/lazyLoad/next_js/next_buildId.js +2 -2
  149. package/build/lazyLoad/next_js/next_buildId.js.map +1 -1
  150. package/build/lazyLoad/next_js/next_getClientSidePaths.js +2 -2
  151. package/build/lazyLoad/next_js/next_getClientSidePaths.js.map +1 -1
  152. package/build/lazyLoad/next_js/next_parseLayoutJs.js +6 -6
  153. package/build/lazyLoad/next_js/next_parseLayoutJs.js.map +1 -1
  154. package/build/lazyLoad/next_js/next_promiseResolve.js +1 -1
  155. package/build/lazyLoad/next_js/next_promiseResolve.js.map +1 -1
  156. package/build/lazyLoad/next_js/next_routerStateForge.js +407 -0
  157. package/build/lazyLoad/next_js/next_routerStateForge.js.map +1 -0
  158. package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js +1 -1
  159. package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js.map +1 -1
  160. package/build/lazyLoad/next_js/next_serverActionIdScan.js +77 -0
  161. package/build/lazyLoad/next_js/next_serverActionIdScan.js.map +1 -0
  162. package/build/lazyLoad/nuxt_js/nuxt_astParse.js +15 -13
  163. package/build/lazyLoad/nuxt_js/nuxt_astParse.js.map +1 -1
  164. package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js +2 -2
  165. package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js.map +1 -1
  166. package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +3 -3
  167. package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js.map +1 -1
  168. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +29 -5
  169. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -1
  170. package/build/lazyLoad/react/react_sourcemapUrls.js +7 -28
  171. package/build/lazyLoad/react/react_sourcemapUrls.js.map +1 -1
  172. package/build/lazyLoad/react/react_webpackChunkPaths.js +10 -202
  173. package/build/lazyLoad/react/react_webpackChunkPaths.js.map +1 -1
  174. package/build/lazyLoad/researchUtils.js +15 -0
  175. package/build/lazyLoad/researchUtils.js.map +1 -0
  176. package/build/lazyLoad/shared/webpackChunkParsers.js +218 -0
  177. package/build/lazyLoad/shared/webpackChunkParsers.js.map +1 -0
  178. package/build/lazyLoad/sourcemap.js +120 -0
  179. package/build/lazyLoad/sourcemap.js.map +1 -1
  180. package/build/lazyLoad/stagnation/stagnationMonitor.js +63 -0
  181. package/build/lazyLoad/stagnation/stagnationMonitor.js.map +1 -0
  182. package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js +1 -0
  183. package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js.map +1 -1
  184. package/build/lazyLoad/svelte/svelte_getFromPageSource.js +5 -5
  185. package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -1
  186. package/build/lazyLoad/svelte/svelte_getVersionJson.js +2 -2
  187. package/build/lazyLoad/svelte/svelte_getVersionJson.js.map +1 -1
  188. package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js +6 -6
  189. package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js.map +1 -1
  190. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +15 -6
  191. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -1
  192. package/build/lazyLoad/techDetect/checkAngularJS.js +1 -1
  193. package/build/lazyLoad/techDetect/checkAngularJS.js.map +1 -1
  194. package/build/lazyLoad/techDetect/checkNuxtJS.js +3 -3
  195. package/build/lazyLoad/techDetect/checkNuxtJS.js.map +1 -1
  196. package/build/lazyLoad/techDetect/checkSvelte.js +0 -1
  197. package/build/lazyLoad/techDetect/checkSvelte.js.map +1 -1
  198. package/build/lazyLoad/techDetect/checkVueJS.js +6 -6
  199. package/build/lazyLoad/techDetect/checkVueJS.js.map +1 -1
  200. package/build/lazyLoad/techDetect/index.js +17 -1
  201. package/build/lazyLoad/techDetect/index.js.map +1 -1
  202. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +2 -2
  203. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -1
  204. package/build/lazyLoad/vue/vue_discoverJsFiles.js +13 -11
  205. package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -1
  206. package/build/lazyLoad/vue/vue_getClientSidePaths.js +1 -1
  207. package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -1
  208. package/build/lazyLoad/vue/vue_pageSrc.js +1 -1
  209. package/build/lazyLoad/vue/vue_pageSrc.js.map +1 -1
  210. package/build/lazyLoad/vue/vue_reconstructSourceMaps.js +12 -3
  211. package/build/lazyLoad/vue/vue_reconstructSourceMaps.js.map +1 -1
  212. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +2 -2
  213. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -1
  214. package/build/lazyLoad/vue/vue_severalJsFilesHome.js +3 -3
  215. package/build/lazyLoad/vue/vue_severalJsFilesHome.js.map +1 -1
  216. package/build/load/index.js +28 -38
  217. package/build/load/index.js.map +1 -1
  218. package/build/map/angular_js/getAngularConnections.js +6 -6
  219. package/build/map/angular_js/getAngularConnections.js.map +1 -1
  220. package/build/map/graphql/resolveGraphql.js +6 -6
  221. package/build/map/graphql/resolveGraphql.js.map +1 -1
  222. package/build/map/index.js +17 -17
  223. package/build/map/index.js.map +1 -1
  224. package/build/map/interactive-mode/commandHandler.js +278 -0
  225. package/build/map/interactive-mode/commandHandler.js.map +1 -0
  226. package/build/map/interactive-mode/commandHelpers.js +189 -0
  227. package/build/map/interactive-mode/commandHelpers.js.map +1 -0
  228. package/build/map/interactive-mode/esqueryGen.js.map +1 -0
  229. package/build/map/interactive-mode/helpMenu.js +11 -0
  230. package/build/map/interactive-mode/helpMenu.js.map +1 -0
  231. package/build/map/interactive-mode/inputPatch.js.map +1 -0
  232. package/build/map/interactive-mode/interactive.js +71 -0
  233. package/build/map/interactive-mode/interactive.js.map +1 -0
  234. package/build/map/interactive-mode/keybindings.js.map +1 -0
  235. package/build/map/interactive-mode/printer.js.map +1 -0
  236. package/build/map/interactive-mode/ui.js.map +1 -0
  237. package/build/map/next_js/getAxiosInstances.js +5 -5
  238. package/build/map/next_js/getAxiosInstances.js.map +1 -1
  239. package/build/map/next_js/getExports.js +4 -4
  240. package/build/map/next_js/getExports.js.map +1 -1
  241. package/build/map/next_js/getFetchInstances.js +10 -10
  242. package/build/map/next_js/getFetchInstances.js.map +1 -1
  243. package/build/map/next_js/getTurbopackConnections.js +8 -8
  244. package/build/map/next_js/getTurbopackConnections.js.map +1 -1
  245. package/build/map/next_js/getWebpackConnections.js +27 -16
  246. package/build/map/next_js/getWebpackConnections.js.map +1 -1
  247. package/build/map/next_js/interactive.js +3 -65
  248. package/build/map/next_js/interactive.js.map +1 -1
  249. package/build/map/next_js/interactive_helpers/commandHandler.js +38 -290
  250. package/build/map/next_js/interactive_helpers/commandHandler.js.map +1 -1
  251. package/build/map/next_js/interactive_helpers/commandHelpers.js +0 -184
  252. package/build/map/next_js/interactive_helpers/commandHelpers.js.map +1 -1
  253. package/build/map/next_js/interactive_helpers/helpMenu.js +2 -10
  254. package/build/map/next_js/interactive_helpers/helpMenu.js.map +1 -1
  255. package/build/map/next_js/resolveAxios.js +6 -6
  256. package/build/map/next_js/resolveAxios.js.map +1 -1
  257. package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js +4 -4
  258. package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js.map +1 -1
  259. package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js +2 -2
  260. package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js.map +1 -1
  261. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +5 -5
  262. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -1
  263. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +10 -10
  264. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -1
  265. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +13 -9
  266. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -1
  267. package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js +12 -8
  268. package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js.map +1 -1
  269. package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js +12 -8
  270. package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js.map +1 -1
  271. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +11 -11
  272. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -1
  273. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +16 -16
  274. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -1
  275. package/build/map/next_js/resolveFetch.js +23 -23
  276. package/build/map/next_js/resolveFetch.js.map +1 -1
  277. package/build/map/next_js/resolveNewRequest.js +10 -10
  278. package/build/map/next_js/resolveNewRequest.js.map +1 -1
  279. package/build/map/next_js/resolveServerActions.js +4 -4
  280. package/build/map/next_js/resolveServerActions.js.map +1 -1
  281. package/build/map/next_js/utils.js +8 -2
  282. package/build/map/next_js/utils.js.map +1 -1
  283. package/build/map/react_js/getReactConnections.js +21 -14
  284. package/build/map/react_js/getReactConnections.js.map +1 -1
  285. package/build/map/svelte_js/interactive.js +3 -54
  286. package/build/map/svelte_js/interactive.js.map +1 -1
  287. package/build/map/vue_js/getViteConnections.js +23 -16
  288. package/build/map/vue_js/getViteConnections.js.map +1 -1
  289. package/build/map/vue_js/interactive.js +3 -63
  290. package/build/map/vue_js/interactive.js.map +1 -1
  291. package/build/map/vue_js/interactive_helpers/commandHandler.js +34 -283
  292. package/build/map/vue_js/interactive_helpers/commandHandler.js.map +1 -1
  293. package/build/map/vue_js/interactive_helpers/helpMenu.js +2 -10
  294. package/build/map/vue_js/interactive_helpers/helpMenu.js.map +1 -1
  295. package/build/map/vue_js/taint_utils.js +1 -1
  296. package/build/map/vue_js/taint_utils.js.map +1 -1
  297. package/build/map/vue_js/vue_resolveFetch.js +12 -12
  298. package/build/map/vue_js/vue_resolveFetch.js.map +1 -1
  299. package/build/map/vue_js/vue_resolveHttpClient.js +18 -18
  300. package/build/map/vue_js/vue_resolveHttpClient.js.map +1 -1
  301. package/build/map/vue_js/vue_resolveXhr.js +11 -11
  302. package/build/map/vue_js/vue_resolveXhr.js.map +1 -1
  303. package/build/mcp/chatOneShot.js +7 -7
  304. package/build/mcp/chatOneShot.js.map +1 -1
  305. package/build/mcp/claudeCodeCreds.js +5 -5
  306. package/build/mcp/claudeCodeCreds.js.map +1 -1
  307. package/build/mcp/cli.js +36 -35
  308. package/build/mcp/cli.js.map +1 -1
  309. package/build/mcp/config.js +4 -4
  310. package/build/mcp/config.js.map +1 -1
  311. package/build/mcp/index.js +7 -7
  312. package/build/mcp/index.js.map +1 -1
  313. package/build/mcp/mcpServer.js +4 -3
  314. package/build/mcp/mcpServer.js.map +1 -1
  315. package/build/mcp/skills.js +1 -0
  316. package/build/mcp/skills.js.map +1 -1
  317. package/build/mcp/tools.js +6 -5
  318. package/build/mcp/tools.js.map +1 -1
  319. package/build/proxy/detectBlockedResponse.js +2 -0
  320. package/build/proxy/detectBlockedResponse.js.map +1 -1
  321. package/build/proxy/index.js +3 -3
  322. package/build/proxy/index.js.map +1 -1
  323. package/build/refactor/index.js +83 -79
  324. package/build/refactor/index.js.map +1 -1
  325. package/build/refactor/next/index.js +69 -26
  326. package/build/refactor/next/index.js.map +1 -1
  327. package/build/refactor/next/transform.js +11 -4
  328. package/build/refactor/next/transform.js.map +1 -1
  329. package/build/refactor/next/validator.js +7 -7
  330. package/build/refactor/next/validator.js.map +1 -1
  331. package/build/refactor/react/index.js +13 -13
  332. package/build/refactor/react/index.js.map +1 -1
  333. package/build/refactor/react/validator.js +7 -7
  334. package/build/refactor/react/validator.js.map +1 -1
  335. package/build/refactor/react-vite/index.js +3 -3
  336. package/build/refactor/react-vite/index.js.map +1 -1
  337. package/build/refactor/remote/hf-client.js +1 -0
  338. package/build/refactor/remote/hf-client.js.map +1 -1
  339. package/build/refactor/remote/version-detect.js +12 -12
  340. package/build/refactor/remote/version-detect.js.map +1 -1
  341. package/build/refactor/vue/index.js +6 -6
  342. package/build/refactor/vue/index.js.map +1 -1
  343. package/build/refactor/vue/vite.js +6 -6
  344. package/build/refactor/vue/vite.js.map +1 -1
  345. package/build/report/index.js +30 -8
  346. package/build/report/index.js.map +1 -1
  347. package/build/report/swaggerJacker.js +63 -0
  348. package/build/report/swaggerJacker.js.map +1 -0
  349. package/build/report/utility/dataTables/genDataTablesPage.js +2 -1
  350. package/build/report/utility/dataTables/genDataTablesPage.js.map +1 -1
  351. package/build/report/utility/genHtml.js +316 -25
  352. package/build/report/utility/genHtml.js.map +1 -1
  353. package/build/report/utility/markdownGen/addAnalyze.js +2 -1
  354. package/build/report/utility/markdownGen/addAnalyze.js.map +1 -1
  355. package/build/report/utility/populateDb/populateAnalysisFindings.js +2 -2
  356. package/build/report/utility/populateDb/populateAnalysisFindings.js.map +1 -1
  357. package/build/report/utility/populateDb/populateEndpoints.js +3 -3
  358. package/build/report/utility/populateDb/populateEndpoints.js.map +1 -1
  359. package/build/report/utility/populateDb/populateMappedJson.js +2 -2
  360. package/build/report/utility/populateDb/populateMappedJson.js.map +1 -1
  361. package/build/report/utility/populateDb/populateMappedOpenapi.js +3 -3
  362. package/build/report/utility/populateDb/populateMappedOpenapi.js.map +1 -1
  363. package/build/report/utility/severityColors.js +35 -0
  364. package/build/report/utility/severityColors.js.map +1 -0
  365. package/build/run/bundler-detect.js +45 -9
  366. package/build/run/bundler-detect.js.map +1 -1
  367. package/build/run/dashboard/dashboardHtml.js +150 -0
  368. package/build/run/dashboard/dashboardHtml.js.map +1 -0
  369. package/build/run/dashboard/fsBrowser.js +43 -0
  370. package/build/run/dashboard/fsBrowser.js.map +1 -0
  371. package/build/run/dashboard/server.js +123 -0
  372. package/build/run/dashboard/server.js.map +1 -0
  373. package/build/run/dashboard/state.js +97 -0
  374. package/build/run/dashboard/state.js.map +1 -0
  375. package/build/run/index.js +177 -110
  376. package/build/run/index.js.map +1 -1
  377. package/build/run/interruptHandler.js +18 -0
  378. package/build/run/interruptHandler.js.map +1 -1
  379. package/build/sourcemaps/index.js +7 -6
  380. package/build/sourcemaps/index.js.map +1 -1
  381. package/build/strings/index.js +27 -24
  382. package/build/strings/index.js.map +1 -1
  383. package/build/strings/openapi.js +4 -4
  384. package/build/strings/openapi.js.map +1 -1
  385. package/build/strings/permutate.js +4 -4
  386. package/build/strings/permutate.js.map +1 -1
  387. package/build/strings/secrets.js +1 -0
  388. package/build/strings/secrets.js.map +1 -1
  389. package/build/strings/trufflehog.js +66 -19
  390. package/build/strings/trufflehog.js.map +1 -1
  391. package/build/strings/trufflehogConfig.js +36 -0
  392. package/build/strings/trufflehogConfig.js.map +1 -0
  393. package/build/strings/trufflehogDownload.js +115 -0
  394. package/build/strings/trufflehogDownload.js.map +1 -0
  395. package/build/utility/ai.js +33 -4
  396. package/build/utility/ai.js.map +1 -1
  397. package/build/utility/banner.js +4 -3
  398. package/build/utility/banner.js.map +1 -1
  399. package/build/utility/cacheDb.js +78 -0
  400. package/build/utility/cacheDb.js.map +1 -0
  401. package/build/utility/configureSandbox.js +2 -2
  402. package/build/utility/configureSandbox.js.map +1 -1
  403. package/build/utility/customHeaders.js +30 -0
  404. package/build/utility/customHeaders.js.map +1 -0
  405. package/build/utility/globals.js +37 -12
  406. package/build/utility/globals.js.map +1 -1
  407. package/build/utility/heap.js +2 -1
  408. package/build/utility/heap.js.map +1 -1
  409. package/build/utility/makeReq.js +38 -87
  410. package/build/utility/makeReq.js.map +1 -1
  411. package/build/utility/openapiGenerator.js +2 -2
  412. package/build/utility/openapiGenerator.js.map +1 -1
  413. package/build/utility/printMsg.js +53 -0
  414. package/build/utility/printMsg.js.map +1 -0
  415. package/build/utility/progressLog.js +4 -3
  416. package/build/utility/progressLog.js.map +1 -1
  417. package/build/utility/resolvePath.js +2 -1
  418. package/build/utility/resolvePath.js.map +1 -1
  419. package/build/utility/ruleVersionMap.js +73 -0
  420. package/build/utility/ruleVersionMap.js.map +1 -0
  421. package/config.dist.yaml +3 -3
  422. package/contributing/testing.md +106 -0
  423. package/eslint.config.js +24 -0
  424. package/package.json +22 -6
  425. package/scripts/exploit-smoke-test.js +82 -0
  426. package/scripts/framework-detect-smoke-test.js +64 -0
  427. package/scripts/postinstall-completion.mjs +40 -0
  428. package/scripts/smoke-test.js +12 -0
  429. package/build/lazyLoad/downloadLoadedJsUtil.js +0 -98
  430. package/build/lazyLoad/downloadLoadedJsUtil.js.map +0 -1
  431. package/build/map/next_js/interactive_helpers/esqueryGen.js.map +0 -1
  432. package/build/map/next_js/interactive_helpers/inputPatch.js.map +0 -1
  433. package/build/map/next_js/interactive_helpers/keybindings.js.map +0 -1
  434. package/build/map/next_js/interactive_helpers/printer.js.map +0 -1
  435. package/build/map/next_js/interactive_helpers/ui.js.map +0 -1
  436. /package/build/map/{next_js/interactive_helpers → interactive-mode}/esqueryGen.js +0 -0
  437. /package/build/map/{next_js/interactive_helpers → interactive-mode}/inputPatch.js +0 -0
  438. /package/build/map/{next_js/interactive_helpers → interactive-mode}/keybindings.js +0 -0
  439. /package/build/map/{next_js/interactive_helpers → interactive-mode}/printer.js +0 -0
  440. /package/build/map/{next_js/interactive_helpers → interactive-mode}/ui.js +0 -0
@@ -0,0 +1,79 @@
1
+ import * as cheerio from "cheerio";
2
+ const resolvePageUrl = (rawValue, baseUrl) => {
3
+ if (!rawValue)
4
+ return null;
5
+ const trimmed = rawValue.trim();
6
+ if (!trimmed || trimmed.startsWith("#"))
7
+ return null;
8
+ if (/^(mailto|tel|javascript|data|blob):/i.test(trimmed))
9
+ return null;
10
+ let resolved;
11
+ try {
12
+ resolved = new URL(trimmed, baseUrl);
13
+ }
14
+ catch (_a) {
15
+ return null;
16
+ }
17
+ if (resolved.protocol !== "http:" && resolved.protocol !== "https:")
18
+ return null;
19
+ resolved.hash = "";
20
+ return resolved.href;
21
+ };
22
+ // Matches an absolute http(s) URL embedded anywhere in a string — e.g. inside an
23
+ // onclick handler's JS: onclick="return powerpress_pinw('https://site/?pinw=123')".
24
+ // Deliberately not tied to a specific function name (window.open, a plugin helper,
25
+ // etc.) — popup/widget links are triggered through all sorts of call shapes, but the
26
+ // URL argument itself is always a plain quoted absolute URL, which this catches
27
+ // regardless of what function it's passed to.
28
+ const EMBEDDED_URL_RE = /https?:\/\/[^\s'"<>)]+/g;
29
+ /**
30
+ * Extracts every absolute http(s) URL substring embedded in a string value (typically
31
+ * an onclick handler or other inline JS attribute). See EMBEDDED_URL_RE for why this
32
+ * isn't tied to a specific JS call pattern like window.open(...).
33
+ */
34
+ export const extractEmbeddedUrls = (attrValue) => [...attrValue.matchAll(EMBEDDED_URL_RE)].map((m) => m[0]);
35
+ /**
36
+ * Extracts navigable page URLs from <a href>/<iframe src> tags and absolute URLs
37
+ * embedded in any other attribute value (typically an onclick handler) — not JS
38
+ * files. Used to recursively discover more HTML pages to scan for JS, per
39
+ * internal#66. <iframe src> and onclick-embedded URLs are included alongside
40
+ * <a href> because embedded widgets (a podcast player, a survey, a booking form) are
41
+ * commonly reachable only via an iframe or a JS-driven popup, never a plain link —
42
+ * WordPress's PowerPress podcast plugin is one real example: its "pop out player"
43
+ * link is `onclick="return powerpress_pinw('https://site/?powerpress_pinw=123-podcast')"`,
44
+ * invisible to href-only or iframe-only crawling. Filters out fragment-only links,
45
+ * non-http(s) schemes (mailto/tel/javascript/data/blob), and strips the hash so
46
+ * #section variants of the same page dedupe to one entry.
47
+ */
48
+ export const extractPageLinks = (html, baseUrl) => {
49
+ const $ = cheerio.load(html);
50
+ const links = new Set();
51
+ $("a[href], iframe[src]").each((_, elem) => {
52
+ var _a;
53
+ const rawValue = (_a = $(elem).attr("href")) !== null && _a !== void 0 ? _a : $(elem).attr("src");
54
+ const resolved = resolvePageUrl(rawValue, baseUrl);
55
+ if (resolved)
56
+ links.add(resolved);
57
+ });
58
+ $("*").each((_, elem) => {
59
+ const attribs = elem.attribs;
60
+ if (!attribs)
61
+ return;
62
+ for (const [attrName, value] of Object.entries(attribs)) {
63
+ // href/src already handled above via cheerio's typed accessors; re-scanning
64
+ // them here would just re-add the same URL, which the Set dedupes anyway,
65
+ // but skipping is cheaper and avoids false "embedded URL" matches inside a
66
+ // long querystring value that itself contains another URL as a parameter.
67
+ if (attrName === "href" || attrName === "src" || !value)
68
+ continue;
69
+ for (const embeddedUrl of extractEmbeddedUrls(value)) {
70
+ const resolved = resolvePageUrl(embeddedUrl, baseUrl);
71
+ if (resolved)
72
+ links.add(resolved);
73
+ }
74
+ }
75
+ });
76
+ return [...links];
77
+ };
78
+ export default extractPageLinks;
79
+ //# sourceMappingURL=generic_extractLinks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic_extractLinks.js","sourceRoot":"","sources":["../../../src/lazyLoad/generic/generic_extractLinks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,152 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import makeRequest from "../../utility/makeReq.js";
11
+ import * as cheerio from "cheerio";
12
+ import fs from "fs";
13
+ import path from "path";
14
+ import crypto from "crypto";
15
+ import * as lazyLoadGlobals from "../globals.js";
16
+ import { printMsg, MSG } from "../../utility/printMsg.js";
17
+ // <script type="..."> values known to hold non-JS content. Browsers never execute
18
+ // these as script — WordPress/plugins routinely stash JSON-LD structured data or
19
+ // browser resource-hint configs in a bare <script> tag with no src, and saving
20
+ // that content as a .js file breaks any JS parser later run against it (Babel
21
+ // can't parse a top-level JSON object as a JS Program).
22
+ const NON_JS_SCRIPT_TYPES = [
23
+ "application/ld+json",
24
+ "application/json",
25
+ "speculationrules",
26
+ "importmap",
27
+ "text/template",
28
+ "text/x-template",
29
+ "text/x-handlebars-template",
30
+ "text/x-jquery-tmpl",
31
+ "text/ng-template",
32
+ "text/html",
33
+ ];
34
+ /**
35
+ * Whether a <script type="..."> value indicates the tag's content should be
36
+ * treated as JS. Missing/empty type defaults to JS per the HTML spec. Deliberately
37
+ * permissive for unrecognized types (e.g. Cloudflare Rocket Loader rewrites
38
+ * type="text/javascript" to a randomized "<hash>-text/javascript" to defer
39
+ * execution — still real JS) — only the known non-JS types above are excluded.
40
+ */
41
+ export const isLikelyJsScriptType = (type) => {
42
+ if (!type)
43
+ return true;
44
+ const normalized = type.trim().toLowerCase();
45
+ if (!normalized)
46
+ return true;
47
+ if (normalized.includes("javascript") || normalized === "module" || normalized.includes("ecmascript")) {
48
+ return true;
49
+ }
50
+ return !NON_JS_SCRIPT_TYPES.some((t) => normalized.includes(t));
51
+ };
52
+ /**
53
+ * Decodes a data: URI script src (e.g. `data:text/javascript;base64,...`) into
54
+ * its JS source text. Returns null if the URI doesn't match the expected shape
55
+ * or the payload can't be decoded.
56
+ */
57
+ export const decodeDataUriScript = (dataUri) => {
58
+ const match = /^data:([^,]*),([\s\S]*)$/.exec(dataUri);
59
+ if (!match)
60
+ return null;
61
+ const [, meta, payload] = match;
62
+ const isBase64 = /;base64$/i.test(meta);
63
+ try {
64
+ return isBase64 ? Buffer.from(payload, "base64").toString("utf-8") : decodeURIComponent(payload);
65
+ }
66
+ catch (_a) {
67
+ return null;
68
+ }
69
+ };
70
+ /**
71
+ * Extracts JS chunk URLs from <script src> and <link rel="modulepreload"> tags,
72
+ * and saves inline <script> bodies (inline text and decoded data: URIs) to disk.
73
+ * Every saved file carries a `// File Source: <url>` header — this is what lets
74
+ * generic_stringsDiscovery.ts later resolve string-literal JS paths found inside
75
+ * these files against the URL they actually came from. Mirrors react_getScriptTags.ts
76
+ * — the same seeding pattern applies to any site regardless of framework.
77
+ */
78
+ const generic_getScriptTags = (url, maxJsSizeMb, outputDir) => __awaiter(void 0, void 0, void 0, function* () {
79
+ let toReturn = [];
80
+ const req = yield makeRequest(url);
81
+ const pageSource = req ? yield req.text() : "";
82
+ const $ = cheerio.load(pageSource);
83
+ const host = new URL(url).host.replace(":", "_");
84
+ // Mirrors the page's own path, not just its host — so inline scripts from
85
+ // different pages of a multi-page generic crawl (internal#66) land in
86
+ // separate directories instead of colliding on inline-0.js, inline-1.js, etc.
87
+ const pageDir = new URL(url).pathname;
88
+ let inlineIndex = 0;
89
+ $("script").each((_, elem) => {
90
+ const src = $(elem).attr("src");
91
+ if (src) {
92
+ let resolved;
93
+ try {
94
+ resolved = new URL(src, url);
95
+ }
96
+ catch (_a) {
97
+ return;
98
+ }
99
+ // A data: URI script src embeds the JS source directly — it isn't a
100
+ // network-fetchable URL, so pushing it to toReturn would make the
101
+ // downloader try (and fail) to request/save it as a file.
102
+ if (resolved.protocol === "data:") {
103
+ if (!outputDir)
104
+ return;
105
+ const content = decodeDataUriScript(resolved.href);
106
+ if (!content)
107
+ return;
108
+ const hostDir = path.join(outputDir, host, pageDir);
109
+ fs.mkdirSync(hostDir, { recursive: true });
110
+ const filename = `inline-${inlineIndex++}.js`;
111
+ const filePath = path.join(hostDir, filename);
112
+ fs.writeFileSync(filePath, `// File Source: ${url} (data URI script #${inlineIndex - 1})\n${content}`);
113
+ lazyLoadGlobals.recordJsFileHash(crypto.createHash("sha256").update(content).digest("hex"));
114
+ printMsg(MSG.Run, `[✓] Saved data URI script to ${filePath}`);
115
+ return;
116
+ }
117
+ // blob:, javascript:, etc — not something we can fetch over the network either.
118
+ if (resolved.protocol !== "http:" && resolved.protocol !== "https:")
119
+ return;
120
+ toReturn.push(resolved.href);
121
+ }
122
+ else if (outputDir) {
123
+ if (!isLikelyJsScriptType($(elem).attr("type")))
124
+ return;
125
+ const content = $(elem).text().trim();
126
+ if (!content)
127
+ return;
128
+ const hostDir = path.join(outputDir, host, pageDir);
129
+ fs.mkdirSync(hostDir, { recursive: true });
130
+ const filename = `inline-${inlineIndex++}.js`;
131
+ const filePath = path.join(hostDir, filename);
132
+ fs.writeFileSync(filePath, `// File Source: ${url} (inline script #${inlineIndex - 1})\n${content}`);
133
+ lazyLoadGlobals.recordJsFileHash(crypto.createHash("sha256").update(content).digest("hex"));
134
+ printMsg(MSG.Run, `[✓] Saved inline script to ${filePath}`);
135
+ }
136
+ });
137
+ $("link[rel='modulepreload']").each((_, elem) => {
138
+ const href = $(elem).attr("href");
139
+ if (href) {
140
+ try {
141
+ toReturn.push(new URL(href, url).href);
142
+ }
143
+ catch (_a) {
144
+ /* not a resolvable URL — skip */
145
+ }
146
+ }
147
+ });
148
+ toReturn = [...new Set(toReturn)];
149
+ return { urls: toReturn, pageSource };
150
+ });
151
+ export default generic_getScriptTags;
152
+ //# sourceMappingURL=generic_getScriptTags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic_getScriptTags.js","sourceRoot":"","sources":["../../../src/lazyLoad/generic/generic_getScriptTags.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import fs from "fs";
11
+ import path from "path";
12
+ import { confirmJsContentType } from "./generic_scanAttributesForJs.js";
13
+ /**
14
+ * Parses a downloaded file's content for a Webpack Module Federation "import map"
15
+ * manifest shape:
16
+ * { "microFrontends": { "<scope>/<name>": [{ "url": "https://.../remote-entry.js", ... }] } }
17
+ * and returns every remote-entry-style URL it lists. Tolerates the
18
+ * `// File Source: <url>\n` header `generic_downloadFiles.ts` prefixes onto every
19
+ * downloaded file — these manifests are typically referenced via a literal
20
+ * `<script src="...prod.json">` tag (picked up like any other script by
21
+ * `generic_getScriptTags.ts` regardless of extension) and saved under a synthesized
22
+ * `.js` filename despite being JSON (see `generic_downloadFiles.ts::synthesizeFilename`),
23
+ * so the header must be stripped before `JSON.parse`.
24
+ */
25
+ export const extractMicroFrontendUrls = (content) => {
26
+ const withoutHeader = content.replace(/^\/\/ File Source: \S+\n/, "");
27
+ let data;
28
+ try {
29
+ data = JSON.parse(withoutHeader);
30
+ }
31
+ catch (_a) {
32
+ return [];
33
+ }
34
+ if (typeof data !== "object" || data === null || !("microFrontends" in data))
35
+ return [];
36
+ const microFrontends = data.microFrontends;
37
+ if (typeof microFrontends !== "object" || microFrontends === null)
38
+ return [];
39
+ const urls = new Set();
40
+ for (const entries of Object.values(microFrontends)) {
41
+ if (!Array.isArray(entries))
42
+ continue;
43
+ for (const entry of entries) {
44
+ const url = entry === null || entry === void 0 ? void 0 : entry.url;
45
+ if (typeof url === "string" && /^https?:\/\//i.test(url) && url.toLowerCase().endsWith(".js")) {
46
+ urls.add(url);
47
+ }
48
+ }
49
+ }
50
+ return [...urls];
51
+ };
52
+ /**
53
+ * Scans every file `generic` tech has already downloaded under outputDir for a
54
+ * micro-frontend import-map manifest (see `extractMicroFrontendUrls`) and confirms each
55
+ * referenced remote-entry URL via Content-Type before returning it as a new download
56
+ * candidate. Internal#74: js-recon was already downloading these manifests (picked up
57
+ * like any other `<script src>`) but never reading them — every remote a
58
+ * module-federation app can dynamically load is listed here, including remotes whose
59
+ * components never rendered (and so never fired a request) during the crawl.
60
+ */
61
+ const generic_importMapDiscovery = (outputDir_1, ...args_1) => __awaiter(void 0, [outputDir_1, ...args_1], void 0, function* (outputDir, alreadyKnownUrls = new Set(), threads = 1) {
62
+ if (!fs.existsSync(outputDir))
63
+ return [];
64
+ const files = fs.readdirSync(outputDir, { recursive: true, encoding: "utf8" });
65
+ const candidates = new Set();
66
+ for (const relPath of files) {
67
+ if (!/\.(js|mjs|json)$/i.test(relPath))
68
+ continue;
69
+ const filePath = path.join(outputDir, relPath);
70
+ let content;
71
+ try {
72
+ content = fs.readFileSync(filePath, "utf-8");
73
+ }
74
+ catch (_a) {
75
+ continue;
76
+ }
77
+ for (const url of extractMicroFrontendUrls(content)) {
78
+ if (!alreadyKnownUrls.has(url))
79
+ candidates.add(url);
80
+ }
81
+ }
82
+ if (candidates.size === 0)
83
+ return [];
84
+ return confirmJsContentType([...candidates], threads);
85
+ });
86
+ export default generic_importMapDiscovery;
87
+ //# sourceMappingURL=generic_importMapDiscovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic_importMapDiscovery.js","sourceRoot":"","sources":["../../../src/lazyLoad/generic/generic_importMapDiscovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { printMsg, MSG } from "../../utility/printMsg.js";
11
+ import { customHeadersToRecord } from "../../utility/customHeaders.js";
12
+ import * as globals from "../../utility/globals.js";
13
+ /**
14
+ * Extracts the host (scheme-independent, matches the format used throughout
15
+ * `lazyLoad/globals.ts`'s scope list) from a URL.
16
+ */
17
+ export const hostFromUrl = (url) => new URL(url).host;
18
+ /**
19
+ * Manually follows HTTP redirects starting at startUrl, up to maxRedirects hops,
20
+ * and returns the final URL reached. Uses redirect: "manual" (rather than the
21
+ * platform default of automatically following) so the hop count is actually
22
+ * enforced by this function instead of an opaque undici-internal limit.
23
+ */
24
+ export const resolveRedirectChain = (startUrl_1, maxRedirects_1, ...args_1) => __awaiter(void 0, [startUrl_1, maxRedirects_1, ...args_1], void 0, function* (startUrl, maxRedirects, fetchImpl = fetch) {
25
+ let currentUrl = startUrl;
26
+ for (let i = 0; i < maxRedirects; i++) {
27
+ let res;
28
+ try {
29
+ res = yield fetchImpl(currentUrl, {
30
+ redirect: "manual",
31
+ headers: customHeadersToRecord(globals.getCustomHeaders()),
32
+ });
33
+ }
34
+ catch (_a) {
35
+ return currentUrl;
36
+ }
37
+ if (res.status >= 300 && res.status < 400) {
38
+ const location = res.headers.get("location");
39
+ if (!location)
40
+ return currentUrl;
41
+ try {
42
+ currentUrl = new URL(location, currentUrl).href;
43
+ }
44
+ catch (_b) {
45
+ return currentUrl;
46
+ }
47
+ continue;
48
+ }
49
+ return currentUrl;
50
+ }
51
+ return currentUrl;
52
+ });
53
+ /**
54
+ * Default scope for the `generic` tech: fetch the target URL, follow redirects
55
+ * (capped at maxRedirects), and scope the crawl to the host of the final
56
+ * destination. Without this, an unscoped generic crawl would follow every
57
+ * in-page link across the entire web.
58
+ */
59
+ const resolveGenericScope = (url, maxRedirects) => __awaiter(void 0, void 0, void 0, function* () {
60
+ const finalUrl = yield resolveRedirectChain(url, maxRedirects);
61
+ const host = hostFromUrl(finalUrl);
62
+ printMsg(MSG.Header, `[i] Generic crawl scope resolved to: ${host}`);
63
+ return [host];
64
+ });
65
+ export default resolveGenericScope;
66
+ //# sourceMappingURL=generic_resolveScope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic_resolveScope.js","sourceRoot":"","sources":["../../../src/lazyLoad/generic/generic_resolveScope.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,OAAO,MAAM,0BAA0B,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,wCAIjB,EAAE,+EAHjB,QAAgB,EAChB,YAAoB,EACpB,YAA0B,KAAK;IAE/B,IAAI,UAAU,GAAG,QAAQ,CAAC;IAE1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACD,GAAG,GAAG,MAAM,SAAS,CAAC,UAAU,EAAE;gBAC9B,QAAQ,EAAE,QAAQ;gBAClB,OAAO,EAAE,qBAAqB,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;aAC7D,CAAC,CAAC;QACP,CAAC;QAAC,WAAM,CAAC;YACL,OAAO,UAAU,CAAC;QACtB,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC7C,IAAI,CAAC,QAAQ;gBAAE,OAAO,UAAU,CAAC;YACjC,IAAI,CAAC;gBACD,UAAU,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC;YACpD,CAAC;YAAC,WAAM,CAAC;gBACL,OAAO,UAAU,CAAC;YACtB,CAAC;YACD,SAAS;QACb,CAAC;QAED,OAAO,UAAU,CAAC;IACtB,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC,CAAA,CAAC;AAEF;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,CAAO,GAAW,EAAE,YAAoB,EAAqB,EAAE;IACvF,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAC/D,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IACnC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,wCAAwC,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,CAAC,IAAI,CAAC,CAAC;AAClB,CAAC,CAAA,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,122 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import * as cheerio from "cheerio";
11
+ import makeRequest from "../../utility/makeReq.js";
12
+ import { isJsContentType } from "./generic_jsMimeTypes.js";
13
+ import { printMsg, MSG } from "../../utility/printMsg.js";
14
+ /**
15
+ * Resolves value against baseUrl and returns the href if it's a network-fetchable
16
+ * (http/https) URL with a path segment ending in ".js" — this is what catches assets
17
+ * served like ".../beacon.min.js/v124/token" (a ".js"-suffixed segment that isn't the
18
+ * last one, so a plain endsWith(".js") check on the whole path would miss it). Returns
19
+ * null for anything unparseable or non-http(s) (data:/blob:/javascript: etc — these
20
+ * aren't requests confirmJsContentType could ever meaningfully make).
21
+ */
22
+ export const resolveJsPathCandidate = (value, baseUrl) => {
23
+ if (!value)
24
+ return null;
25
+ const trimmed = value.trim();
26
+ if (!trimmed)
27
+ return null;
28
+ // A fragment-only ("#selector") or query-only ("?x=1") value resolves against
29
+ // baseUrl by inheriting its pathname completely unchanged. When baseUrl is itself
30
+ // a .js file (e.g. generic_stringsDiscovery.ts resolving strings found INSIDE an
31
+ // already-downloaded JS file), a value that isn't a path reference at all — a CSS
32
+ // selector string embedded in a Vue bundle's scoped styles, say — would otherwise
33
+ // falsely look like a legitimate JS-path candidate purely because it inherited the
34
+ // base's own ".js"-ending pathname.
35
+ if (trimmed.startsWith("#") || trimmed.startsWith("?"))
36
+ return null;
37
+ let parsed;
38
+ try {
39
+ parsed = new URL(trimmed, baseUrl);
40
+ }
41
+ catch (_a) {
42
+ return null;
43
+ }
44
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
45
+ return null;
46
+ const segments = parsed.pathname.split("/");
47
+ if (!segments.some((seg) => seg.toLowerCase().endsWith(".js")))
48
+ return null;
49
+ return parsed.href;
50
+ };
51
+ /**
52
+ * Pure candidate extraction: walks every element attribute in the given HTML and
53
+ * keeps the ones that resolve to a JS-looking path (see resolveJsPathCandidate).
54
+ */
55
+ export const findJsPathSegmentCandidates = (html, baseUrl) => {
56
+ const $ = cheerio.load(html);
57
+ const candidates = new Set();
58
+ $("*").each((_, elem) => {
59
+ const attribs = elem.attribs;
60
+ if (!attribs)
61
+ return;
62
+ for (const value of Object.values(attribs)) {
63
+ const resolved = resolveJsPathCandidate(value, baseUrl);
64
+ if (resolved)
65
+ candidates.add(resolved);
66
+ }
67
+ });
68
+ return [...candidates];
69
+ };
70
+ /**
71
+ * Confirms each candidate is actually JavaScript via Content-Type (per RFC 9239 /
72
+ * RFC 4329 and legacy variants — see generic_jsMimeTypes.ts), not just the URL shape.
73
+ * Uses GET rather than HEAD: makeRequest's response cache is keyed on URL only (not
74
+ * method), so a cached HEAD response would poison the later GET that downloads the
75
+ * body — every other crawler in this codebase uses GET for the same reason.
76
+ *
77
+ * `concurrency` (default 1, matching every other generic-tech call site's default
78
+ * single-threaded behavior) controls how many candidates are in flight at once — a
79
+ * worker-pool over the candidate list, same shape as generic_downloadFiles.ts's
80
+ * `processOne`/`worker` pattern. Internal#75: a webpack chunk-hash-map can list far
81
+ * more candidates than a string-literal scan ever would (every chunk ID an entry
82
+ * chunk knows about, not just ones referenced by a literal path), and each failing
83
+ * candidate costs up to `10 retries * requestTimeout` in makeRequest — sequential
84
+ * confirmation of a large candidate batch, with even a handful of dead chunk IDs in
85
+ * it, becomes prohibitively slow. Passing a caller-supplied `threads` value here
86
+ * (already threaded through generic tech for downloads) keeps that path proportional.
87
+ */
88
+ export const confirmJsContentType = (candidates_1, ...args_1) => __awaiter(void 0, [candidates_1, ...args_1], void 0, function* (candidates, concurrency = 1) {
89
+ const confirmed = [];
90
+ let cursor = 0;
91
+ const worker = () => __awaiter(void 0, void 0, void 0, function* () {
92
+ var _a;
93
+ while (true) {
94
+ const idx = cursor++;
95
+ if (idx >= candidates.length)
96
+ break;
97
+ const url = candidates[idx];
98
+ let contentType = null;
99
+ try {
100
+ const res = yield makeRequest(url, { method: "GET" });
101
+ contentType = (_a = res === null || res === void 0 ? void 0 : res.headers.get("content-type")) !== null && _a !== void 0 ? _a : null;
102
+ }
103
+ catch (_b) {
104
+ continue;
105
+ }
106
+ if (isJsContentType(contentType)) {
107
+ printMsg(MSG.Run, `[✓] Confirmed JS via Content-Type: ${url}`);
108
+ confirmed.push(url);
109
+ }
110
+ }
111
+ });
112
+ yield Promise.all(Array.from({ length: Math.max(1, concurrency) }, () => worker()));
113
+ return confirmed;
114
+ });
115
+ const generic_scanAttributesForJs = (html_1, baseUrl_1, ...args_1) => __awaiter(void 0, [html_1, baseUrl_1, ...args_1], void 0, function* (html, baseUrl, alreadyKnownUrls = new Set()) {
116
+ const candidates = findJsPathSegmentCandidates(html, baseUrl).filter((u) => !alreadyKnownUrls.has(u));
117
+ if (candidates.length === 0)
118
+ return [];
119
+ return confirmJsContentType(candidates);
120
+ });
121
+ export default generic_scanAttributesForJs;
122
+ //# sourceMappingURL=generic_scanAttributesForJs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic_scanAttributesForJs.js","sourceRoot":"","sources":["../../../src/lazyLoad/generic/generic_scanAttributesForJs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import fs from "fs";
11
+ import path from "path";
12
+ import strings from "../../strings/index.js";
13
+ import { resolveJsPathCandidate, confirmJsContentType } from "./generic_scanAttributesForJs.js";
14
+ import { printMsg, MSG } from "../../utility/printMsg.js";
15
+ /**
16
+ * Parses the `// File Source: <url>` header every generic-downloaded file carries
17
+ * as its first line (written by generic_downloadFiles.ts and generic_getScriptTags.ts)
18
+ * to recover the URL a downloaded file actually came from. This is what lets string
19
+ * literals found inside that file resolve against ITS OWN url — unlike Next.js's
20
+ * subsequent-requests pass (next_SubsequentRequests.ts), which resolves every
21
+ * extracted path against a single fixed target URL for the whole crawl.
22
+ */
23
+ export const extractFileSourceUrl = (fileContent) => {
24
+ const match = /^\/\/ File Source: (\S+)/.exec(fileContent);
25
+ return match ? match[1] : null;
26
+ };
27
+ /**
28
+ * Pure candidate extraction: given the strings module's raw per-file output
29
+ * ({ [filePath]: string[] }), resolves each string against the URL its own file
30
+ * came from and keeps the ones that look like a JS path. readFile is injected so
31
+ * this stays unit-testable without real filesystem access.
32
+ */
33
+ export const findJsPathCandidatesFromStrings = (allStrings, readFile) => {
34
+ var _a;
35
+ const candidates = new Set();
36
+ for (const filePath of Object.keys(allStrings)) {
37
+ let content;
38
+ try {
39
+ content = readFile(filePath);
40
+ }
41
+ catch (_b) {
42
+ continue;
43
+ }
44
+ const sourceUrl = extractFileSourceUrl(content);
45
+ if (!sourceUrl)
46
+ continue;
47
+ for (const str of (_a = allStrings[filePath]) !== null && _a !== void 0 ? _a : []) {
48
+ const resolved = resolveJsPathCandidate(str, sourceUrl);
49
+ if (resolved)
50
+ candidates.add(resolved);
51
+ }
52
+ }
53
+ return [...candidates];
54
+ };
55
+ let stringsPassCounter = 0;
56
+ /**
57
+ * Runs the existing `strings` module against the generic crawl's whole output
58
+ * directory (files span multiple host subdirectories — the page's own host plus
59
+ * any third-party asset hosts), recovers per-file source URLs, and confirms
60
+ * JS-looking string-literal candidates via Content-Type. Internal#66: WordPress
61
+ * plugin configs routinely reference further JS assets only as a string inside
62
+ * an already-downloaded file (inline script or external JS), invisible to
63
+ * attribute scanning or <script src> discovery.
64
+ *
65
+ * alreadyKnownUrls (typically the caller's running downloadedJsUrls set) is
66
+ * filtered out BEFORE confirmJsContentType, not after — each subsequent pass
67
+ * rescans the same growing directory (strings() has no incremental-scan mode),
68
+ * so without this every already-confirmed URL from a prior pass would otherwise
69
+ * trigger a redundant live GET request every single pass.
70
+ */
71
+ const generic_stringsDiscovery = (outputDir_1, ...args_1) => __awaiter(void 0, [outputDir_1, ...args_1], void 0, function* (outputDir, alreadyKnownUrls = new Set()) {
72
+ if (!fs.existsSync(outputDir))
73
+ return [];
74
+ const tmpStringsFile = path.join(outputDir, `.generic-strings-pass-${stringsPassCounter++}.json`);
75
+ try {
76
+ yield strings(outputDir, tmpStringsFile, false, "", false, false, false);
77
+ }
78
+ catch (err) {
79
+ printMsg(MSG.Warn, `[!] Generic strings discovery pass failed: ${err}`);
80
+ return [];
81
+ }
82
+ let allStrings;
83
+ try {
84
+ allStrings = JSON.parse(fs.readFileSync(tmpStringsFile, "utf-8"));
85
+ }
86
+ catch (_a) {
87
+ return [];
88
+ }
89
+ finally {
90
+ try {
91
+ fs.unlinkSync(tmpStringsFile);
92
+ }
93
+ catch (_b) {
94
+ /* best-effort cleanup — a leftover temp file isn't fatal */
95
+ }
96
+ }
97
+ const candidates = findJsPathCandidatesFromStrings(allStrings, (p) => fs.readFileSync(p, "utf-8")).filter((u) => !alreadyKnownUrls.has(u));
98
+ if (candidates.length === 0)
99
+ return [];
100
+ return confirmJsContentType(candidates);
101
+ });
102
+ export default generic_stringsDiscovery;
103
+ //# sourceMappingURL=generic_stringsDiscovery.js.map