@js-recon/js-recon 1.3.1-beta.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 (361) hide show
  1. package/.gitattributes +2 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. package/.github/ISSUE_TEMPLATE/new_tech_support_request.md +26 -0
  5. package/.github/workflows/build-and-prettify.yaml +121 -0
  6. package/.github/workflows/pr_checker.yml +22 -0
  7. package/.github/workflows/publish-js-recon.yml +169 -0
  8. package/.prettierignore +2 -0
  9. package/.prettierrc +6 -0
  10. package/CHANGELOG.md +692 -0
  11. package/CLAUDE.md +290 -0
  12. package/Dockerfile +34 -0
  13. package/LICENSE +21 -0
  14. package/README.md +101 -0
  15. package/SECURITY.md +37 -0
  16. package/build/analyze/engine/astEngine.js +224 -0
  17. package/build/analyze/engine/astEngine.js.map +1 -0
  18. package/build/analyze/engine/index.js +59 -0
  19. package/build/analyze/engine/index.js.map +1 -0
  20. package/build/analyze/engine/requestEngine.js +100 -0
  21. package/build/analyze/engine/requestEngine.js.map +1 -0
  22. package/build/analyze/helpers/engineHelpers/findDirectAssignment.js +37 -0
  23. package/build/analyze/helpers/engineHelpers/findDirectAssignment.js.map +1 -0
  24. package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js +29 -0
  25. package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js.map +1 -0
  26. package/build/analyze/helpers/engineHelpers/resolveFunctionIdentifier.js +38 -0
  27. package/build/analyze/helpers/engineHelpers/resolveFunctionIdentifier.js.map +1 -0
  28. package/build/analyze/helpers/engineHelpers/taintFlow.js +250 -0
  29. package/build/analyze/helpers/engineHelpers/taintFlow.js.map +1 -0
  30. package/build/analyze/helpers/initRules.js +111 -0
  31. package/build/analyze/helpers/initRules.js.map +1 -0
  32. package/build/analyze/helpers/outputHelper.js +14 -0
  33. package/build/analyze/helpers/outputHelper.js.map +1 -0
  34. package/build/analyze/helpers/schemas.js +57 -0
  35. package/build/analyze/helpers/schemas.js.map +1 -0
  36. package/build/analyze/helpers/validate.js +89 -0
  37. package/build/analyze/helpers/validate.js.map +1 -0
  38. package/build/analyze/index.js +150 -0
  39. package/build/analyze/index.js.map +1 -0
  40. package/build/analyze/types/index.js +2 -0
  41. package/build/analyze/types/index.js.map +1 -0
  42. package/build/api_gateway/checkFeasibility.js +41 -0
  43. package/build/api_gateway/checkFeasibility.js.map +1 -0
  44. package/build/api_gateway/checkFireWallBlocking.js +33 -0
  45. package/build/api_gateway/checkFireWallBlocking.js.map +1 -0
  46. package/build/api_gateway/genReq.js +205 -0
  47. package/build/api_gateway/genReq.js.map +1 -0
  48. package/build/api_gateway/index.js +291 -0
  49. package/build/api_gateway/index.js.map +1 -0
  50. package/build/endpoints/gen_report/gen_json.js +30 -0
  51. package/build/endpoints/gen_report/gen_json.js.map +1 -0
  52. package/build/endpoints/gen_report/utility/iterate_n_store.js +64 -0
  53. package/build/endpoints/gen_report/utility/iterate_n_store.js.map +1 -0
  54. package/build/endpoints/index.js +101 -0
  55. package/build/endpoints/index.js.map +1 -0
  56. package/build/endpoints/next_js/client_jsFilesHref.js +100 -0
  57. package/build/endpoints/next_js/client_jsFilesHref.js.map +1 -0
  58. package/build/endpoints/next_js/client_jsonParse.js +89 -0
  59. package/build/endpoints/next_js/client_jsonParse.js.map +1 -0
  60. package/build/endpoints/next_js/client_mappedJsonFile.js +103 -0
  61. package/build/endpoints/next_js/client_mappedJsonFile.js.map +1 -0
  62. package/build/endpoints/next_js/client_subsequentRequests.js +211 -0
  63. package/build/endpoints/next_js/client_subsequentRequests.js.map +1 -0
  64. package/build/fingerprint/index.js +123 -0
  65. package/build/fingerprint/index.js.map +1 -0
  66. package/build/globalConfig.js +16 -0
  67. package/build/globalConfig.js.map +1 -0
  68. package/build/index.js +332 -0
  69. package/build/index.js.map +1 -0
  70. package/build/lazyLoad/angular/angular_getFromMainJs.js +55 -0
  71. package/build/lazyLoad/angular/angular_getFromMainJs.js.map +1 -0
  72. package/build/lazyLoad/angular/angular_getFromPageSource.js +43 -0
  73. package/build/lazyLoad/angular/angular_getFromPageSource.js.map +1 -0
  74. package/build/lazyLoad/downloadFilesUtil.js +127 -0
  75. package/build/lazyLoad/downloadFilesUtil.js.map +1 -0
  76. package/build/lazyLoad/downloadLoadedJsUtil.js +44 -0
  77. package/build/lazyLoad/downloadLoadedJsUtil.js.map +1 -0
  78. package/build/lazyLoad/downloadQueue.js +191 -0
  79. package/build/lazyLoad/downloadQueue.js.map +1 -0
  80. package/build/lazyLoad/globals.js +107 -0
  81. package/build/lazyLoad/globals.js.map +1 -0
  82. package/build/lazyLoad/index.js +377 -0
  83. package/build/lazyLoad/index.js.map +1 -0
  84. package/build/lazyLoad/next_js/NextJsCrawler.js +332 -0
  85. package/build/lazyLoad/next_js/NextJsCrawler.js.map +1 -0
  86. package/build/lazyLoad/next_js/next_GetJSScript.js +126 -0
  87. package/build/lazyLoad/next_js/next_GetJSScript.js.map +1 -0
  88. package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js +83 -0
  89. package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js.map +1 -0
  90. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +222 -0
  91. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -0
  92. package/build/lazyLoad/next_js/next_SubsequentRequests.js +208 -0
  93. package/build/lazyLoad/next_js/next_SubsequentRequests.js.map +1 -0
  94. package/build/lazyLoad/next_js/next_bruteForceJsFiles.js +37 -0
  95. package/build/lazyLoad/next_js/next_bruteForceJsFiles.js.map +1 -0
  96. package/build/lazyLoad/next_js/next_buildId.js +55 -0
  97. package/build/lazyLoad/next_js/next_buildId.js.map +1 -0
  98. package/build/lazyLoad/next_js/next_getClientSidePaths.js +83 -0
  99. package/build/lazyLoad/next_js/next_getClientSidePaths.js.map +1 -0
  100. package/build/lazyLoad/next_js/next_globals.js +8 -0
  101. package/build/lazyLoad/next_js/next_globals.js.map +1 -0
  102. package/build/lazyLoad/next_js/next_parseLayoutJs.js +116 -0
  103. package/build/lazyLoad/next_js/next_parseLayoutJs.js.map +1 -0
  104. package/build/lazyLoad/next_js/next_promiseResolve.js +85 -0
  105. package/build/lazyLoad/next_js/next_promiseResolve.js.map +1 -0
  106. package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js +51 -0
  107. package/build/lazyLoad/next_js/next_scriptTagsSubsequentRequests.js.map +1 -0
  108. package/build/lazyLoad/nuxt_js/nuxt_astParse.js +202 -0
  109. package/build/lazyLoad/nuxt_js/nuxt_astParse.js.map +1 -0
  110. package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +82 -0
  111. package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js.map +1 -0
  112. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +108 -0
  113. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -0
  114. package/build/lazyLoad/react/react_followImports.js +105 -0
  115. package/build/lazyLoad/react/react_followImports.js.map +1 -0
  116. package/build/lazyLoad/react/react_getScriptTags.js +52 -0
  117. package/build/lazyLoad/react/react_getScriptTags.js.map +1 -0
  118. package/build/lazyLoad/react/react_sourcemapUrls.js +44 -0
  119. package/build/lazyLoad/react/react_sourcemapUrls.js.map +1 -0
  120. package/build/lazyLoad/react/react_webpackChunkPaths.js +188 -0
  121. package/build/lazyLoad/react/react_webpackChunkPaths.js.map +1 -0
  122. package/build/lazyLoad/sourcemap.js +188 -0
  123. package/build/lazyLoad/sourcemap.js.map +1 -0
  124. package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js +162 -0
  125. package/build/lazyLoad/svelte/svelte_discoverPagesFromJs.js.map +1 -0
  126. package/build/lazyLoad/svelte/svelte_getFromPageSource.js +91 -0
  127. package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -0
  128. package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js +180 -0
  129. package/build/lazyLoad/svelte/svelte_recursivePageCrawl.js.map +1 -0
  130. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +123 -0
  131. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -0
  132. package/build/lazyLoad/techDetect/checkAngularJS.js +70 -0
  133. package/build/lazyLoad/techDetect/checkAngularJS.js.map +1 -0
  134. package/build/lazyLoad/techDetect/checkNextJS.js +45 -0
  135. package/build/lazyLoad/techDetect/checkNextJS.js.map +1 -0
  136. package/build/lazyLoad/techDetect/checkNuxtJS.js +39 -0
  137. package/build/lazyLoad/techDetect/checkNuxtJS.js.map +1 -0
  138. package/build/lazyLoad/techDetect/checkReact.js +86 -0
  139. package/build/lazyLoad/techDetect/checkReact.js.map +1 -0
  140. package/build/lazyLoad/techDetect/checkSvelte.js +69 -0
  141. package/build/lazyLoad/techDetect/checkSvelte.js.map +1 -0
  142. package/build/lazyLoad/techDetect/checkVueJS.js +118 -0
  143. package/build/lazyLoad/techDetect/checkVueJS.js.map +1 -0
  144. package/build/lazyLoad/techDetect/index.js +161 -0
  145. package/build/lazyLoad/techDetect/index.js.map +1 -0
  146. package/build/lazyLoad/vue/vue_RuntimeJs.js +169 -0
  147. package/build/lazyLoad/vue/vue_RuntimeJs.js.map +1 -0
  148. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +102 -0
  149. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -0
  150. package/build/lazyLoad/vue/vue_discoverJsFiles.js +82 -0
  151. package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -0
  152. package/build/lazyLoad/vue/vue_getClientSidePaths.js +155 -0
  153. package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -0
  154. package/build/lazyLoad/vue/vue_jsImports.js +76 -0
  155. package/build/lazyLoad/vue/vue_jsImports.js.map +1 -0
  156. package/build/lazyLoad/vue/vue_pageSrc.js +60 -0
  157. package/build/lazyLoad/vue/vue_pageSrc.js.map +1 -0
  158. package/build/lazyLoad/vue/vue_reconstructSourceMaps.js +64 -0
  159. package/build/lazyLoad/vue/vue_reconstructSourceMaps.js.map +1 -0
  160. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +142 -0
  161. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -0
  162. package/build/lazyLoad/vue/vue_severalJsFilesHome.js +57 -0
  163. package/build/lazyLoad/vue/vue_severalJsFilesHome.js.map +1 -0
  164. package/build/lazyLoad/vue/vue_sourcemapExtract.js +166 -0
  165. package/build/lazyLoad/vue/vue_sourcemapExtract.js.map +1 -0
  166. package/build/lazyLoad/vue/vue_stringJsFiles.js +148 -0
  167. package/build/lazyLoad/vue/vue_stringJsFiles.js.map +1 -0
  168. package/build/lazyLoad/vue/vue_viteMapDeps.js +89 -0
  169. package/build/lazyLoad/vue/vue_viteMapDeps.js.map +1 -0
  170. package/build/load/index.js +316 -0
  171. package/build/load/index.js.map +1 -0
  172. package/build/map/graphql/resolveGraphql.js +296 -0
  173. package/build/map/graphql/resolveGraphql.js.map +1 -0
  174. package/build/map/index.js +261 -0
  175. package/build/map/index.js.map +1 -0
  176. package/build/map/next_js/getAxiosInstances.js +64 -0
  177. package/build/map/next_js/getAxiosInstances.js.map +1 -0
  178. package/build/map/next_js/getExports.js +101 -0
  179. package/build/map/next_js/getExports.js.map +1 -0
  180. package/build/map/next_js/getFetchInstances.js +139 -0
  181. package/build/map/next_js/getFetchInstances.js.map +1 -0
  182. package/build/map/next_js/getTurbopackConnections.js +255 -0
  183. package/build/map/next_js/getTurbopackConnections.js.map +1 -0
  184. package/build/map/next_js/getWebpackConnections.js +235 -0
  185. package/build/map/next_js/getWebpackConnections.js.map +1 -0
  186. package/build/map/next_js/interactive.js +69 -0
  187. package/build/map/next_js/interactive.js.map +1 -0
  188. package/build/map/next_js/interactive_helpers/commandHandler.js +310 -0
  189. package/build/map/next_js/interactive_helpers/commandHandler.js.map +1 -0
  190. package/build/map/next_js/interactive_helpers/commandHelpers.js +245 -0
  191. package/build/map/next_js/interactive_helpers/commandHelpers.js.map +1 -0
  192. package/build/map/next_js/interactive_helpers/esqueryGen.js +370 -0
  193. package/build/map/next_js/interactive_helpers/esqueryGen.js.map +1 -0
  194. package/build/map/next_js/interactive_helpers/helpMenu.js +12 -0
  195. package/build/map/next_js/interactive_helpers/helpMenu.js.map +1 -0
  196. package/build/map/next_js/interactive_helpers/inputPatch.js +207 -0
  197. package/build/map/next_js/interactive_helpers/inputPatch.js.map +1 -0
  198. package/build/map/next_js/interactive_helpers/keybindings.js +90 -0
  199. package/build/map/next_js/interactive_helpers/keybindings.js.map +1 -0
  200. package/build/map/next_js/interactive_helpers/printer.js +23 -0
  201. package/build/map/next_js/interactive_helpers/printer.js.map +1 -0
  202. package/build/map/next_js/interactive_helpers/ui.js +88 -0
  203. package/build/map/next_js/interactive_helpers/ui.js.map +1 -0
  204. package/build/map/next_js/resolveAxios.js +152 -0
  205. package/build/map/next_js/resolveAxios.js.map +1 -0
  206. package/build/map/next_js/resolveAxiosHelpers/astNodeToJsonString.js +64 -0
  207. package/build/map/next_js/resolveAxiosHelpers/astNodeToJsonString.js.map +1 -0
  208. package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js +48 -0
  209. package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js.map +1 -0
  210. package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js +34 -0
  211. package/build/map/next_js/resolveAxiosHelpers/findAxiosClients.js.map +1 -0
  212. package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js +39 -0
  213. package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js.map +1 -0
  214. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +312 -0
  215. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -0
  216. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +173 -0
  217. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -0
  218. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +261 -0
  219. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -0
  220. package/build/map/next_js/resolveAxiosHelpers/interceptorHeaders.js +206 -0
  221. package/build/map/next_js/resolveAxiosHelpers/interceptorHeaders.js.map +1 -0
  222. package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js +168 -0
  223. package/build/map/next_js/resolveAxiosHelpers/processAxiosCall.js.map +1 -0
  224. package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js +121 -0
  225. package/build/map/next_js/resolveAxiosHelpers/processDirectAxiosCall.js.map +1 -0
  226. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +274 -0
  227. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -0
  228. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +518 -0
  229. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -0
  230. package/build/map/next_js/resolveAxiosHelpers/traceBody.js +913 -0
  231. package/build/map/next_js/resolveAxiosHelpers/traceBody.js.map +1 -0
  232. package/build/map/next_js/resolveFetch.js +533 -0
  233. package/build/map/next_js/resolveFetch.js.map +1 -0
  234. package/build/map/next_js/resolveNewRequest.js +749 -0
  235. package/build/map/next_js/resolveNewRequest.js.map +1 -0
  236. package/build/map/next_js/resolveServerActions.js +449 -0
  237. package/build/map/next_js/resolveServerActions.js.map +1 -0
  238. package/build/map/next_js/utils.js +1600 -0
  239. package/build/map/next_js/utils.js.map +1 -0
  240. package/build/map/react_js/getReactConnections.js +303 -0
  241. package/build/map/react_js/getReactConnections.js.map +1 -0
  242. package/build/map/react_js/interactive.js +4 -0
  243. package/build/map/react_js/interactive.js.map +1 -0
  244. package/build/map/react_js/react_resolveFetch.js +6 -0
  245. package/build/map/react_js/react_resolveFetch.js.map +1 -0
  246. package/build/map/svelte_js/interactive.js +58 -0
  247. package/build/map/svelte_js/interactive.js.map +1 -0
  248. package/build/map/svelte_js/interactive_helpers/commandHandler.js +4 -0
  249. package/build/map/svelte_js/interactive_helpers/commandHandler.js.map +1 -0
  250. package/build/map/vue_js/bodyResolver.js +477 -0
  251. package/build/map/vue_js/bodyResolver.js.map +1 -0
  252. package/build/map/vue_js/crossFileResolver.js +438 -0
  253. package/build/map/vue_js/crossFileResolver.js.map +1 -0
  254. package/build/map/vue_js/getViteConnections.js +343 -0
  255. package/build/map/vue_js/getViteConnections.js.map +1 -0
  256. package/build/map/vue_js/interactive.js +67 -0
  257. package/build/map/vue_js/interactive.js.map +1 -0
  258. package/build/map/vue_js/interactive_helpers/commandHandler.js +307 -0
  259. package/build/map/vue_js/interactive_helpers/commandHandler.js.map +1 -0
  260. package/build/map/vue_js/interactive_helpers/commandHelpers.js +39 -0
  261. package/build/map/vue_js/interactive_helpers/commandHelpers.js.map +1 -0
  262. package/build/map/vue_js/interactive_helpers/helpMenu.js +12 -0
  263. package/build/map/vue_js/interactive_helpers/helpMenu.js.map +1 -0
  264. package/build/map/vue_js/taint_utils.js +621 -0
  265. package/build/map/vue_js/taint_utils.js.map +1 -0
  266. package/build/map/vue_js/vue_resolveFetch.js +416 -0
  267. package/build/map/vue_js/vue_resolveFetch.js.map +1 -0
  268. package/build/map/vue_js/vue_resolveHttpClient.js +738 -0
  269. package/build/map/vue_js/vue_resolveHttpClient.js.map +1 -0
  270. package/build/map/vue_js/vue_resolveXhr.js +282 -0
  271. package/build/map/vue_js/vue_resolveXhr.js.map +1 -0
  272. package/build/mcp/chatOneShot.js +101 -0
  273. package/build/mcp/chatOneShot.js.map +1 -0
  274. package/build/mcp/claudeCodeCreds.js +150 -0
  275. package/build/mcp/claudeCodeCreds.js.map +1 -0
  276. package/build/mcp/cli.js +372 -0
  277. package/build/mcp/cli.js.map +1 -0
  278. package/build/mcp/commands.js +227 -0
  279. package/build/mcp/commands.js.map +1 -0
  280. package/build/mcp/config.js +68 -0
  281. package/build/mcp/config.js.map +1 -0
  282. package/build/mcp/index.js +50 -0
  283. package/build/mcp/index.js.map +1 -0
  284. package/build/mcp/intent.js +204 -0
  285. package/build/mcp/intent.js.map +1 -0
  286. package/build/mcp/jobs.js +199 -0
  287. package/build/mcp/jobs.js.map +1 -0
  288. package/build/mcp/mcpServer.js +241 -0
  289. package/build/mcp/mcpServer.js.map +1 -0
  290. package/build/mcp/providers.js +170 -0
  291. package/build/mcp/providers.js.map +1 -0
  292. package/build/mcp/skills.js +115 -0
  293. package/build/mcp/skills.js.map +1 -0
  294. package/build/mcp/tools.js +185 -0
  295. package/build/mcp/tools.js.map +1 -0
  296. package/build/refactor/index.js +85 -0
  297. package/build/refactor/index.js.map +1 -0
  298. package/build/refactor/next/index.js +109 -0
  299. package/build/refactor/next/index.js.map +1 -0
  300. package/build/refactor/react/index.js +636 -0
  301. package/build/refactor/react/index.js.map +1 -0
  302. package/build/report/index.js +68 -0
  303. package/build/report/index.js.map +1 -0
  304. package/build/report/utility/dataTables/genDataTablesPage.js +158 -0
  305. package/build/report/utility/dataTables/genDataTablesPage.js.map +1 -0
  306. package/build/report/utility/genHtml.js +516 -0
  307. package/build/report/utility/genHtml.js.map +1 -0
  308. package/build/report/utility/initReportDb.js +96 -0
  309. package/build/report/utility/initReportDb.js.map +1 -0
  310. package/build/report/utility/markdownGen/addAnalyze.js +53 -0
  311. package/build/report/utility/markdownGen/addAnalyze.js.map +1 -0
  312. package/build/report/utility/markdownGen/addMappedJson.js +33 -0
  313. package/build/report/utility/markdownGen/addMappedJson.js.map +1 -0
  314. package/build/report/utility/populateDb/populateAnalysisFindings.js +31 -0
  315. package/build/report/utility/populateDb/populateAnalysisFindings.js.map +1 -0
  316. package/build/report/utility/populateDb/populateEndpoints.js +50 -0
  317. package/build/report/utility/populateDb/populateEndpoints.js.map +1 -0
  318. package/build/report/utility/populateDb/populateMappedJson.js +31 -0
  319. package/build/report/utility/populateDb/populateMappedJson.js.map +1 -0
  320. package/build/report/utility/populateDb/populateMappedOpenapi.js +49 -0
  321. package/build/report/utility/populateDb/populateMappedOpenapi.js.map +1 -0
  322. package/build/run/index.js +446 -0
  323. package/build/run/index.js.map +1 -0
  324. package/build/run/interruptHandler.js +93 -0
  325. package/build/run/interruptHandler.js.map +1 -0
  326. package/build/strings/index.js +239 -0
  327. package/build/strings/index.js.map +1 -0
  328. package/build/strings/openapi.js +63 -0
  329. package/build/strings/openapi.js.map +1 -0
  330. package/build/strings/permutate.js +62 -0
  331. package/build/strings/permutate.js.map +1 -0
  332. package/build/strings/secrets.js +102 -0
  333. package/build/strings/secrets.js.map +1 -0
  334. package/build/utility/ai.js +97 -0
  335. package/build/utility/ai.js.map +1 -0
  336. package/build/utility/configureSandbox.js +14 -0
  337. package/build/utility/configureSandbox.js.map +1 -0
  338. package/build/utility/globals.js +322 -0
  339. package/build/utility/globals.js.map +1 -0
  340. package/build/utility/interfaces.js +2 -0
  341. package/build/utility/interfaces.js.map +1 -0
  342. package/build/utility/makeReq.js +448 -0
  343. package/build/utility/makeReq.js.map +1 -0
  344. package/build/utility/openapiGenerator.js +254 -0
  345. package/build/utility/openapiGenerator.js.map +1 -0
  346. package/build/utility/postmanGenerator.js +216 -0
  347. package/build/utility/postmanGenerator.js.map +1 -0
  348. package/build/utility/progressLog.js +50 -0
  349. package/build/utility/progressLog.js.map +1 -0
  350. package/build/utility/puppeteerInstance.js +5 -0
  351. package/build/utility/puppeteerInstance.js.map +1 -0
  352. package/build/utility/replaceUrlPlaceholders.js +48 -0
  353. package/build/utility/replaceUrlPlaceholders.js.map +1 -0
  354. package/build/utility/resolvePath.js +44 -0
  355. package/build/utility/resolvePath.js.map +1 -0
  356. package/build/utility/runSandboxed.js +42 -0
  357. package/build/utility/runSandboxed.js.map +1 -0
  358. package/build/utility/urlUtils.js +21 -0
  359. package/build/utility/urlUtils.js.map +1 -0
  360. package/contributing/nextjs.md +410 -0
  361. package/package.json +75 -0
