@js-recon/js-recon 1.3.2 → 1.4.1-alpha.10

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 (233) hide show
  1. package/.github/workflows/build-and-prettify.yaml +207 -14
  2. package/.github/workflows/pr_checker.yml +2 -2
  3. package/.github/workflows/promote-js-recon.yml +104 -0
  4. package/.github/workflows/publish-js-recon.yml +22 -80
  5. package/.github/workflows/rules-smoke-test.yaml +79 -0
  6. package/CHANGELOG.md +177 -4
  7. package/CLAUDE.md +350 -16
  8. package/Dockerfile.release +29 -0
  9. package/README.md +48 -19
  10. package/build/analyze/engine/csMastSEngine.js +129 -0
  11. package/build/analyze/engine/csMastSEngine.js.map +1 -0
  12. package/build/analyze/engine/index.js +15 -0
  13. package/build/analyze/engine/index.js.map +1 -1
  14. package/build/analyze/helpers/engineHelpers/findDirectAssignment.js +2 -1
  15. package/build/analyze/helpers/engineHelpers/findDirectAssignment.js.map +1 -1
  16. package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js +2 -1
  17. package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js.map +1 -1
  18. package/build/analyze/helpers/engineHelpers/resolveFunctionIdentifier.js +2 -1
  19. package/build/analyze/helpers/engineHelpers/resolveFunctionIdentifier.js.map +1 -1
  20. package/build/analyze/helpers/engineHelpers/taintFlow.js +11 -2
  21. package/build/analyze/helpers/engineHelpers/taintFlow.js.map +1 -1
  22. package/build/analyze/helpers/initRules.js.map +1 -1
  23. package/build/analyze/helpers/schemas.js +6 -2
  24. package/build/analyze/helpers/schemas.js.map +1 -1
  25. package/build/analyze/helpers/validate.js +3 -3
  26. package/build/analyze/helpers/validate.js.map +1 -1
  27. package/build/analyze/index.js +1 -0
  28. package/build/analyze/index.js.map +1 -1
  29. package/build/completion/index.js +432 -0
  30. package/build/completion/index.js.map +1 -0
  31. package/build/cs_mast/index.js +213 -0
  32. package/build/cs_mast/index.js.map +1 -0
  33. package/build/endpoints/next_js/client_jsFilesHref.js +2 -1
  34. package/build/endpoints/next_js/client_jsFilesHref.js.map +1 -1
  35. package/build/endpoints/next_js/client_jsonParse.js +2 -1
  36. package/build/endpoints/next_js/client_jsonParse.js.map +1 -1
  37. package/build/endpoints/next_js/client_mappedJsonFile.js +2 -1
  38. package/build/endpoints/next_js/client_mappedJsonFile.js.map +1 -1
  39. package/build/endpoints/next_js/client_subsequentRequests.js +2 -1
  40. package/build/endpoints/next_js/client_subsequentRequests.js.map +1 -1
  41. package/build/fingerprint/index.js +56 -33
  42. package/build/fingerprint/index.js.map +1 -1
  43. package/build/globalConfig.js +3 -3
  44. package/build/globalConfig.js.map +1 -1
  45. package/build/index.js +210 -10
  46. package/build/index.js.map +1 -1
  47. package/build/lazyLoad/angular/angular_getFromMainJs.js +2 -1
  48. package/build/lazyLoad/angular/angular_getFromMainJs.js.map +1 -1
  49. package/build/lazyLoad/downloadFilesUtil.js +6 -5
  50. package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
  51. package/build/lazyLoad/downloadLoadedJsUtil.js +59 -5
  52. package/build/lazyLoad/downloadLoadedJsUtil.js.map +1 -1
  53. package/build/lazyLoad/downloadQueue.js +10 -9
  54. package/build/lazyLoad/downloadQueue.js.map +1 -1
  55. package/build/lazyLoad/index.js +127 -85
  56. package/build/lazyLoad/index.js.map +1 -1
  57. package/build/lazyLoad/methodFilter.js +50 -0
  58. package/build/lazyLoad/methodFilter.js.map +1 -0
  59. package/build/lazyLoad/next_js/NextJsCrawler.js +69 -48
  60. package/build/lazyLoad/next_js/NextJsCrawler.js.map +1 -1
  61. package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js +36 -34
  62. package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js.map +1 -1
  63. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +66 -13
  64. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
  65. package/build/lazyLoad/next_js/next_parseLayoutJs.js +80 -68
  66. package/build/lazyLoad/next_js/next_parseLayoutJs.js.map +1 -1
  67. package/build/lazyLoad/next_js/next_promiseResolve.js +22 -16
  68. package/build/lazyLoad/next_js/next_promiseResolve.js.map +1 -1
  69. package/build/lazyLoad/nuxt_js/nuxt_astParse.js +49 -47
  70. package/build/lazyLoad/nuxt_js/nuxt_astParse.js.map +1 -1
  71. package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js +64 -0
  72. package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js.map +1 -0
  73. package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +3 -1
  74. package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js.map +1 -1
  75. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +3 -2
  76. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -1
  77. package/build/lazyLoad/react/react_followImports.js +16 -7
  78. package/build/lazyLoad/react/react_followImports.js.map +1 -1
  79. package/build/lazyLoad/react/react_webpackChunkPaths.js +175 -123
  80. package/build/lazyLoad/react/react_webpackChunkPaths.js.map +1 -1
  81. package/build/lazyLoad/svelte/svelte_getFromPageSource.js +16 -0
  82. package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -1
  83. package/build/lazyLoad/svelte/svelte_getVersionJson.js +40 -0
  84. package/build/lazyLoad/svelte/svelte_getVersionJson.js.map +1 -0
  85. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +3 -2
  86. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -1
  87. package/build/lazyLoad/techDetect/checkAngularJS.js +27 -6
  88. package/build/lazyLoad/techDetect/checkAngularJS.js.map +1 -1
  89. package/build/lazyLoad/techDetect/checkNextJS.js +24 -15
  90. package/build/lazyLoad/techDetect/checkNextJS.js.map +1 -1
  91. package/build/lazyLoad/techDetect/checkReact.js +8 -0
  92. package/build/lazyLoad/techDetect/checkReact.js.map +1 -1
  93. package/build/lazyLoad/techDetect/checkSvelte.js +17 -0
  94. package/build/lazyLoad/techDetect/checkSvelte.js.map +1 -1
  95. package/build/lazyLoad/techDetect/index.js +33 -5
  96. package/build/lazyLoad/techDetect/index.js.map +1 -1
  97. package/build/lazyLoad/vue/vue_RuntimeJs.js +2 -1
  98. package/build/lazyLoad/vue/vue_RuntimeJs.js.map +1 -1
  99. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +2 -1
  100. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -1
  101. package/build/lazyLoad/vue/vue_discoverJsFiles.js +59 -25
  102. package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -1
  103. package/build/lazyLoad/vue/vue_getClientSidePaths.js +2 -1
  104. package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -1
  105. package/build/lazyLoad/vue/vue_jsImports.js +2 -1
  106. package/build/lazyLoad/vue/vue_jsImports.js.map +1 -1
  107. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +2 -2
  108. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -1
  109. package/build/lazyLoad/vue/vue_viteMapDeps.js +62 -54
  110. package/build/lazyLoad/vue/vue_viteMapDeps.js.map +1 -1
  111. package/build/map/angular_js/getAngularConnections.js +88 -0
  112. package/build/map/angular_js/getAngularConnections.js.map +1 -0
  113. package/build/map/angular_js/interactive.js +4 -0
  114. package/build/map/angular_js/interactive.js.map +1 -0
  115. package/build/map/graphql/resolveGraphql.js +2 -1
  116. package/build/map/graphql/resolveGraphql.js.map +1 -1
  117. package/build/map/index.js +38 -0
  118. package/build/map/index.js.map +1 -1
  119. package/build/map/next_js/getExports.js +2 -1
  120. package/build/map/next_js/getExports.js.map +1 -1
  121. package/build/map/next_js/getFetchInstances.js +2 -1
  122. package/build/map/next_js/getFetchInstances.js.map +1 -1
  123. package/build/map/next_js/getTurbopackConnections.js +2 -1
  124. package/build/map/next_js/getTurbopackConnections.js.map +1 -1
  125. package/build/map/next_js/getWebpackConnections.js +2 -1
  126. package/build/map/next_js/getWebpackConnections.js.map +1 -1
  127. package/build/map/next_js/resolveAxios.js +2 -1
  128. package/build/map/next_js/resolveAxios.js.map +1 -1
  129. package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js +2 -1
  130. package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js.map +1 -1
  131. package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js +2 -1
  132. package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js.map +1 -1
  133. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +2 -1
  134. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -1
  135. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +2 -1
  136. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -1
  137. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +2 -1
  138. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -1
  139. package/build/map/next_js/resolveAxiosHelpers/interceptorHeaders.js +2 -1
  140. package/build/map/next_js/resolveAxiosHelpers/interceptorHeaders.js.map +1 -1
  141. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +2 -1
  142. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -1
  143. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +2 -1
  144. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -1
  145. package/build/map/next_js/resolveAxiosHelpers/traceBody.js +2 -1
  146. package/build/map/next_js/resolveAxiosHelpers/traceBody.js.map +1 -1
  147. package/build/map/next_js/resolveFetch.js +2 -1
  148. package/build/map/next_js/resolveFetch.js.map +1 -1
  149. package/build/map/next_js/resolveNewRequest.js +2 -1
  150. package/build/map/next_js/resolveNewRequest.js.map +1 -1
  151. package/build/map/next_js/resolveServerActions.js +2 -1
  152. package/build/map/next_js/resolveServerActions.js.map +1 -1
  153. package/build/map/next_js/utils.js +2 -1
  154. package/build/map/next_js/utils.js.map +1 -1
  155. package/build/map/react_js/getReactConnections.js +5 -4
  156. package/build/map/react_js/getReactConnections.js.map +1 -1
  157. package/build/map/vue_js/crossFileResolver.js +3 -2
  158. package/build/map/vue_js/crossFileResolver.js.map +1 -1
  159. package/build/map/vue_js/getViteConnections.js +5 -4
  160. package/build/map/vue_js/getViteConnections.js.map +1 -1
  161. package/build/map/vue_js/taint_utils.js +2 -1
  162. package/build/map/vue_js/taint_utils.js.map +1 -1
  163. package/build/map/vue_js/vue_resolveFetch.js +3 -2
  164. package/build/map/vue_js/vue_resolveFetch.js.map +1 -1
  165. package/build/map/vue_js/vue_resolveHttpClient.js +5 -3
  166. package/build/map/vue_js/vue_resolveHttpClient.js.map +1 -1
  167. package/build/map/vue_js/vue_resolveXhr.js +5 -3
  168. package/build/map/vue_js/vue_resolveXhr.js.map +1 -1
  169. package/build/mcp/cli.js.map +1 -1
  170. package/build/refactor/index.js +973 -27
  171. package/build/refactor/index.js.map +1 -1
  172. package/build/refactor/next/helpers.js +395 -0
  173. package/build/refactor/next/helpers.js.map +1 -0
  174. package/build/refactor/next/index.js +261 -71
  175. package/build/refactor/next/index.js.map +1 -1
  176. package/build/refactor/next/transform.js +1027 -0
  177. package/build/refactor/next/transform.js.map +1 -0
  178. package/build/refactor/next/validator.js +119 -0
  179. package/build/refactor/next/validator.js.map +1 -0
  180. package/build/refactor/react/helpers.js +106 -0
  181. package/build/refactor/react/helpers.js.map +1 -0
  182. package/build/refactor/react/index.js +290 -585
  183. package/build/refactor/react/index.js.map +1 -1
  184. package/build/refactor/react/library-classify.js +397 -0
  185. package/build/refactor/react/library-classify.js.map +1 -0
  186. package/build/refactor/react/transform.js +1852 -0
  187. package/build/refactor/react/transform.js.map +1 -0
  188. package/build/refactor/react/validator.js +123 -0
  189. package/build/refactor/react/validator.js.map +1 -0
  190. package/build/refactor/react-vite/index.js +652 -0
  191. package/build/refactor/react-vite/index.js.map +1 -0
  192. package/build/refactor/react-vite/vendor-analyze.js +336 -0
  193. package/build/refactor/react-vite/vendor-analyze.js.map +1 -0
  194. package/build/refactor/remote/cache.js +250 -0
  195. package/build/refactor/remote/cache.js.map +1 -0
  196. package/build/refactor/remote/config.js +63 -0
  197. package/build/refactor/remote/config.js.map +1 -0
  198. package/build/refactor/remote/hf-client.js +202 -0
  199. package/build/refactor/remote/hf-client.js.map +1 -0
  200. package/build/refactor/remote/version-detect.js +355 -0
  201. package/build/refactor/remote/version-detect.js.map +1 -0
  202. package/build/refactor/vue/index.js +176 -0
  203. package/build/refactor/vue/index.js.map +1 -0
  204. package/build/refactor/vue/vendor-analyze-vue.js +271 -0
  205. package/build/refactor/vue/vendor-analyze-vue.js.map +1 -0
  206. package/build/refactor/vue/vite.js +216 -0
  207. package/build/refactor/vue/vite.js.map +1 -0
  208. package/build/report/utility/genHtml.js +15 -4
  209. package/build/report/utility/genHtml.js.map +1 -1
  210. package/build/run/bundler-detect.js +154 -0
  211. package/build/run/bundler-detect.js.map +1 -0
  212. package/build/run/index.js +208 -16
  213. package/build/run/index.js.map +1 -1
  214. package/build/sourcemaps/index.js +89 -0
  215. package/build/sourcemaps/index.js.map +1 -0
  216. package/build/strings/index.js +6 -2
  217. package/build/strings/index.js.map +1 -1
  218. package/build/strings/trufflehog.js +71 -0
  219. package/build/strings/trufflehog.js.map +1 -0
  220. package/build/utility/banner.js +68 -0
  221. package/build/utility/banner.js.map +1 -0
  222. package/build/utility/getChromiumPath.js +40 -0
  223. package/build/utility/getChromiumPath.js.map +1 -0
  224. package/build/utility/globals.js +7 -0
  225. package/build/utility/globals.js.map +1 -1
  226. package/build/utility/makeReq.js +21 -11
  227. package/build/utility/makeReq.js.map +1 -1
  228. package/build/utility/postmanGenerator.js +2 -2
  229. package/build/utility/postmanGenerator.js.map +1 -1
  230. package/build/utility/puppeteerInstance.js +7 -1
  231. package/build/utility/puppeteerInstance.js.map +1 -1
  232. package/package.json +14 -8
  233. package/scripts/smoke-test.js +74 -0
