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

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 (236) hide show
  1. package/.claude/settings.local.json +10 -0
  2. package/.github/workflows/build-and-prettify.yaml +205 -14
  3. package/.github/workflows/pr_checker.yml +2 -2
  4. package/.github/workflows/promote-js-recon.yml +104 -0
  5. package/.github/workflows/publish-js-recon.yml +22 -80
  6. package/.github/workflows/rules-smoke-test.yaml +79 -0
  7. package/CHANGELOG.md +171 -4
  8. package/CLAUDE.md +350 -16
  9. package/Dockerfile.release +29 -0
  10. package/README.md +48 -19
  11. package/build/analyze/engine/csMastSEngine.js +129 -0
  12. package/build/analyze/engine/csMastSEngine.js.map +1 -0
  13. package/build/analyze/engine/index.js +15 -0
  14. package/build/analyze/engine/index.js.map +1 -1
  15. package/build/analyze/helpers/engineHelpers/findDirectAssignment.js +2 -1
  16. package/build/analyze/helpers/engineHelpers/findDirectAssignment.js.map +1 -1
  17. package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js +2 -1
  18. package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js.map +1 -1
  19. package/build/analyze/helpers/engineHelpers/resolveFunctionIdentifier.js +2 -1
  20. package/build/analyze/helpers/engineHelpers/resolveFunctionIdentifier.js.map +1 -1
  21. package/build/analyze/helpers/engineHelpers/taintFlow.js +11 -2
  22. package/build/analyze/helpers/engineHelpers/taintFlow.js.map +1 -1
  23. package/build/analyze/helpers/initRules.js +1 -1
  24. package/build/analyze/helpers/initRules.js.map +1 -1
  25. package/build/analyze/helpers/schemas.js +6 -2
  26. package/build/analyze/helpers/schemas.js.map +1 -1
  27. package/build/analyze/helpers/validate.js +3 -3
  28. package/build/analyze/helpers/validate.js.map +1 -1
  29. package/build/analyze/index.js +1 -0
  30. package/build/analyze/index.js.map +1 -1
  31. package/build/completion/index.js +432 -0
  32. package/build/completion/index.js.map +1 -0
  33. package/build/cs_mast/index.js +213 -0
  34. package/build/cs_mast/index.js.map +1 -0
  35. package/build/endpoints/next_js/client_jsFilesHref.js +2 -1
  36. package/build/endpoints/next_js/client_jsFilesHref.js.map +1 -1
  37. package/build/endpoints/next_js/client_jsonParse.js +2 -1
  38. package/build/endpoints/next_js/client_jsonParse.js.map +1 -1
  39. package/build/endpoints/next_js/client_mappedJsonFile.js +2 -1
  40. package/build/endpoints/next_js/client_mappedJsonFile.js.map +1 -1
  41. package/build/endpoints/next_js/client_subsequentRequests.js +2 -1
  42. package/build/endpoints/next_js/client_subsequentRequests.js.map +1 -1
  43. package/build/fingerprint/index.js +56 -33
  44. package/build/fingerprint/index.js.map +1 -1
  45. package/build/globalConfig.js +3 -3
  46. package/build/globalConfig.js.map +1 -1
  47. package/build/index.js +210 -10
  48. package/build/index.js.map +1 -1
  49. package/build/lazyLoad/angular/angular_getFromMainJs.js +2 -1
  50. package/build/lazyLoad/angular/angular_getFromMainJs.js.map +1 -1
  51. package/build/lazyLoad/downloadFilesUtil.js +6 -5
  52. package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
  53. package/build/lazyLoad/downloadLoadedJsUtil.js +59 -5
  54. package/build/lazyLoad/downloadLoadedJsUtil.js.map +1 -1
  55. package/build/lazyLoad/downloadQueue.js +10 -9
  56. package/build/lazyLoad/downloadQueue.js.map +1 -1
  57. package/build/lazyLoad/index.js +127 -85
  58. package/build/lazyLoad/index.js.map +1 -1
  59. package/build/lazyLoad/methodFilter.js +50 -0
  60. package/build/lazyLoad/methodFilter.js.map +1 -0
  61. package/build/lazyLoad/next_js/NextJsCrawler.js +69 -48
  62. package/build/lazyLoad/next_js/NextJsCrawler.js.map +1 -1
  63. package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js +36 -34
  64. package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js.map +1 -1
  65. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +66 -13
  66. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
  67. package/build/lazyLoad/next_js/next_parseLayoutJs.js +80 -68
  68. package/build/lazyLoad/next_js/next_parseLayoutJs.js.map +1 -1
  69. package/build/lazyLoad/next_js/next_promiseResolve.js +22 -16
  70. package/build/lazyLoad/next_js/next_promiseResolve.js.map +1 -1
  71. package/build/lazyLoad/nuxt_js/nuxt_astParse.js +49 -47
  72. package/build/lazyLoad/nuxt_js/nuxt_astParse.js.map +1 -1
  73. package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js +64 -0
  74. package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js.map +1 -0
  75. package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +3 -1
  76. package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js.map +1 -1
  77. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +3 -2
  78. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -1
  79. package/build/lazyLoad/react/react_followImports.js +16 -7
  80. package/build/lazyLoad/react/react_followImports.js.map +1 -1
  81. package/build/lazyLoad/react/react_webpackChunkPaths.js +175 -123
  82. package/build/lazyLoad/react/react_webpackChunkPaths.js.map +1 -1
  83. package/build/lazyLoad/svelte/svelte_getFromPageSource.js +16 -0
  84. package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -1
  85. package/build/lazyLoad/svelte/svelte_getVersionJson.js +40 -0
  86. package/build/lazyLoad/svelte/svelte_getVersionJson.js.map +1 -0
  87. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +3 -2
  88. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -1
  89. package/build/lazyLoad/techDetect/checkAngularJS.js +27 -6
  90. package/build/lazyLoad/techDetect/checkAngularJS.js.map +1 -1
  91. package/build/lazyLoad/techDetect/checkNextJS.js +24 -15
  92. package/build/lazyLoad/techDetect/checkNextJS.js.map +1 -1
  93. package/build/lazyLoad/techDetect/checkReact.js +8 -0
  94. package/build/lazyLoad/techDetect/checkReact.js.map +1 -1
  95. package/build/lazyLoad/techDetect/checkSvelte.js +17 -0
  96. package/build/lazyLoad/techDetect/checkSvelte.js.map +1 -1
  97. package/build/lazyLoad/techDetect/index.js +33 -5
  98. package/build/lazyLoad/techDetect/index.js.map +1 -1
  99. package/build/lazyLoad/vue/vue_RuntimeJs.js +2 -1
  100. package/build/lazyLoad/vue/vue_RuntimeJs.js.map +1 -1
  101. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +2 -1
  102. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -1
  103. package/build/lazyLoad/vue/vue_discoverJsFiles.js +59 -25
  104. package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -1
  105. package/build/lazyLoad/vue/vue_getClientSidePaths.js +2 -1
  106. package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -1
  107. package/build/lazyLoad/vue/vue_jsImports.js +2 -1
  108. package/build/lazyLoad/vue/vue_jsImports.js.map +1 -1
  109. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +2 -2
  110. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -1
  111. package/build/lazyLoad/vue/vue_viteMapDeps.js +62 -54
  112. package/build/lazyLoad/vue/vue_viteMapDeps.js.map +1 -1
  113. package/build/map/angular_js/getAngularConnections.js +88 -0
  114. package/build/map/angular_js/getAngularConnections.js.map +1 -0
  115. package/build/map/angular_js/interactive.js +4 -0
  116. package/build/map/angular_js/interactive.js.map +1 -0
  117. package/build/map/graphql/resolveGraphql.js +2 -1
  118. package/build/map/graphql/resolveGraphql.js.map +1 -1
  119. package/build/map/index.js +38 -0
  120. package/build/map/index.js.map +1 -1
  121. package/build/map/next_js/getExports.js +2 -1
  122. package/build/map/next_js/getExports.js.map +1 -1
  123. package/build/map/next_js/getFetchInstances.js +2 -1
  124. package/build/map/next_js/getFetchInstances.js.map +1 -1
  125. package/build/map/next_js/getTurbopackConnections.js +2 -1
  126. package/build/map/next_js/getTurbopackConnections.js.map +1 -1
  127. package/build/map/next_js/getWebpackConnections.js +2 -1
  128. package/build/map/next_js/getWebpackConnections.js.map +1 -1
  129. package/build/map/next_js/resolveAxios.js +2 -1
  130. package/build/map/next_js/resolveAxios.js.map +1 -1
  131. package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js +2 -1
  132. package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js.map +1 -1
  133. package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js +2 -1
  134. package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js.map +1 -1
  135. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +2 -1
  136. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -1
  137. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +2 -1
  138. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -1
  139. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +2 -1
  140. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -1
  141. package/build/map/next_js/resolveAxiosHelpers/interceptorHeaders.js +2 -1
  142. package/build/map/next_js/resolveAxiosHelpers/interceptorHeaders.js.map +1 -1
  143. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +2 -1
  144. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -1
  145. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +2 -1
  146. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -1
  147. package/build/map/next_js/resolveAxiosHelpers/traceBody.js +2 -1
  148. package/build/map/next_js/resolveAxiosHelpers/traceBody.js.map +1 -1
  149. package/build/map/next_js/resolveFetch.js +2 -1
  150. package/build/map/next_js/resolveFetch.js.map +1 -1
  151. package/build/map/next_js/resolveNewRequest.js +2 -1
  152. package/build/map/next_js/resolveNewRequest.js.map +1 -1
  153. package/build/map/next_js/resolveServerActions.js +2 -1
  154. package/build/map/next_js/resolveServerActions.js.map +1 -1
  155. package/build/map/next_js/utils.js +2 -1
  156. package/build/map/next_js/utils.js.map +1 -1
  157. package/build/map/react_js/getReactConnections.js +5 -4
  158. package/build/map/react_js/getReactConnections.js.map +1 -1
  159. package/build/map/vue_js/crossFileResolver.js +3 -2
  160. package/build/map/vue_js/crossFileResolver.js.map +1 -1
  161. package/build/map/vue_js/getViteConnections.js +5 -4
  162. package/build/map/vue_js/getViteConnections.js.map +1 -1
  163. package/build/map/vue_js/taint_utils.js +2 -1
  164. package/build/map/vue_js/taint_utils.js.map +1 -1
  165. package/build/map/vue_js/vue_resolveFetch.js +3 -2
  166. package/build/map/vue_js/vue_resolveFetch.js.map +1 -1
  167. package/build/map/vue_js/vue_resolveHttpClient.js +5 -3
  168. package/build/map/vue_js/vue_resolveHttpClient.js.map +1 -1
  169. package/build/map/vue_js/vue_resolveXhr.js +5 -3
  170. package/build/map/vue_js/vue_resolveXhr.js.map +1 -1
  171. package/build/mcp/cli.js.map +1 -1
  172. package/build/refactor/index.js +973 -27
  173. package/build/refactor/index.js.map +1 -1
  174. package/build/refactor/next/helpers.js +395 -0
  175. package/build/refactor/next/helpers.js.map +1 -0
  176. package/build/refactor/next/index.js +261 -71
  177. package/build/refactor/next/index.js.map +1 -1
  178. package/build/refactor/next/transform.js +1027 -0
  179. package/build/refactor/next/transform.js.map +1 -0
  180. package/build/refactor/next/validator.js +119 -0
  181. package/build/refactor/next/validator.js.map +1 -0
  182. package/build/refactor/react/helpers.js +106 -0
  183. package/build/refactor/react/helpers.js.map +1 -0
  184. package/build/refactor/react/index.js +290 -585
  185. package/build/refactor/react/index.js.map +1 -1
  186. package/build/refactor/react/library-classify.js +397 -0
  187. package/build/refactor/react/library-classify.js.map +1 -0
  188. package/build/refactor/react/transform.js +1852 -0
  189. package/build/refactor/react/transform.js.map +1 -0
  190. package/build/refactor/react/validator.js +123 -0
  191. package/build/refactor/react/validator.js.map +1 -0
  192. package/build/refactor/react-vite/index.js +652 -0
  193. package/build/refactor/react-vite/index.js.map +1 -0
  194. package/build/refactor/react-vite/vendor-analyze.js +336 -0
  195. package/build/refactor/react-vite/vendor-analyze.js.map +1 -0
  196. package/build/refactor/remote/cache.js +250 -0
  197. package/build/refactor/remote/cache.js.map +1 -0
  198. package/build/refactor/remote/config.js +63 -0
  199. package/build/refactor/remote/config.js.map +1 -0
  200. package/build/refactor/remote/hf-client.js +202 -0
  201. package/build/refactor/remote/hf-client.js.map +1 -0
  202. package/build/refactor/remote/version-detect.js +355 -0
  203. package/build/refactor/remote/version-detect.js.map +1 -0
  204. package/build/refactor/vue/index.js +176 -0
  205. package/build/refactor/vue/index.js.map +1 -0
  206. package/build/refactor/vue/vendor-analyze-vue.js +271 -0
  207. package/build/refactor/vue/vendor-analyze-vue.js.map +1 -0
  208. package/build/refactor/vue/vite.js +216 -0
  209. package/build/refactor/vue/vite.js.map +1 -0
  210. package/build/report/utility/genHtml.js +15 -4
  211. package/build/report/utility/genHtml.js.map +1 -1
  212. package/build/run/bundler-detect.js +154 -0
  213. package/build/run/bundler-detect.js.map +1 -0
  214. package/build/run/index.js +208 -16
  215. package/build/run/index.js.map +1 -1
  216. package/build/sourcemaps/index.js +89 -0
  217. package/build/sourcemaps/index.js.map +1 -0
  218. package/build/strings/index.js +6 -2
  219. package/build/strings/index.js.map +1 -1
  220. package/build/strings/trufflehog.js +71 -0
  221. package/build/strings/trufflehog.js.map +1 -0
  222. package/build/utility/banner.js +68 -0
  223. package/build/utility/banner.js.map +1 -0
  224. package/build/utility/getChromiumPath.js +40 -0
  225. package/build/utility/getChromiumPath.js.map +1 -0
  226. package/build/utility/globals.js +7 -0
  227. package/build/utility/globals.js.map +1 -1
  228. package/build/utility/makeReq.js +21 -11
  229. package/build/utility/makeReq.js.map +1 -1
  230. package/build/utility/postmanGenerator.js +2 -2
  231. package/build/utility/postmanGenerator.js.map +1 -1
  232. package/build/utility/puppeteerInstance.js +7 -1
  233. package/build/utility/puppeteerInstance.js.map +1 -1
  234. package/package.json +14 -8
  235. package/scripts/smoke-test.js +74 -0
  236. package/urls.txt +5 -0