package/CLAUDE.md ADDED
@@ -0,0 +1,290 @@
1
+ # js-recon
2
+
3
+ Static analysis tool that maps API endpoints and detects client-side security issues by analyzing Next.js (webpack/turbopack) and Vue.js bundles. Written in TypeScript, compiled to `build/` before running.
4
+
5
+ ## Build & run
6
+
7
+ ```bash
8
+ npm run cleanup # rm -rf build/ + tsc (full rebuild)
9
+ npm run start -- <subcommand> [options]
10
+ ```
11
+
12
+ `cleanup` must be run before testing any TypeScript change when using the `run` command.
13
+
14
+ ## Subcommands
15
+
16
+ | Command | Purpose |
17
+ | ------------- | ---------------------------------------------------------------------------------- |
18
+ | `lazyload` | Download JS chunks from a target URL |
19
+ | `strings` | Extract strings/paths/secrets from JS files |
20
+ | `map` | Parse webpack/turbopack bundles into a structured `mapped.json` |
21
+ | `endpoints` | Extract client-side routes |
22
+ | `analyze` | Run YAML rules against `mapped.json` / OpenAPI spec |
23
+ | `report` | Generate HTML/SQLite report |
24
+ | `run` | Run all of the above in sequence (primary interface) |
25
+ | `api-gateway` | Manage AWS API Gateway for IP rotation |
26
+ | `mcp` | AI-powered CLI / one-shot chat (`-c`) / Model Context Protocol server (`--server`) |
27
+
28
+ ## Key source files
29
+
30
+ - `src/index.ts` — CLI entry point; all subcommand definitions and option declarations live here
31
+ - `src/run/index.ts` — orchestrates the full pipeline (`run` subcommand); two tech-specific flows (Next.js 8-step, Vue 4-step)
32
+ - `src/analyze/index.ts` — loads/validates rules, runs AST and request engines
33
+ - `src/analyze/helpers/initRules.ts` — downloads/caches rules from GitHub to `~/.js-recon/rules`
34
+ - `src/analyze/helpers/validate.ts` — validates rules and checks `js_recon_version` compatibility
35
+ - `src/analyze/helpers/schemas.ts` — Zod schema for rule YAML files
36
+ - `src/map/graphql/resolveGraphql.ts` — framework-agnostic GraphQL operation scanner. Visits every `StringLiteral` and `TemplateLiteral` in every JS file, validates with the `graphql` library's `parse()`, and emits each operation as a POST request under a flat `GraphQL` collection folder. Inlines transitively-referenced fragment definitions into each printed query so emitted requests are self-contained. Runs in every framework branch of `map/index.ts` when `--openapi` is on and `--no-graphql`/`--ngql` is not set.
37
+ - `src/map/next_js/resolveFetch.ts` — resolves `fetch()` calls, detects Next.js framework chunks
38
+ - `src/map/next_js/resolveServerActions.ts` — detects `createServerReference(actionId, ...)` calls, derives App Router routes from chunk file paths, traces argument call sites (same-chunk and cross-chunk), and emits POST endpoints with `next-action` headers and typed arg hints (e.g. `<string:userId>`) into the global OpenAPI output
39
+ - `src/map/next_js/utils.ts` — `resolveNodeValue`, `resolveVariableInChunk`, `substituteVariablesInString`
40
+ - `src/map/vue_js/vue_resolveXhr.ts` — directory-scan resolver for `new XMLHttpRequest()` + `.open()/.setRequestHeader()/.send()` patterns. Shared by Vue/React/Svelte pipelines; the `frameworkName` arg only changes log labels. Reaches ground-truth XHR sites but in axios/Got/Ky-style bundles the URL/method come from a dispatcher config (`re.url`, `re.method`) and resolve only to opaque `[member:re.url]` placeholders that taint analysis cannot unwind across the library's internal dispatch chain — those entries fail the `looksLikeUrl` check at emit time. Catch the wrapper-level call instead via `vue_resolveHttpClient`.
41
+ - `src/map/vue_js/vue_resolveHttpClient.ts` — directory-scan resolver for `<obj>.<verb>(<url>, [body], [config])` calls where `<verb>` ∈ {get,post,put,delete,patch,head,options}. Designed for bundles whose transport layer overrides `XMLHttpRequest.prototype.{open,send,setRequestHeader}` (axios xhrAdapter and similar wrappers): the override layer is irrelevant to URL extraction because the literal URL is composed at the client-instance method call site, not inside the adapter. The `looksLikeUrl` heuristic (post-placeholder-strip, must contain `/` or scheme) filters out `Map.get` / `Headers.delete` / `EventBus.post` false positives while keeping partially-resolved URLs like `[call:base()]<literal>/[var X]`. Three resolution stages run on every captured callsite — each addresses a separate gap exposed when an RPC wrapper is hidden behind multiple layers of webpack-exported helpers:
42
+ 1. `resolveFromAssignments` — walks `binding.constantViolations` for `[unresolved: NAME]` markers, so identifiers declared as `let X;` and assigned later in the function body (e.g. `(X = a + "/" + b)` inside a sequence expression) resolve to their RHS. `resolveNodeValue`'s Identifier handler only looks at `binding.init`, which is empty for late-assigned locals.
43
+ 2. `expandParamPlaceholders` — fans out one captured callsite into one URL per caller chain. Walks the `enclosingFn.parent` chain to find which named function declares each `[param:X]`, then substitutes **every** placeholder owned by that same function from a single caller's args (keeps `[param:e]`/`[param:t]` consistent across one caller — never mixing args from different callsites). Recurses on the caller's `enclosingFn` so a forwarding wrapper (`Se(e,t,n) → ae.request(e,t,n,...)`) walks up to the wrapper's own callers.
44
+ 3. Taint substitution falls back to `substituteCallerPlaceholders` / `substituteCallerHeaders` for body/header placeholders that don't have multi-caller fan-out semantics.
45
+
46
+ Wired into Vue / React / Svelte pipelines in `map/index.ts`.
47
+
48
+ - `src/map/vue_js/taint_utils.ts` — shared taint analysis primitives. Several pieces are non-obvious and exist to make `vue_resolveHttpClient` (and `vue_resolveXhr`) work on webpack output:
49
+ - `EnclosingFn.paramNames` + `parent` chain: `resolveNodeValue` emits `[param:X]` for any param at any index in any enclosing function. The chain lets the helpers resolve such a marker against whichever enclosing scope actually declared X — bundled code routinely nests the resolution callsite inside an anonymous `.then(function ($) {…})` whose own params don't include X, while X is a param of an outer named function.
50
+ - `buildAliasMap`: collects `{ exportedName: localBinding }` and `{ exportedName: () => localBinding }` patterns from object literals on a **per-file** basis. Webpack's `a.d(b, { name: () => Binding })` getter exports and re-export registries (`const ae = { request: Me }`) hide the local minifier name behind a meaningful key; without this map, `getCallers("Me")` would miss every `ae.request(...)` / `r.default.request(...)` callsite. **The map must be file-scoped** — minifier locals (`Se`, `Me`) collide across modules, and a global alias map blends unrelated functions into the same name set.
51
+ - `makeGetCallers` accepts an optional `sourceFile` argument so callers can scope alias lookup to the file where the binding was declared. Direct minifier-local matches (`bindingName.length ≤ 2`) are dropped from the candidate list because they generate too many false positives across files; meaningful aliases (length > 2) are kept and used for both bare-identifier (`X(...)`) and member-expression (`<anything>.X(...)`) callsite matching. Overflow returns the partial caller list rather than nothing — the file-scoped alias map already suppresses noise, so partial coverage beats none.
52
+ - `src/map/next_js/getWebpackConnections.ts` — extracts chunk code from webpack bundles
53
+ - `src/map/next_js/interactive_helpers/esqueryGen.ts` — `esquery` interactive command: minifies a pasted snippet, matches it against each chunk's minified AST nodes, prints loose/strict selectors. Vue's command handler imports the same module — keep it framework-agnostic.
54
+ - `src/map/next_js/interactive.ts` / `src/map/vue_js/interactive.ts` — export both the blessed-backed `interactive()` entry and a headless `runCommands(chunks, mapFile, commands)` that pipes `outputBox.log` to stdout for `-c/--command` execution.
55
+ - `src/map/next_js/interactive_helpers/inputPatch.ts` — `enableCursorInput(inputBox)` patches a blessed textbox instance to support cursor movement, mid-string insertion, and paste-at-cursor. It overrides `_listener`/`setValue`/`_updateCursor`/`clearValue` on the instance. **Don't try to remove blessed's listener after the fact** — blessed re-binds `this._listener` on every focus, so overriding `_listener` on the instance is the only race-free approach. Shared by Next.js and Vue interactive entries.
56
+ - `src/globalConfig.ts` — current version string and tool-wide constants
57
+ - `src/utility/globals.ts` — mutable global state (tech detection result, AI config, OpenAPI flag, etc.)
58
+
59
+ ## `run` pipeline in detail
60
+
61
+ `run` is the primary subcommand. It calls `processUrl` for each target, which dispatches to one of two pipelines based on the detected front-end framework (`globalsUtil.getTech()`).
62
+
63
+ ### Next.js pipeline (8 steps)
64
+
65
+ 1. **Lazyload** — downloads initial JS chunks via Puppeteer; detects framework; sets `globalsUtil.getTech()` to `"next"`
66
+ 2. **Strings** — scans downloaded JS for strings, extracts URL paths → `extracted_urls.json`
67
+ 3. **Lazyload (subsequent requests)** — re-crawls using the extracted paths to fetch dynamically loaded chunks; also fetches `buildId`
68
+ 4. **Strings (pass 2)** — re-runs strings on the expanded chunk set; generates `extracted_urls.txt` (permuted) and `extracted_urls-openapi.json`; optionally scans secrets (`--secrets`)
69
+ 5. **Lazyload re-pass (step 4.5)** — a second subsequent-requests crawl to pick up chunks for dynamic routes discovered in pass 2
70
+ 6. **Strings re-pass (step 4.6)** — strings pass over the re-pass chunks
71
+ 7. **Map** — parses webpack/turbopack bundles; resolves `fetch()` calls and axios usage; generates `mapped.json` and `mapped-openapi.json`; CDN-aware: if JS was served from a different host, `getCdnDir` finds the CDN output dir and passes that to map instead of `outputDir/host`
72
+ 8. **Endpoints** — extracts client-side route paths; uses `___subsequent_requests` directory presence to decide whether to pass a JS directory
73
+ 9. **Analyze** — loads YAML rules (from `-r/--rules` if provided, otherwise default rules cache); runs AST engine and request engine; writes `analyze.json`
74
+ 10. **Report** — populates SQLite DB (`js-recon.db`) and generates HTML report
75
+
76
+ ### Vue.js pipeline (4 steps)
77
+
78
+ 1. **Lazyload** — same as Next.js step 1; sets `globalsUtil.getTech()` to `"vue"`
79
+ 2. **Map** — scans the entire `outputDir` (Vue chunks spread across asset hosts)
80
+ 3. **Analyze** — same rule loading as Next.js; `-r/--rules` is forwarded here too
81
+ 4. **Report** — same as Next.js; if `endpoints.json` doesn't exist it is written as `[]` since Vue endpoints extraction isn't implemented yet
82
+
83
+ ### Tech detection flow
84
+
85
+ `lazyLoad` sets the global tech string. If it remains `""` after lazyload, `run` exits (single URL) or skips (batch). Techs other than `"next"` and `"vue"` only get lazyload; the rest of the pipeline is skipped with a warning.
86
+
87
+ ### Batch mode
88
+
89
+ When `-u` points to a file of URLs, each line is processed sequentially. For each URL:
90
+
91
+ - A subdirectory `output/<host>/` is created
92
+ - `clearJsUrls()` / `clearJsonUrls()` reset the URL sets so previous targets don't bleed over
93
+ - All output paths are prefixed with `workingDir/`
94
+
95
+ ## Adding a new flag to `run`
96
+
97
+ 1. Declare the option in `src/index.ts` on the `run` command (`.option(...)`)
98
+ 2. If it configures a global, call the setter in the `action` handler before `await run(cmd)`
99
+ 3. If it needs to reach a downstream module (like `analyze`), thread it through `cmd` — `processUrl` receives the full `cmd` object and passes it to submodule calls
100
+
101
+ **Example — `-r/--rules` flag (added in this codebase):**
102
+
103
+ - Declared in `src/index.ts`: `.option("-r, --rules <file/dir>", "Rules file or directory (passed to analyze module)")`
104
+ - In `src/run/index.ts` the `analyze` calls use `cmd.rules || ""` — empty string tells `analyze` to use the default rules cache
105
+
106
+ **Example — `--lazyload-timeout` flag:**
107
+
108
+ - Declared in `src/index.ts` on both the `lazyload` and `run` commands: `.option("--lazyload-timeout <minutes>", ..., "30")`
109
+ - Threaded directly into each `lazyLoad()` call as `Number(cmd.lazyloadTimeout) * 60 * 1000` (converts minutes → ms). Unlike flags that set a global, this one is passed as a parameter — no setter in the action handler.
110
+
111
+ ## Interactive-mode commands
112
+
113
+ The `map -i` blessed UI dispatches user input through `interactive_helpers/commandHandler.ts`. The same handler runs headlessly when commands are supplied via `-c/--command`:
114
+
115
+ - The `-c` option's commander coerce function splits each value on `&&` (with optional whitespace) and concatenates into a single command array. So `-c "list fetch && esquery * fetch"` is two commands; passing `-c` twice has the same effect.
116
+ - `map`'s entry point checks `commands.length > 0` first — if non-empty, it calls `nextRunCommands` / `vueRunCommands` and skips the blessed UI even when `-i` is also set.
117
+ - New commands should be added to **both** `next_js/interactive_helpers/commandHandler.ts` and `vue_js/interactive_helpers/commandHandler.ts`, plus the corresponding `helpMenu.ts` entry. When the implementation is framework-agnostic (e.g. `esquery`), put it under `next_js/interactive_helpers/` and import it from the Vue handler — don't duplicate.
118
+ - `list server_actions` is intentionally Next.js-only (it reads from `getOpenapiOutput()` filtered by `next-action` header) and has no Vue counterpart.
119
+
120
+ ## Reversing RPC-style API calls from manual browser observations
121
+
122
+ When the user supplies a call-stack screenshot or notes from a real session ("XHR sent here, sink is this prototype override, body comes from this function"), the goal isn't to reproduce that exact target — it's to find the _generic pattern_ that the bundler emitted and add resolver support for it. The reverse-engineering workflow that produced the HTTP-client resolver:
123
+
124
+ 1. **Read the call stack bottom-up.** The deepest frame is almost always the transport (`XMLHttpRequest.send`, `fetch`); ignore it. The next frames going up are the HTTP library (axios's `_request` / `dispatchXhrRequest`); ignore those too unless the URL is literal at that level. Look for the first frame whose source line contains _a recognisable path fragment or template string_ — that's the wrapper callsite worth resolving.
125
+ 2. **Identify the URL composition site.** Open the file at that frame in the downloaded bundle (`output/<host>/static/js/<chunk>.js`) and find the literal. Typical webpack patterns are `client.post(base + "literal/path/" + paramVar, body, config)` or `client.request({ url: base + "/" + paramVar, method: "POST" })`. Note what's a literal, what's a parameter, what's a local variable.
126
+ 3. **Walk inward from the wrapper.** For every non-literal in the URL, find where it came from in the same function. If it's a `let X;` followed by `X = a + "/" + b` in a sequence expression, that's `resolveFromAssignments`' territory. If it's a function parameter, that's taint analysis' territory.
127
+ 4. **Walk outward from the wrapper.** Look at the callers of the enclosing function. In webpack bundles the function is usually exported through one of:
128
+ - A registry object: `const ae = { request: Me, postUnchecked: Se }` — callsites read `ae.request(...)`, NOT `Me(...)`.
129
+ - A webpack getter export: `a.d(b, { request: () => Me })` — same effect, different shape.
130
+ - Both. The same binding often appears in multiple aliases.
131
+
132
+ Both shapes are recognised by `buildAliasMap` in `taint_utils.ts` and _must be matched per file_ — minifier locals like `Se`, `Me` collide across modules.
133
+
134
+ 5. **Trace forwarding wrappers all the way out.** A wrapper like `Se(e, t, n) → ae.request(e, t, n, ...)` just forwards its parameters. After substituting at the wrapper level, recurse into Se's own callers; the externally-meaningful arguments (`s.signIn.namespace`) are several layers up.
135
+ 6. **Confirm the literal source.** The outermost caller passes a `MemberExpression` like `s.signIn.namespace`. Find the `const s = { signIn: { namespace: "...", method: "..." } }` declaration — `resolveNodeValue` handles this naturally as long as the binding is in scope at the caller's location.
136
+
137
+ If at any layer the new resolver returns `[unresolved: X]` or `[param:X]`, that's a signal which primitive is missing — extend `taint_utils.ts` (chain walk, per-file aliases, member-expression matching, late-assignment recovery) rather than special-casing the wrapper. The goal is a primitive that resolves _similar_ RPC-style libraries in unrelated apps, not the one bundle in front of you.
138
+
139
+ **Do not encode target-specific paths or service names in code or comments.** When iterating, run `map` against the downloaded chunks and grep the resulting `mapped-openapi.json` for the expected URL fragment — never paste that fragment into source.
140
+
141
+ ### How to test changes here
142
+
143
+ The HTTP-client resolver runs inside the `map` step of the React/Vue/Svelte pipeline; verify it as part of the full `run` pipeline (see "Testing a change" below). Quick iteration loop while debugging:
144
+
145
+ ```bash
146
+ npx tsc
147
+ node --max-old-space-size=8192 build/index.js map \
148
+ -d output/<host>/static/js -o /tmp/jsr-mapped -t react -f json \
149
+ 2>&1 | grep "URL: " | sort -u
150
+ ```
151
+
152
+ This bypasses the slow `lazyload` step by reusing already-downloaded chunks. The final acceptance test is still `npm run cleanup && npm run start -- run -u <target> -y -k`; grep `mapped-openapi.json` for the expected resolved URL fragment.
153
+
154
+ ## Rules
155
+
156
+ Rules are YAML files (`.yml`/`.yaml`) in two places:
157
+
158
+ - **Workspace:** `../js-recon-rules/` (relative to this repo)
159
+ - **Installed cache:** `~/.js-recon/rules`
160
+
161
+ `initRules` downloads rules from GitHub when missing or when the cached version doesn't match the latest release. `js_recon_version` (required) must be declared in every rule (e.g. `js_recon_version: ">=X.Y.Z"`); `initRules` uses it to validate compatibility and skips incompatible rules with a warning. The version check strips prerelease suffixes (e.g. `1.3.1-alpha.3` → `[1,3,1]`).
162
+
163
+ Rule categories:
164
+
165
+ - `ast/` — AST-based pattern matching against chunk code (uses `@babel/parser` + `esquery`)
166
+ - `request/` — OpenAPI/request-level checks against the resolved endpoint list
167
+
168
+ When `-r` points to a single file, only that rule is loaded. When it points to a directory, all `.yml`/`.yaml` files are loaded recursively.
169
+
170
+ ## Testing a change
171
+
172
+ **Testing is mandatory for every change.** Before reporting a task complete:
173
+
174
+ 1. Run `npm run cleanup` to rebuild TypeScript.
175
+ 2. Run the `run` subcommand against the target the user provides. Do not use `analyze` or other individual subcommands as a substitute — the `run` subcommand must be used to validate end-to-end behavior.
176
+ 3. If the user has not provided a target, ask for one before proceeding.
177
+
178
+ Typical test invocation:
179
+
180
+ ```bash
181
+ npm run cleanup && npm run start -- run -u <target-url> -y -k
182
+ ```
183
+
184
+ ## Release process
185
+
186
+ Releasing a new version touches three repos. Work on `dev` (js-recon, js-recon-rules) and `stage` (js-recon-docs). Do **not** touch `js-recon-research` — it is private and excluded from releases.
187
+
188
+ **Ordering is critical**: release js-recon first (including the GitHub release so CI publishes it to npm), then snapshot and PR js-recon-docs. This ensures the docs `version_check` CI step passes instead of failing due to a missing npm package.
189
+
190
+ ### When a user asks to prepare a release
191
+
192
+ Before writing any files, gather the current state:
193
+
194
+ 1. Check `package.json` and `src/globalConfig.ts` for the current version — both must match. If they don't, fix them first.
195
+ 2. Find the latest git tag: `git describe --tags --abbrev=0`
196
+ 3. List unreleased commits: `git log <latest-tag>..HEAD --oneline | grep -E "^[a-f0-9]+ (feat|fix)"`
197
+ 4. Check if `CHANGELOG.md` already has an `(unreleased)` entry for the current version — if so, only the date needs to be added.
198
+ 5. Check `js-recon-rules` for unreleased commits since its last tag: `git -C ../js-recon-rules log $(git -C ../js-recon-rules describe --tags --abbrev=0)..HEAD --oneline`
199
+ 6. Check `js-recon-docs` for commits since the last version snapshot: `git -C ../js-recon-docs log --oneline -20`
200
+
201
+ ### Phase 1 — js-recon (release first)
202
+
203
+ 1. **Bump version** (if not already at the target version) — update `version` in `src/globalConfig.ts` and `package.json`. Both must match.
204
+
205
+ 2. **Update CHANGELOG** — if the version heading already exists as `(unreleased)`, replace it with the real date (`## <version> - <YYYY-MM-DD>`). Otherwise add the full section with `### Fixed`, `### Performance`, `### Added`, `### Changed` sub-sections. Verify every `feat`/`fix` commit since the previous tag is covered:
206
+
207
+ ```bash
208
+ git log <prev-tag>..HEAD --oneline | grep -E "^[a-f0-9]+ (feat|fix)"
209
+ ```
210
+
211
+ 3. **Update README** — ensure the Commands table in `README.md` lists every subcommand declared in `src/index.ts`. The `refactor` and `load` subcommands are easy to miss — explicitly verify they are present.
212
+
213
+ 4. **Update rules** (`js-recon-rules` repo, `dev` branch) — if there are substantive unreleased commits (not just merge/cleanup commits), update `CHANGELOG.md` and `version.txt`, push to `dev`, and open a PR (`shriyanss/js-recon-rules` dev→main, title=rules version, body=rules changelog section).
214
+
215
+ 5. **Push** `js-recon` dev branch: `git push origin dev`
216
+
217
+ 6. **Open PR** using `gh pr create`:
218
+ | Repo | Source | Target | Title | Body |
219
+ |------|--------|--------|-------|------|
220
+ | `shriyanss/js-recon` | `dev` | `main` | bare version string (e.g. `v1.3.1-alpha.4`) | raw `## <version>` changelog section |
221
+
222
+ 7. **Monitor js-recon CI** — use `gh pr checks <pr-number> --repo shriyanss/js-recon` and poll until all checks complete. Handle CodeRabbit suggestions (see below). Do NOT merge — wait for user approval.
223
+
224
+ 8. **Create GitHub release** — after the PR is merged to main:
225
+
226
+ ```bash
227
+ gh release create v<version> \
228
+ --repo shriyanss/js-recon \
229
+ --title "v<version>" \
230
+ --notes "<changelog section>" \
231
+ --prerelease # set for any version containing "alpha" or "beta"
232
+ ```
233
+
234
+ `--latest` flag rules:
235
+ - **Omit** `--latest` if the version contains `alpha` or `beta`
236
+ - **Add** `--latest` only for stable releases (no pre-release suffix in the version string)
237
+
238
+ Previous tag is left to GitHub's automatic detection (do not set `--target` or `--tag` beyond the tag name itself).
239
+
240
+ 9. **Wait for npm publish** — monitor the release pipeline: `gh run list --repo shriyanss/js-recon --workflow release`. Confirm the npm package is live at the new version before proceeding to Phase 2.
241
+
242
+ ### Phase 2 — js-recon-docs (after npm is live)
243
+
244
+ 10. **Fix doc gaps** — cross-check `docs/docs/modules/*.md` against `src/index.ts` and the new CHANGELOG entries. Add or update any missing flags, options, or command descriptions.
245
+
246
+ 11. **Snapshot** — run inside `js-recon-docs/`:
247
+
248
+ ```bash
249
+ npx docusaurus docs:version <version>
250
+ ```
251
+
252
+ This creates `versioned_docs/version-<version>/`, updates `versions.json`, and creates `versioned_sidebars/version-<version>-sidebars.json`.
253
+
254
+ 12. **Keep `lastVersion` stable** — `lastVersion` in `docusaurus.config.ts` stays pointing to the last stable release. Do **not** update it for alpha or beta versions.
255
+
256
+ 13. **Push** `js-recon-docs` stage branch and open PR:
257
+
258
+ ```bash
259
+ git -C ../js-recon-docs add .
260
+ git -C ../js-recon-docs commit -m "docs: snapshot v<version>"
261
+ git -C ../js-recon-docs push origin stage
262
+ gh pr create --repo shriyanss/js-recon-docs \
263
+ --head stage --base main \
264
+ --title "v<version>" \
265
+ --body "<brief summary of doc changes>"
266
+ ```
267
+
268
+ 14. **Monitor docs CI** — `version_check` should pass now that the npm package is live. CodeRabbit rate-limit comments are non-blocking.
269
+
270
+ ### Handling CodeRabbit
271
+
272
+ After any PR is created, poll for review comments:
273
+
274
+ ```bash
275
+ gh api repos/shriyanss/js-recon/pulls/<pr>/comments
276
+ ```
277
+
278
+ For each suggestion: apply a fix commit to `dev` for correctness bugs or convention violations. Skip trivial style preferences. The PR updates automatically.
279
+
280
+ ### Stop before merge
281
+
282
+ Do NOT merge any PR. Once all CI checks pass and CodeRabbit suggestions are addressed, present a summary to the user: what changed in each repo, PR links, CI status, CodeRabbit disposition. Wait for explicit merge approval.
283
+
284
+ ## Security / confidentiality
285
+
286
+ When a change is informed by behavior observed on a real target (URLs, endpoint names, response shapes, finding details, etc.):
287
+
288
+ - **Do not include any target information in code comments, commit messages, docstrings, variable names, or any other artifact.**
289
+ - This applies to hostnames, paths, parameter names, response content, or any other detail that could identify the target.
290
+ - If context from the target is needed to describe a change, describe it in abstract terms only (e.g. "URL parameter passed to fetch" not "https://example.com/api/docs passes `file` param to fetch").
package/Dockerfile ADDED
@@ -0,0 +1,34 @@
1
+ FROM ghcr.io/puppeteer/puppeteer:24.43.1
2
+
3
+ WORKDIR /home/pptruser
4
+
5
+ # selectively copy the source files
6
+ COPY ./package.json .
7
+ COPY ./package-lock.json .
8
+ COPY ./tsconfig.json .
9
+ COPY ./src ./src
10
+
11
+ USER root
12
+ ENV PUPPETEER_SKIP_DOWNLOAD=true
13
+ RUN apt-get update && apt-get install -y --no-install-recommends \
14
+ unzip \
15
+ libnspr4 libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 \
16
+ libxcomposite1 libxdamage1 libxrandr2 libgbm1 libxkbcommon0 \
17
+ libasound2 libpangocairo-1.0-0 libxfixes3 libxi6 libxinerama1 \
18
+ libxcursor1 libdrm2 && \
19
+ rm -rf /var/lib/apt/lists/*
20
+ RUN npm ci
21
+ RUN npm run build
22
+
23
+ USER pptruser
24
+ RUN ./node_modules/.bin/puppeteer browsers install chrome && \
25
+ for zip in /home/pptruser/.cache/puppeteer/chrome/*-chrome-linux64.zip; do \
26
+ [ -f "$zip" ] || break; \
27
+ version="${zip%-chrome-linux64.zip}"; version="${version##*/}"; \
28
+ dest="/home/pptruser/.cache/puppeteer/chrome/linux-${version}"; \
29
+ unzip -o "$zip" -d "${dest}/" && chmod +x "${dest}/chrome-linux64/chrome"; \
30
+ done
31
+
32
+ ENV IS_DOCKER=true
33
+ ENV NODE_OPTIONS="--max-http-header-size=99999999"
34
+ ENTRYPOINT ["node", "build/index.js"]
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Shriyans Sudhi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # JS Recon
2
+
3
+ ![NPM Licence](https://img.shields.io/npm/l/%40shriyanss%2Fjs-recon) ![GitHub repo size](https://img.shields.io/github/repo-size/shriyanss/js-recon) ![NPM Downloads](https://img.shields.io/npm/dm/%40shriyanss%2Fjs-recon) ![GitHub commit activity (dev)](https://img.shields.io/github/commit-activity/w/shriyanss/js-recon/dev) ![NPM Last Update](https://img.shields.io/npm/last-update/%40shriyanss%2Fjs-recon) ![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/shriyanss/js-recon)
4
+
5
+ <p align="center">
6
+ <a href="https://js-recon.io">
7
+ <img src="https://js-recon.io/img/js-recon-logo.png" alt="JS Recon Logo" width="100">
8
+ </a>
9
+ </p>
10
+
11
+ A powerful tool for JavaScript reconnaissance. `js-recon` helps you discover, download, and analyze JavaScript files to uncover endpoints, secrets, and other valuable information from any web application running supported frameworks.
12
+
13
+ It can also reconstruct HTTP requests that the app makes to the server, and output them to the OpenAPI spec.
14
+
15
+ ## Installation
16
+
17
+ This tool requires Node.JS and `npm` to be installed. The [official download page](https://nodejs.org/en/download) can be referred. Please install **22.17.0 (LTS)** or later. Downloading older versions might break the tool.
18
+
19
+ To install the tool globally, run:
20
+
21
+ ```bash
22
+ npm i -g @shriyanss/js-recon
23
+ ```
24
+
25
+ For detailed installation and setup process, please refer to the [Installation page](https://js-recon.io/docs/docs/installation)
26
+
27
+ ## Framework Support
28
+
29
+ The features in JS Recon tool are built after thorough research on apps running different frameworks.
30
+
31
+ Please refer to the [Framework Support](https://js-recon.io/docs/docs/framework-support) page for detailed information on feature compatibility across different frameworks.
32
+
33
+ ## Quick Start
34
+
35
+ ```bash
36
+ # Get a list of all commands
37
+ js-recon --help
38
+
39
+ # Get help for a specific command
40
+ js-recon <command> --help
41
+ ```
42
+
43
+ To launch a quick assesment against a target, the `run` module can be used to automate other modules
44
+
45
+ ```bash
46
+ js-recon run -u https://app.example.com
47
+ ```
48
+
49
+ ## Commands
50
+
51
+ `js-recon` provides a suite of commands for comprehensive JavaScript analysis. For detailed usage and examples, please refer to its full documentation.
52
+
53
+ | Command | Description | Documentation |
54
+ | ------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------- |
55
+ | `lazyload` | Downloads dynamically loaded JavaScript files from a target. | [Read Docs](https://js-recon.io/docs/docs/modules/lazyload) |
56
+ | `endpoints` | Extracts API endpoints and client-side paths from JS files. | [Read Docs](https://js-recon.io/docs/docs/modules/endpoints) |
57
+ | `strings` | Extracts strings, URLs, and potential secrets from JS files. | [Read Docs](https://js-recon.io/docs/docs/modules/strings) |
58
+ | `map` | Maps function calls and analyzes code, with optional AI-powered descriptions. | [Read Docs](https://js-recon.io/docs/docs/modules/map) |
59
+ | `api-gateway` | Manages AWS API Gateway for IP rotation to bypass rate limits. | [Read Docs](https://js-recon.io/docs/docs/modules/api-gateway) |
60
+ | `run` | Runs all analysis modules automatically on a target. | [Read Docs](https://js-recon.io/docs/docs/modules/run) |
61
+ | `analyze` | Analyzes the code. | [Read Docs](https://js-recon.io/docs/docs/modules/analyze) |
62
+ | `report` | Generates a report from the analysis modules. | [Read Docs](https://js-recon.io/docs/docs/modules/report) |
63
+ | `mcp` | AI-powered interactive CLI, one-shot chat, and MCP stdio server. | [Read Docs](https://js-recon.io/docs/docs/modules/mcp) |
64
+ | `fingerprint` | Detects the JavaScript framework used by a target URL (JSON/JSONL output). | [Read Docs](https://js-recon.io/docs/docs/modules/fingerprint) |
65
+ | `refactor` | Refactors and deobfuscates webpack modules from a mapped JSON file. | [Read Docs](https://js-recon.io/docs/docs/modules/refactor) |
66
+ | `load` | Populates the response cache from a Caido or Burp Suite export. | [Read Docs](https://js-recon.io/docs/docs/modules/load) |
67
+
68
+ ## Key Features
69
+
70
+ - Downloads all dynamically loaded JS files (refered as `lazyload`) from website with supported frameworks
71
+ - Use API gateway to rotate IP addresses to bypass firewall
72
+ - Extract strings from the discovered JS files, and extract potential secrets, endpoints, etc. from them
73
+ - Endpoints modules extracts client-side paths from the app
74
+ - Map feature analyzes the JS files and outputs it to a JSON file. An interactive mode can be then used to analyze it
75
+ - Reconstruct HTTP requests that the app makes to the server, and output them to the OpenAPI spec
76
+ - Run analyze to find potential issues in JS code and the HTTP requests the app makes
77
+ - Generate a report from the analyze module
78
+
79
+ ## Example Scenario
80
+
81
+ Refer to [this page](https://js-recon.io/docs/docs/example-scenarios/next-js) where an example scenario of running this tool against a Next.JS target is demonstrated.
82
+
83
+ ## Documentation
84
+
85
+ For detailed guides, command options, and advanced usage examples, please check out the JS Recon Site at https://js-recon.io
86
+
87
+ ## Labs
88
+
89
+ <p align="center">
90
+ <img src="https://github.com/shriyanss/js-recon-labs/blob/main/static/labs-banner.png?raw=true" alt="JS Recon Labs" width="300"/>
91
+ </p>
92
+
93
+ Labs to test JS Recon tool are available [here](https://github.com/shriyanss/js-recon-labs). Walkthroughs are available [here](https://js-recon.io/labs).
94
+
95
+ ## Contributing
96
+
97
+ Please refer to the [Contributing](https://js-recon.io/contributing) page for detailed information on contributing to this project.
98
+
99
+ ## License
100
+
101
+ JS Recon is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
package/SECURITY.md ADDED
@@ -0,0 +1,37 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ The three most recent versions receive security fixes. Older versions are unsupported.
6
+
7
+ ## Reporting a Vulnerability
8
+
9
+ Please **do not** open a public GitHub issue for security vulnerabilities.
10
+
11
+ Report vulnerabilities by emailing: **shriyanss@ss0x00.com**
12
+
13
+ Include in your report:
14
+
15
+ - Description of the vulnerability and its potential impact
16
+ - Steps to reproduce or a proof-of-concept
17
+ - Affected version(s)
18
+ - Any suggested mitigations, if known
19
+
20
+ You can expect an acknowledgement within **72 hours**. If a vulnerability is confirmed, a fix will be prioritized based on severity.
21
+
22
+ ## Scope
23
+
24
+ js-recon is a security research tool. Reports are in scope if they affect:
25
+
26
+ - The js-recon CLI itself (arbitrary code execution, path traversal, unsafe deserialization, etc.)
27
+ - The Docker container image
28
+ - Dependencies with known CVEs that affect js-recon's attack surface
29
+
30
+ Out of scope:
31
+
32
+ - Vulnerabilities in targets analyzed by js-recon (that is the intended use case, not a bug)
33
+ - Issues requiring physical access or social engineering of the operator
34
+
35
+ ## Disclosure Policy
36
+
37
+ Once a fix is available, coordinated public disclosure is preferred. Please allow reasonable time (up to 90 days) for a patch to be released before public disclosure.