@@ -12,7 +12,7 @@ jobs:
12
12
  !startsWith(github.event.head_commit.message, 'chore: prettify code')
13
13
  runs-on: ubuntu-latest
14
14
  steps:
15
- - uses: actions/checkout@v4
15
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
16
16
  - name: Check version mismatch
17
17
  env:
18
18
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -42,8 +42,8 @@ jobs:
42
42
  runs-on: ubuntu-latest
43
43
  needs: version_check
44
44
  steps:
45
- - uses: actions/checkout@v4
46
- - uses: actions/setup-node@v4
45
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
46
+ - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
47
47
  with:
48
48
  node-version: "22"
49
49
  cache: "npm"
@@ -55,16 +55,23 @@ jobs:
55
55
  prettier:
56
56
  runs-on: ubuntu-latest
57
57
  needs: audit
58
+ environment: commit-signing
58
59
  steps:
59
60
  - name: Checkout
60
- uses: actions/checkout@v4
61
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
61
62
  with:
62
63
  # Make sure the action checks out the repository to the pull request branch
63
64
  ref: ${{ github.ref_name }}
64
- ssh-key: ${{ secrets.DEPLOY_KEY }}
65
+
66
+ - name: Configure SSH commit signing
67
+ uses: shriyanss/verified-commit-action@v1
68
+ with:
69
+ ssh-private-key: ${{ secrets.JS_RECON_SIGNING_KEY }}
70
+ commit-name: "js-recon-bot"
71
+ commit-email: ${{ secrets.JS_RECON_SIGNING_EMAIL }}
65
72
 