@@ -0,0 +1,10 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npm view *)",
5
+ "Bash(python3 -c \"import json, sys; v=json.load\\(sys.stdin\\); stable=[x for x in v if all\\(c not in x for c in ['alpha','beta','rc','canary','next','experimental','-']\\)]; print\\('\\\\n'.join\\(stable[-30:]\\)\\)\")",
6
+ "Bash(npm install *)",
7
+ "Bash(npx vitest *)"
8
+ ]
9
+ }
10
+ }
@@ -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"
@@ -113,9 +139,174 @@ jobs:
113
139
  runs-on: ubuntu-latest
114
140
  steps:
115
141
  - name: Checkout
116
- uses: actions/checkout@v4
142
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
117
143
  with:
118
144
  # Make sure the action checks out the repository to the pull request branch
119
145
  ref: ${{ github.ref_name }}
120
146
  - name: Build docker container
121
- run: docker build -t shriyanss/js-recon .
147
+ run: docker build -t js-recon/js-recon .
148
+
149
+ integration-test-docker:
150
+ needs: build-docker
151
+ runs-on: ubuntu-latest
152
+ timeout-minutes: 30
153
+ steps:
154
+ - name: Checkout js-recon
155
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
156
+ with:
157
+ ref: ${{ github.ref_name }}
158
+
159
+ - name: Checkout js-recon-labs
160
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
161
+ with:
162
+ repository: js-recon/js-recon-labs
163
+ path: js-recon-labs
164
+
165
+ - name: Checkout js-recon-rules
166
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
167
+ with:
168
+ repository: js-recon/js-recon-rules
169
+ path: js-recon-rules
170
+
171
+ - name: Set up Node.js
172
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
173
+ with:
174
+ node-version: "22"
175
+ cache: "npm"
176
+
177
+ - name: Build js-recon Docker image
178
+ run: docker build -t js-recon/js-recon .
179
+
180
+ - name: Install vuln-all-rules app dependencies
181
+ working-directory: js-recon-labs/next_js/vuln-all-rules
182
+ run: npm ci
183
+
184
+ - name: Build vuln-all-rules app
185
+ working-directory: js-recon-labs/next_js/vuln-all-rules
186
+ run: npm run build
187
+
188
+ - name: Start vuln-all-rules app
189
+ working-directory: js-recon-labs/next_js/vuln-all-rules
190
+ run: npm start &
191
+
192
+ - name: Wait for lab app to be ready
193
+ run: |
194
+ echo "Waiting for lab app on port 3001..."
195
+ n=0
196
+ until curl -sf http://localhost:3001 > /dev/null; do
197
+ n=$((n+1))
198
+ [ $n -ge 30 ] && echo "Timed out waiting for lab app" && exit 1
199
+ sleep 2
200
+ done
201
+ echo "Lab app is ready."
202
+
203
+ - name: Run js-recon via Docker against lab app
204
+ run: |
205
+ docker run --name js-recon-run \
206
+ --network host \
207
+ -v "$(pwd)/js-recon-rules:/home/pptruser/js-recon-rules" \
208
+ --entrypoint /bin/bash \
209
+ js-recon/js-recon \
210
+ -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'
211
+ mkdir -p output
212
+ docker cp js-recon-run:/home/pptruser/output/. ./output/ 2>/dev/null || true
213
+ docker rm js-recon-run
214
+
215
+ - name: Verify all rules fired
216
+ run: node scripts/smoke-test.js
217
+
218
+ - name: Upload analyze.json on failure
219
+ if: failure()
220
+ uses: actions/upload-artifact@v4
221
+ with:
222
+ name: analyze-json-docker
223
+ path: output/localhost_3001/analyze.json
224
+ if-no-files-found: ignore
225
+
226
+ integration-test-macos:
227
+ needs: build
228
+ runs-on: macos-latest
229
+ timeout-minutes: 30
230
+ steps:
231
+ - name: Checkout js-recon
232
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
233
+ with:
234
+ ref: ${{ github.ref_name }}
235
+
236
+ - name: Checkout js-recon-labs
237
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
238
+ with:
239
+ repository: js-recon/js-recon-labs
240
+ path: js-recon-labs
241
+
242
+ - name: Checkout js-recon-rules
243
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
244
+ with:
245
+ repository: js-recon/js-recon-rules
246
+ path: js-recon-rules
247
+
248
+ - name: Set up Node.js
249
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
250
+ with:
251
+ node-version: "22"
252
+ cache: "npm"
253
+
254
+ - name: Install Chrome
255
+ run: brew install --cask google-chrome
256
+
257
+ - name: Install js-recon dependencies
258
+ run: npm ci
259
+ env:
260
+ PUPPETEER_SKIP_DOWNLOAD: "true"
261
+
262
+ - name: Build js-recon
263
+ run: npm run build
264
+
265
+ - name: Install vuln-all-rules app dependencies
266
+ working-directory: js-recon-labs/next_js/vuln-all-rules
267
+ run: npm ci
268
+
269
+ - name: Build vuln-all-rules app
270
+ working-directory: js-recon-labs/next_js/vuln-all-rules
271
+ run: npm run build
272
+
273
+ - name: Start vuln-all-rules app
274
+ working-directory: js-recon-labs/next_js/vuln-all-rules
275
+ run: npm start &
276
+
277
+ - name: Wait for lab app to be ready
278
+ run: |
279
+ echo "Waiting for lab app on port 3001..."
280
+ n=0
281
+ until curl -sf http://localhost:3001 > /dev/null; do
282
+ n=$((n+1))
283
+ [ $n -ge 30 ] && echo "Timed out waiting for lab app" && exit 1
284
+ sleep 2
285
+ done
286
+ echo "Lab app is ready."
287
+
288
+ - name: Pre-populate js-recon rules cache
289
+ run: |
290
+ mkdir -p ~/.js-recon
291
+ ln -sf "$GITHUB_WORKSPACE/js-recon-rules" ~/.js-recon/rules
292
+
293
+ - name: Run js-recon natively against lab app
294
+ run: |
295
+ echo "http://localhost:3001" > /tmp/smoke-urls.txt
296
+ node --max-old-space-size=4096 build/index.js run \
297
+ -u /tmp/smoke-urls.txt \
298
+ -r ./js-recon-rules \
299
+ -y -k
300
+ env:
301
+ PUPPETEER_EXECUTABLE_PATH: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
302
+
303
+ - name: Verify all rules fired
304
+ run: node scripts/smoke-test.js
305
+
306
+ - name: Upload analyze.json on failure
307
+ if: failure()
308
+ uses: actions/upload-artifact@v4
309
+ with:
310
+ name: analyze-json-macos
311
+ path: output/localhost_3001/analyze.json
312
+ 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