66
73
  - name: Set up Node.js
67
- uses: actions/setup-node@v4
74
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
68
75
  with:
69
76
  node-version: "22"
70
77
  cache: "npm"
@@ -77,30 +84,49 @@ jobs:
77
84
 
78
85
  - name: Run Prettier
79
86
  run: prettier --write . --config .prettierrc
80
-
87
+
81
88
  - name: Remove node_modules
82
89
  run: rm -rf node_modules
83
90
 
84
91
  - name: Commit and push changes
85
92
  run: |
86
- git config user.name "github-actions[bot]"
87
- git config user.email "github-actions[bot]@users.noreply.github.com"
88
93
  git add .
89
94
  git commit -m "chore: prettify code" || echo "No changes to commit"
90
95
  git push
91
96
 
92
- build:
97
+ test:
93
98
  needs: prettier
94
99
  runs-on: ubuntu-latest
95
100
  steps:
96
101
  - name: Checkout
97
- uses: actions/checkout@v4
102
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
103
+ with:
104
+ ref: ${{ github.ref_name }}
105
+
106
+ - name: Set up Node.js
107
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
108
+ with:
109
+ node-version: "22"
110
+ cache: "npm"
111
+
112
+ - name: Install dependencies
113
+ run: npm ci
114
+
115
+ - name: Run unit tests
116
+ run: npm test
117
+
118
+ build:
119
+ needs: test
120
+ runs-on: ubuntu-latest
121
+ steps:
122
+ - name: Checkout
123
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
98
124
  with:
99
125
  # Make sure the action checks out the repository to the pull request branch
100
126
  ref: ${{ github.ref_name }}
101
127
 
102
128
  - name: Set up Node.js
103
- uses: actions/setup-node@v4
129
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
104
130
  with:
105
131
  node-version: "22"
106
132
  cache: "npm"
@@ -110,12 +136,179 @@ jobs:
110
136
  run: npm run build
111
137
  build-docker:
112
138
  needs: build
139
+ permissions:
140
+ contents: read
113
141
  runs-on: ubuntu-latest
114
142
  steps:
115
143
  - name: Checkout
116
- uses: actions/checkout@v4
144
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
117
145
  with:
118
146
  # Make sure the action checks out the repository to the pull request branch
119
147
  ref: ${{ github.ref_name }}
120
148
  - name: Build docker container
121
- run: docker build -t shriyanss/js-recon .
149
+ run: docker build -t js-recon/js-recon .
150
+
151
+ integration-test-docker:
152
+ needs: build-docker
153
+ runs-on: ubuntu-latest
154
+ timeout-minutes: 30
155
+ steps:
156
+ - name: Checkout js-recon
157
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
158
+ with:
159
+ ref: ${{ github.ref_name }}
160
+
161
+ - name: Checkout js-recon-labs
162
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
163
+ with:
164
+ repository: js-recon/js-recon-labs
165
+ path: js-recon-labs
166
+
167
+ - name: Checkout js-recon-rules
168
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
169
+ with:
170
+ repository: js-recon/js-recon-rules
171
+ path: js-recon-rules
172
+
173
+ - name: Set up Node.js
174
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
175
+ with:
176
+ node-version: "22"
177
+ cache: "npm"
178
+
179
+ - name: Build js-recon Docker image
180
+ run: docker build -t js-recon/js-recon .
181
+
182
+ - name: Install vuln-all-rules app dependencies
183
+ working-directory: js-recon-labs/next_js/vuln-all-rules
184
+ run: npm ci
185
+
186
+ - name: Build vuln-all-rules app
187
+ working-directory: js-recon-labs/next_js/vuln-all-rules
188
+ run: npm run build
189
+
190
+ - name: Start vuln-all-rules app
191
+ working-directory: js-recon-labs/next_js/vuln-all-rules
192
+ run: npm start &
193
+
194
+ - name: Wait for lab app to be ready
195
+ run: |
196
+ echo "Waiting for lab app on port 3001..."
197
+ n=0
198
+ until curl -sf http://localhost:3001 > /dev/null; do
199
+ n=$((n+1))
200
+ [ $n -ge 30 ] && echo "Timed out waiting for lab app" && exit 1
201
+ sleep 2
202
+ done
203
+ echo "Lab app is ready."
204
+
205
+ - name: Run js-recon via Docker against lab app
206
+ run: |
207
+ docker run --name js-recon-run \
208
+ --network host \
209
+ -v "$(pwd)/js-recon-rules:/home/pptruser/js-recon-rules" \
210
+ --entrypoint /bin/bash \
211
+ js-recon/js-recon \
212
+ -c 'mkdir -p ~/.js-recon && ln -sf /home/pptruser/js-recon-rules ~/.js-recon/rules && printf "http://localhost:3001\n" > /tmp/urls.txt && node build/index.js run -u /tmp/urls.txt -r ./js-recon-rules --no-sandbox -y -k'
213
+ mkdir -p output
214
+ docker cp js-recon-run:/home/pptruser/output/. ./output/ 2>/dev/null || true
215
+ docker rm js-recon-run
216
+
217
+ - name: Verify all rules fired
218
+ run: node scripts/smoke-test.js
219
+
220
+ - name: Upload analyze.json on failure
221
+ if: failure()
222
+ uses: actions/upload-artifact@v4
223
+ with:
224
+ name: analyze-json-docker
225
+ path: output/localhost_3001/analyze.json
226
+ if-no-files-found: ignore
227
+
228
+ integration-test-macos:
229
+ needs: build
230
+ runs-on: macos-latest
231
+ timeout-minutes: 30
232
+ steps:
233
+ - name: Checkout js-recon
234
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
235
+ with:
236
+ ref: ${{ github.ref_name }}
237
+
238
+ - name: Checkout js-recon-labs
239
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
240
+ with:
241
+ repository: js-recon/js-recon-labs
242
+ path: js-recon-labs
243
+
244
+ - name: Checkout js-recon-rules
245
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
246
+ with:
247
+ repository: js-recon/js-recon-rules
248
+ path: js-recon-rules
249
+
250
+ - name: Set up Node.js
251
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
252
+ with:
253
+ node-version: "22"
254
+ cache: "npm"
255
+
256
+ - name: Install Chrome
257
+ run: brew install --cask google-chrome
258
+
259
+ - name: Install js-recon dependencies
260
+ run: npm ci
261
+ env:
262
+ PUPPETEER_SKIP_DOWNLOAD: "true"
263
+
264
+ - name: Build js-recon
265
+ run: npm run build
266
+
267
+ - name: Install vuln-all-rules app dependencies
268
+ working-directory: js-recon-labs/next_js/vuln-all-rules
269
+ run: npm ci
270
+
271
+ - name: Build vuln-all-rules app
272
+ working-directory: js-recon-labs/next_js/vuln-all-rules
273
+ run: npm run build
274
+
275
+ - name: Start vuln-all-rules app
276
+ working-directory: js-recon-labs/next_js/vuln-all-rules
277
+ run: npm start &
278
+
279
+ - name: Wait for lab app to be ready
280
+ run: |
281
+ echo "Waiting for lab app on port 3001..."
282
+ n=0
283
+ until curl -sf http://localhost:3001 > /dev/null; do
284
+ n=$((n+1))
285
+ [ $n -ge 30 ] && echo "Timed out waiting for lab app" && exit 1
286
+ sleep 2
287
+ done
288
+ echo "Lab app is ready."
289
+
290
+ - name: Pre-populate js-recon rules cache
291
+ run: |
292
+ mkdir -p ~/.js-recon
293
+ ln -sf "$GITHUB_WORKSPACE/js-recon-rules" ~/.js-recon/rules
294
+
295
+ - name: Run js-recon natively against lab app
296
+ run: |
297
+ echo "http://localhost:3001" > /tmp/smoke-urls.txt
298
+ node --max-old-space-size=4096 build/index.js run \
299
+ -u /tmp/smoke-urls.txt \
300
+ -r ./js-recon-rules \
301
+ -y -k
302
+ env:
303
+ PUPPETEER_EXECUTABLE_PATH: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
304
+
305
+ - name: Verify all rules fired
306
+ run: node scripts/smoke-test.js
307
+
308
+ - name: Upload analyze.json on failure
309
+ if: failure()
310
+ uses: actions/upload-artifact@v4
311
+ with:
312
+ name: analyze-json-macos
313
+ path: output/localhost_3001/analyze.json
314
+ if-no-files-found: ignore
@@ -13,10 +13,10 @@ jobs:
13
13
  steps:
14
14
  - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
15
15
  - name: Redirect PR to dev
16
- if: github.head_ref != 'dev' || github.event.pull_request.head.repo.full_name != 'shriyanss/js-recon'
16
+ if: github.head_ref != 'dev' || github.event.pull_request.head.repo.full_name != 'js-recon/js-recon'
17
17
  env:
18
18
  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19
19
  PR_NUMBER: ${{ github.event.pull_request.number }}
20
20
  run: |
21
21
  gh pr edit $PR_NUMBER --base dev
22
- gh pr comment $PR_NUMBER --body "This PR was targeting \`main\`, but only the \`dev\` branch of \`shriyanss/js-recon\` can merge directly into \`main\`. The target branch has been changed to \`dev\`."
22
+ gh pr comment $PR_NUMBER --body "This PR was targeting \`main\`, but only the \`dev\` branch of \`js-recon/js-recon\` can merge directly into \`main\`. The target branch has been changed to \`dev\`."
@@ -0,0 +1,104 @@
1
+ # Manually-triggered second phase of a release, run after a staged npm publish
2
+ # (see publish-js-recon.yml) has been approved by a human with 2FA on npmjs.com.
3
+ # Installs js-recon from the published npm registry artifact rather than
4
+ # building from git source, so the Homebrew/Docker/GHCR outputs are provably
5
+ # the same bits that were reviewed and approved on npm.
6
+
7
+ name: Promote JS Recon Release
8
+
9
+ on:
10
+ workflow_dispatch:
11
+ inputs:
12
+ version:
13
+ description: "Published npm version to promote (e.g. 1.4.1-alpha.6, no leading v)"
14
+ required: true
15
+ type: string
16
+
17
+ jobs:
18
+ update-homebrew-tap:
19
+ runs-on: ubuntu-latest
20
+ environment: homebrew-publish
21
+ steps:
22
+ - name: Fetch published tarball and compute SHA256
23
+ id: sha256
24
+ run: |
25
+ npm pack "@js-recon/js-recon@${VERSION}"
26
+ SHA=$(sha256sum "js-recon-js-recon-${VERSION}.tgz" | awk '{print $1}')
27
+ echo "sha256=${SHA}" >> "$GITHUB_OUTPUT"
28
+ env:
29
+ VERSION: ${{ inputs.version }}
30
+
31
+ - name: Determine target formula
32
+ id: formula
33
+ run: |
34
+ if [[ "$VERSION" == *"alpha"* ]]; then
35
+ FORMULA="Formula/js-recon-alpha.rb"
36
+ elif [[ "$VERSION" == *"beta"* ]]; then
37
+ FORMULA="Formula/js-recon-beta.rb"
38
+ else
39
+ FORMULA="Formula/js-recon.rb"
40
+ fi
41
+ echo "formula=${FORMULA}" >> "$GITHUB_OUTPUT"
42
+ env:
43
+ VERSION: ${{ inputs.version }}
44
+
45
+ - name: Check out homebrew-tap
46
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
47
+ with:
48
+ repository: js-recon/homebrew-tap
49
+ token: ${{ secrets.HOMEBREW_TAP_GH_PAT }}
50
+ path: homebrew-tap
51
+
52
+ - name: Update formula fields
53
+ working-directory: homebrew-tap
54
+ run: |
55
+ sed -i "s|^ url \"https://registry\.npmjs\.org/@js-recon/js-recon/-/js-recon-[^\"]*\"| url \"https://registry.npmjs.org/@js-recon/js-recon/-/js-recon-${VERSION}.tgz\"|" "${FORMULA}"
56
+ sed -i "s|^ sha256 \"[a-f0-9]*\"| sha256 \"${SHA}\"|" "${FORMULA}"
57
+ env:
58
+ VERSION: ${{ inputs.version }}
59
+ SHA: ${{ steps.sha256.outputs.sha256 }}
60
+ FORMULA: ${{ steps.formula.outputs.formula }}
61
+
62
+ - name: Commit and push
63
+ working-directory: homebrew-tap
64
+ run: |
65
+ git config user.name "github-actions[bot]"
66
+ git config user.email "github-actions[bot]@users.noreply.github.com"
67
+ git add "${FORMULA}"
68
+ git commit -m "chore: update ${FORMULA} to ${VERSION}"
69
+ git push
70
+ env:
71
+ VERSION: ${{ inputs.version }}
72
+ FORMULA: ${{ steps.formula.outputs.formula }}
73
+
74
+ publish-ghcr:
75
+ runs-on: ubuntu-latest
76
+ permissions:
77
+ contents: read
78
+ packages: write
79
+ steps:
80
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
81
+ - uses: docker/login-action@v3
82
+ with:
83
+ registry: ghcr.io
84
+ username: ${{ github.actor }}
85
+ password: ${{ secrets.GITHUB_TOKEN }}
86
+ - name: Build and push to github container registry
87
+ run: |
88
+ # build the image from the published npm artifact
89
+ docker build -f Dockerfile.release --build-arg JS_RECON_VERSION=$VERSION -t ghcr.io/js-recon/js-recon:$VERSION .
90
+
91
+ # check if it is alpha or beta. default to latest
92
+ TAG="latest"
93
+ [[ "$VERSION" == *"beta"* ]] && TAG="beta"
94
+ [[ "$VERSION" == *"alpha"* ]] && TAG="alpha"
95
+
96
+ # tag again with whatever has been set
97
+ docker tag ghcr.io/js-recon/js-recon:$VERSION ghcr.io/js-recon/js-recon:$TAG
98
+
99
+ # push images with both tags
100
+ docker push ghcr.io/js-recon/js-recon:$VERSION
101
+ docker push ghcr.io/js-recon/js-recon:$TAG
102
+
103
+ env:
104
+ VERSION: ${{ inputs.version }}
@@ -11,7 +11,7 @@ jobs:
11
11
  version_check:
12
12
  runs-on: ubuntu-latest
13
13
  steps:
14
- - uses: actions/checkout@v4
14
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
15
15
  - name: Check version mismatch
16
16
  run: |
17
17
  echo "[i] Checking if the version in the CHANGELOG.md, package.json, and Github release version matches"
@@ -39,8 +39,8 @@ jobs:
39
39
  needs: version_check
40
40
  runs-on: ubuntu-latest
41
41
  steps:
42
- - uses: actions/checkout@v4
43
- - uses: actions/setup-node@v4
42
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
43
+ - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
44
44
  with:
45
45
  node-version: 22
46
46
  - run: npm ci
@@ -51,8 +51,8 @@ jobs:
51
51
  needs: audit
52
52
  runs-on: ubuntu-latest
53
53
  steps:
54
- - uses: actions/checkout@v4
55
- - uses: actions/setup-node@v4
54
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
55
+ - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
56
56
  with:
57
57
  node-version: 22
58
58
  - run: npm ci
@@ -63,103 +63,45 @@ jobs:
63
63
  publish-npm:
64
64
  needs: build
65
65
  runs-on: ubuntu-latest
66
+ permissions:
67
+ id-token: write
68
+ contents: read
66
69
  steps:
67
- - uses: actions/checkout@v4
68
- - uses: actions/setup-node@v4
70
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
71
+ - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
69
72
  with:
70
73
  node-version: 22
71
74
  registry-url: https://registry.npmjs.org/
72
75
  - run: npm ci
73
76
  - run: npm run build
74
- - name: Publish to npm
77
+ - name: Ensure npm CLI supports OIDC trusted publishing
78
+ run: npm install -g npm@latest
79
+ - name: Stage release to npm via OIDC
75
80
  run: |
76
81
  TAG="latest"
77
82
  [[ "$VERSION" == *"beta"* ]] && TAG="beta"
78
83
  [[ "$VERSION" == *"alpha"* ]] && TAG="alpha"
79
- npm publish --tag $TAG
80
- env:
81
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}
82
- VERSION: ${{ github.event.release.tag_name }}
83
-
84
-
85
- publish-docker:
86
- needs: build
87
- runs-on: ubuntu-latest
88
- steps:
89
- - uses: actions/checkout@v4
90
- - name: Build and push to dockerhub
91
- run: |
92
- # login to docker
93
- echo $DOCKER_SECRET | docker login -u shriyanss --password-stdin
94
-
95
- # build the image
96
- docker build -t shriyanss/js-recon:$VERSION .
97
-
98
- # check if it is alpha or beta. default to latest
99
- TAG="latest"
100
- [[ "$VERSION" == *"beta"* ]] && TAG="beta"
101
- [[ "$VERSION" == *"alpha"* ]] && TAG="alpha"
102
-
103
- # tag again with whatever has been set
104
- docker tag shriyanss/js-recon:$VERSION shriyanss/js-recon:$TAG
105
-
106
- # push images with both tags
107
- docker push shriyanss/js-recon:$VERSION
108
- docker push shriyanss/js-recon:$TAG
109
-
84
+ npm stage publish --tag $TAG
110
85
  env:
111
- DOCKER_SECRET: ${{ secrets.DOCKER_SECRET }}
112
86
  VERSION: ${{ github.event.release.tag_name }}
113
87
 
114
-
115
- publish-ghcr:
116
- needs: build
117
- runs-on: ubuntu-latest
118
- permissions:
119
- contents: read
120
- packages: write
121
- steps:
122
- - uses: actions/checkout@v4
123
- - uses: docker/login-action@v3
124
- with:
125
- registry: ghcr.io
126
- username: ${{ github.actor }}
127
- password: ${{ secrets.GITHUB_TOKEN }}
128
- - name: Build and push to github container registry
129
- run: |
130
- # build the image
131
- docker build -t ghcr.io/shriyanss/js-recon:$VERSION .
132
-
133
- # check if it is alpha or beta. default to latest
134
- TAG="latest"
135
- [[ "$VERSION" == *"beta"* ]] && TAG="beta"
136
- [[ "$VERSION" == *"alpha"* ]] && TAG="alpha"
137
-
138
- # tag again with whatever has been set
139
- docker tag ghcr.io/shriyanss/js-recon:$VERSION ghcr.io/shriyanss/js-recon:$TAG
140
-
141
- # push images with both tags
142
- docker push ghcr.io/shriyanss/js-recon:$VERSION
143
- docker push ghcr.io/shriyanss/js-recon:$TAG
144
-
145
- env:
146
- VERSION: ${{ github.event.release.tag_name }}
147
-
148
88
  merge_main_and_dev:
149
89
  needs:
150
90
  - publish-npm
151
- - publish-docker
152
- - publish-ghcr
153
91
  runs-on: ubuntu-latest
92
+ environment: commit-signing
154
93
  steps:
155
- - uses: actions/checkout@v4
94
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
156
95
  with:
157
- ssh-key: ${{ secrets.DEPLOY_KEY }}
158
96
  fetch-depth: 0
97
+ - name: Configure SSH commit signing
98
+ uses: shriyanss/verified-commit-action@v1
99
+ with:
100
+ ssh-private-key: ${{ secrets.JS_RECON_SIGNING_KEY }}
101
+ commit-name: "js-recon-bot"
102
+ commit-email: ${{ secrets.JS_RECON_SIGNING_EMAIL }}
159
103
  - name: Merge main and dev
160
104
  run: |
161
- git config --global user.name 'github-actions[bot]'
162
- git config --global user.email 'github-actions[bot]@users.noreply.github.com'
163
105
  git fetch origin main:main
164
106
  git fetch origin dev:dev
165
107
  git checkout dev
@@ -0,0 +1,79 @@
1
+ name: Rules Smoke Test
2
+
3
+ on:
4
+ push:
5
+ branches-ignore:
6
+ - main
7
+
8
+ jobs:
9
+ rules-smoke-test:
10
+ runs-on: ubuntu-latest
11
+ timeout-minutes: 30
12
+
13
+ steps:
14
+ - name: Checkout js-recon
15
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
16
+
17
+ - name: Checkout js-recon-labs
18
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
19
+ with:
20
+ repository: js-recon/js-recon-labs
21
+ path: js-recon-labs
22
+
23
+ - name: Checkout js-recon-rules
24
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
25
+ with:
26
+ repository: js-recon/js-recon-rules
27
+ path: js-recon-rules
28
+
29
+ - name: Set up Node.js
30
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
31
+ with:
32
+ node-version: "22"
33
+ cache: "npm"
34
+
35
+ - name: Install js-recon dependencies
36
+ run: npm ci
37
+
38
+ - name: Build js-recon
39
+ run: npm run build
40
+
41
+ - name: Install vulnerable app dependencies
42
+ working-directory: js-recon-labs/next_js/vuln-all-rules
43
+ run: npm ci
44
+
45
+ - name: Build vulnerable app
46
+ working-directory: js-recon-labs/next_js/vuln-all-rules
47
+ run: npm run build
48
+
49
+ - name: Start vulnerable app
50
+ working-directory: js-recon-labs/next_js/vuln-all-rules
51
+ run: npm start &
52
+
53
+ - name: Wait for app to be ready
54
+ run: |
55
+ echo "Waiting for app on port 3001..."
56
+ timeout 60 bash -c 'until curl -sf http://localhost:3001 > /dev/null; do sleep 2; done'
57
+ echo "App is ready."
58
+
59
+ - name: Run js-recon against vulnerable app
60
+ run: |
61
+ echo "http://localhost:3001" > /tmp/smoke-urls.txt
62
+ node --max-old-space-size=4096 build/index.js run \
63
+ -u /tmp/smoke-urls.txt \
64
+ -r ./js-recon-rules \
65
+ --no-sandbox \
66
+ -y -k
67
+ env:
68
+ PUPPETEER_EXECUTABLE_PATH: /usr/bin/google-chrome-stable
69
+
70
+ - name: Verify all rules fired
71
+ run: node scripts/smoke-test.js
72
+
73
+ - name: Upload analyze.json on failure
74
+ if: failure()
75
+ uses: actions/upload-artifact@v4
76
+ with:
77
+ name: analyze-json
78
+ path: output/localhost_3001/analyze.json
79
+ if-no-files-found: ignore