0sec-cli 0.21.4 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/0.js +56 -56
  2. package/README.md +48 -63
  3. package/chunks/{adapt-loop-IGBRQAXO.js → adapt-loop-J6QCZZTB.js} +4 -4
  4. package/chunks/{artifact-scraper-LNQJUORS.js → artifact-scraper-MFKT6OI4.js} +2 -2
  5. package/chunks/{assumption-mining-4MJTP6H5.js → assumption-mining-646LYSJY.js} +16 -16
  6. package/chunks/{chunk-Z3IKZX3X.js → chunk-23DG5YKS.js} +1 -1
  7. package/chunks/{chunk-2WSXFFJZ.js → chunk-3E2KALZ5.js} +2 -2
  8. package/chunks/{chunk-TF46UWFU.js → chunk-4G7OVYJX.js} +1 -1
  9. package/chunks/{chunk-E2UOY5PJ.js → chunk-5BTJMINS.js} +12 -70
  10. package/chunks/{chunk-QZVG3BG4.js → chunk-5IBCBQEH.js} +1 -2
  11. package/chunks/{chunk-YA4PUM4H.js → chunk-7XCKYNLO.js} +1 -1
  12. package/chunks/{chunk-BACXRTQ4.js → chunk-AV2LG2L7.js} +87 -767
  13. package/chunks/{chunk-IMGWPNQM.js → chunk-BCSRRQG5.js} +76 -593
  14. package/chunks/{chunk-NOPBXZUV.js → chunk-BOUGKEKA.js} +1 -1
  15. package/chunks/{chunk-RF5QGKLR.js → chunk-CPWA6RWE.js} +3 -3
  16. package/chunks/{chunk-P6YG6TEZ.js → chunk-DKSCN2AB.js} +1 -1
  17. package/chunks/{chunk-YPOA3W4O.js → chunk-GOEA3NW6.js} +877 -110
  18. package/chunks/{chunk-ANDKY54G.js → chunk-HHPWRY2M.js} +4019 -7299
  19. package/chunks/{chunk-NDJU5ZZ7.js → chunk-IFME676H.js} +3 -3
  20. package/chunks/{chunk-HBKCGJAV.js → chunk-IVQV574Y.js} +1 -1
  21. package/chunks/{chunk-W4JOXE4N.js → chunk-IXT64DV5.js} +709 -1929
  22. package/chunks/{chunk-PC6RCKQV.js → chunk-KAU6NLGP.js} +59 -26
  23. package/chunks/{chunk-FAH6V4QM.js → chunk-LGCASF2C.js} +1117 -2291
  24. package/chunks/{chunk-CAJJRUTV.js → chunk-NLH4LMWH.js} +1 -1
  25. package/chunks/chunk-OHHCGDJ2.js +5523 -0
  26. package/chunks/{chunk-YHWWF4QY.js → chunk-OSBPGWTE.js} +3 -3
  27. package/chunks/{chunk-G34QP2XW.js → chunk-TM74SSHC.js} +1 -1
  28. package/chunks/{chunk-VOAXLO4A.js → chunk-TO35Y326.js} +5 -721
  29. package/chunks/{chunk-FWAYJ2IV.js → chunk-TV27OWIW.js} +8 -8
  30. package/chunks/chunk-UELXHK2Y.js +1950 -0
  31. package/chunks/{chunk-CL5KAUM6.js → chunk-V6GHX34G.js} +274 -8
  32. package/chunks/{chunk-WZISK5VC.js → chunk-VWITLWXB.js} +53 -7
  33. package/chunks/{chunk-ER3SUMYJ.js → chunk-W6UWZFKL.js} +0 -195
  34. package/chunks/chunk-WSDDGFA6.js +114 -0
  35. package/chunks/{chunk-5T6D5BVY.js → chunk-WZRVS7SB.js} +1 -1
  36. package/chunks/chunk-X7LAEEUW.js +2143 -0
  37. package/chunks/chunk-XA2O4WXA.js +1228 -0
  38. package/chunks/{chunk-Y5H6E24H.js → chunk-XCISCI4T.js} +1 -1
  39. package/chunks/{chunk-WPQLBN4S.js → chunk-XDKB2P5X.js} +1 -1
  40. package/chunks/{chunk-SBMB4OL3.js → chunk-YL6YAGLL.js} +62 -8
  41. package/chunks/{chunk-O6SD4A36.js → chunk-ZKQ2I3S2.js} +1 -1
  42. package/chunks/{codex-models-TYYV4JNN.js → codex-models-NHQW45SO.js} +5 -3
  43. package/chunks/{commands-WF5RG4I2.js → commands-N6GN5SBF.js} +2152 -3643
  44. package/chunks/{db-U3WQZVAO.js → db-5IWEJUYV.js} +3 -3
  45. package/chunks/{disclose-67GZCDBO.js → disclose-LDNKAVRH.js} +10 -8
  46. package/chunks/{dist-ACC3DZUZ.js → dist-BS4CY4RG.js} +3 -1
  47. package/chunks/{dist-EVTN3UTT.js → dist-FSS7MBDF.js} +2 -2
  48. package/chunks/{dist-F6X62TQK.js → dist-L3XJWWZ6.js} +225 -192
  49. package/chunks/{eval-runner-SA6OUGHZ.js → eval-runner-EMEGF24P.js} +11 -11
  50. package/chunks/{exploit-agent-36Q7XQFP.js → exploit-agent-KW4EB7BE.js} +1 -1
  51. package/chunks/{exploit-autoclimb-J4OTSTZ6.js → exploit-autoclimb-CXJ2ERRO.js} +1 -1
  52. package/chunks/{exploit-climb-PYEJDIC4.js → exploit-climb-TJWLY4XC.js} +2 -2
  53. package/chunks/fix-UUKPXCFB.js +26 -0
  54. package/chunks/{harness-GDUMKGSE.js → harness-C5HOKIEV.js} +3 -3
  55. package/chunks/{hunt-scan-UDJSCISU.js → hunt-scan-KZZ444V2.js} +14 -14
  56. package/chunks/{identity-JTIVJSV7.js → identity-62SVRW4H.js} +1 -1
  57. package/chunks/{kernel-primitive-F2IXUFAX.js → kernel-primitive-Z77IR7YS.js} +2 -2
  58. package/chunks/{kernel-vm-runner-276LHIOV.js → kernel-vm-runner-JW77P276.js} +2 -2
  59. package/chunks/{memsafety-scan-NHUOGTEX.js → memsafety-scan-FCPAXIZE.js} +2 -2
  60. package/chunks/{native-loop-3BSYVDUI.js → native-loop-P6P5GYVJ.js} +10 -10
  61. package/chunks/{npm-detectors-VIYJXKFQ.js → npm-detectors-Z2ZIQCN4.js} +2 -2
  62. package/chunks/orchestrate-DWWUT5RC.js +58 -0
  63. package/chunks/{process-PNMC36JI.js → process-N245QIQG.js} +1 -4
  64. package/chunks/{run-CBGE6DRQ.js → run-GAFKBCTN.js} +14935 -17598
  65. package/chunks/{runtime-PXO5G6UV.js → runtime-H7YBR5IZ.js} +4 -5
  66. package/chunks/{scope-NJHIDDTN.js → scope-QWY4VQZ7.js} +4 -1
  67. package/chunks/{session-store-46WBZM22.js → session-store-XIDFGG7K.js} +2 -2
  68. package/chunks/{variant-candidates-UH2WC2HA.js → variant-candidates-7D4F5E4H.js} +3 -3
  69. package/chunks/{web-recon-prepass-SFXU44SS.js → web-recon-prepass-VXXBPDAV.js} +3 -3
  70. package/cli-path-traversal-fixture.js +352 -0
  71. package/dashboard/assets/bot-Bg1Tp9_d.js +1 -0
  72. package/dashboard/assets/dist-B_dDCPbu.js +1 -0
  73. package/dashboard/assets/findings-page-mayGhNx6.js +5 -0
  74. package/dashboard/assets/format--susmHX7.js +1 -0
  75. package/dashboard/assets/input-TuVPR3Zl.js +1 -0
  76. package/dashboard/assets/jsx-runtime-MGseXjj5.js +3 -0
  77. package/dashboard/assets/live-page-HWWHX99U.js +1 -0
  78. package/dashboard/assets/meta-tile-ckHo-w7k.js +1 -0
  79. package/dashboard/assets/operations-BxZ0OoXO.js +10 -0
  80. package/dashboard/assets/operations-app-D3d35rgo.js +46 -0
  81. package/dashboard/assets/overview-page-W_4IteEr.js +1 -0
  82. package/dashboard/assets/page-header-Bw9AJgBV.js +1 -0
  83. package/dashboard/assets/scans-page-CgzVXHnn.js +1 -0
  84. package/dashboard/assets/siren-KQj8QAnJ.js +1 -0
  85. package/dashboard/assets/table-8EDklulN.js +1 -0
  86. package/dashboard/assets/tabs-CFHPOwg8.js +1 -0
  87. package/dashboard/index.html +2 -3
  88. package/node_modules/node-addon-api/LICENSE.md +9 -0
  89. package/node_modules/node-addon-api/README.md +95 -0
  90. package/node_modules/node-addon-api/common.gypi +21 -0
  91. package/node_modules/node-addon-api/except.gypi +25 -0
  92. package/node_modules/node-addon-api/index.js +14 -0
  93. package/node_modules/node-addon-api/napi-inl.deprecated.h +186 -0
  94. package/node_modules/node-addon-api/napi-inl.h +7250 -0
  95. package/node_modules/node-addon-api/napi.h +3463 -0
  96. package/node_modules/node-addon-api/node_addon_api.gyp +42 -0
  97. package/node_modules/node-addon-api/node_api.gyp +9 -0
  98. package/node_modules/node-addon-api/noexcept.gypi +26 -0
  99. package/node_modules/node-addon-api/nothing.c +0 -0
  100. package/node_modules/node-addon-api/package-support.json +21 -0
  101. package/node_modules/node-addon-api/package.json +481 -0
  102. package/node_modules/node-addon-api/tools/README.md +73 -0
  103. package/node_modules/node-addon-api/tools/check-napi.js +99 -0
  104. package/node_modules/node-addon-api/tools/clang-format.js +71 -0
  105. package/node_modules/node-addon-api/tools/conversion.js +301 -0
  106. package/node_modules/node-gyp-build/LICENSE +21 -0
  107. package/node_modules/node-gyp-build/README.md +58 -0
  108. package/node_modules/node-gyp-build/SECURITY.md +5 -0
  109. package/node_modules/node-gyp-build/bin.js +84 -0
  110. package/node_modules/node-gyp-build/build-test.js +19 -0
  111. package/node_modules/node-gyp-build/index.js +6 -0
  112. package/node_modules/node-gyp-build/node-gyp-build.js +207 -0
  113. package/node_modules/node-gyp-build/optional.js +7 -0
  114. package/node_modules/node-gyp-build/package.json +43 -0
  115. package/node_modules/tree-sitter/LICENSE +21 -0
  116. package/node_modules/tree-sitter/README.md +90 -0
  117. package/node_modules/tree-sitter/binding.gyp +76 -0
  118. package/node_modules/tree-sitter/index.js +895 -0
  119. package/node_modules/tree-sitter/package.json +62 -0
  120. package/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
  121. package/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
  122. package/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
  123. package/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
  124. package/node_modules/tree-sitter/src/addon_data.h +47 -0
  125. package/node_modules/tree-sitter/src/binding.cc +35 -0
  126. package/node_modules/tree-sitter/src/conversions.cc +140 -0
  127. package/node_modules/tree-sitter/src/conversions.h +22 -0
  128. package/node_modules/tree-sitter/src/language.cc +106 -0
  129. package/node_modules/tree-sitter/src/language.h +17 -0
  130. package/node_modules/tree-sitter/src/logger.cc +70 -0
  131. package/node_modules/tree-sitter/src/logger.h +19 -0
  132. package/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
  133. package/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
  134. package/node_modules/tree-sitter/src/node.cc +1056 -0
  135. package/node_modules/tree-sitter/src/node.h +30 -0
  136. package/node_modules/tree-sitter/src/parser.cc +298 -0
  137. package/node_modules/tree-sitter/src/parser.h +35 -0
  138. package/node_modules/tree-sitter/src/query.cc +383 -0
  139. package/node_modules/tree-sitter/src/query.h +39 -0
  140. package/node_modules/tree-sitter/src/tree.cc +307 -0
  141. package/node_modules/tree-sitter/src/tree.h +45 -0
  142. package/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
  143. package/node_modules/tree-sitter/src/tree_cursor.h +52 -0
  144. package/node_modules/tree-sitter/tree-sitter.d.ts +211 -0
  145. package/node_modules/tree-sitter/vendor/tree-sitter/LICENSE +21 -0
  146. package/node_modules/tree-sitter/vendor/tree-sitter/README.md +21 -0
  147. package/node_modules/tree-sitter/vendor/tree-sitter/lib/README.md +6 -0
  148. package/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1266 -0
  149. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
  150. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
  151. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +290 -0
  152. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
  153. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
  154. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
  155. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +501 -0
  156. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
  157. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
  158. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +221 -0
  159. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +299 -0
  160. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
  161. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +419 -0
  162. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +49 -0
  163. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +14 -0
  164. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +774 -0
  165. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2151 -0
  166. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +230 -0
  167. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +62 -0
  168. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4134 -0
  169. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
  170. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
  171. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +899 -0
  172. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +133 -0
  173. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1060 -0
  174. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +382 -0
  175. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +165 -0
  176. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
  177. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +714 -0
  178. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
  179. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
  180. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
  181. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
  182. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
  183. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
  184. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
  185. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
  186. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
  187. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
  188. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +50 -0
  189. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +23 -0
  190. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +109 -0
  191. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1294 -0
  192. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1823 -0
  193. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
  194. package/node_modules/tree-sitter/vendor/tree-sitter/test/fixtures/grammars/.gitkeep +0 -0
  195. package/node_modules/tree-sitter-c/LICENSE +21 -0
  196. package/node_modules/tree-sitter-c/README.md +18 -0
  197. package/node_modules/tree-sitter-c/binding.gyp +20 -0
  198. package/node_modules/tree-sitter-c/bindings/node/binding.cc +20 -0
  199. package/node_modules/tree-sitter-c/bindings/node/index.d.ts +28 -0
  200. package/node_modules/tree-sitter-c/bindings/node/index.js +7 -0
  201. package/node_modules/tree-sitter-c/grammar.js +1463 -0
  202. package/node_modules/tree-sitter-c/package.json +108 -0
  203. package/node_modules/tree-sitter-c/prebuilds/darwin-arm64/tree-sitter-c.node +0 -0
  204. package/node_modules/tree-sitter-c/prebuilds/darwin-x64/tree-sitter-c.node +0 -0
  205. package/node_modules/tree-sitter-c/prebuilds/linux-x64/tree-sitter-c.node +0 -0
  206. package/node_modules/tree-sitter-c/prebuilds/win32-x64/tree-sitter-c.node +0 -0
  207. package/node_modules/tree-sitter-c/queries/highlights.scm +81 -0
  208. package/node_modules/tree-sitter-c/queries/tags.scm +9 -0
  209. package/node_modules/tree-sitter-c/src/grammar.json +9682 -0
  210. package/node_modules/tree-sitter-c/src/node-types.json +4556 -0
  211. package/node_modules/tree-sitter-c/src/parser.c +113852 -0
  212. package/node_modules/tree-sitter-c/src/tree_sitter/alloc.h +54 -0
  213. package/node_modules/tree-sitter-c/src/tree_sitter/array.h +290 -0
  214. package/node_modules/tree-sitter-c/src/tree_sitter/parser.h +265 -0
  215. package/package.json +10 -3
  216. package/vendor/tree-sitter-0.21.1-node24.json +16 -0
  217. package/vendor/tree-sitter-0.21.1-node24.tgz +0 -0
  218. package/chunks/chunk-CGHCEN7W.js +0 -169
  219. package/chunks/chunk-CXKDWFNO.js +0 -102
  220. package/chunks/chunk-GIQKESMN.js +0 -687
  221. package/chunks/chunk-HPQZHOIU.js +0 -67
  222. package/chunks/chunk-PD2BBBKT.js +0 -245
  223. package/chunks/chunk-WF5W75WY.js +0 -1070
  224. package/chunks/fix-J2KBRJDV.js +0 -12
  225. package/chunks/orchestrate-DHBFRTSI.js +0 -59
  226. package/chunks/replay-runner-LK2XFIVG.js +0 -39
  227. package/dashboard/assets/bot-yILPnRgD.js +0 -1
  228. package/dashboard/assets/chevron-down-BeDJ-Vka.js +0 -1
  229. package/dashboard/assets/circle-alert-BEnMBMT-.js +0 -1
  230. package/dashboard/assets/client-DRYsuOGl.js +0 -9
  231. package/dashboard/assets/copy-Bi5vzoF9.js +0 -1
  232. package/dashboard/assets/desktop-BT7RkC4q.js +0 -32
  233. package/dashboard/assets/desktop-OaBI0E0e.css +0 -1
  234. package/dashboard/assets/dist-CmX-h7a4.js +0 -1
  235. package/dashboard/assets/dist-DAwYQmf_.js +0 -45
  236. package/dashboard/assets/findings-page-B4rwF6fZ.js +0 -5
  237. package/dashboard/assets/format-LNQSSpn6.js +0 -1
  238. package/dashboard/assets/jsx-runtime-C7oxC63R.js +0 -1
  239. package/dashboard/assets/live-page-DoNwpPAO.js +0 -1
  240. package/dashboard/assets/meta-tile-BMtBC-Qq.js +0 -1
  241. package/dashboard/assets/operations-app-ER0gg7GN.js +0 -2
  242. package/dashboard/assets/operations-e2CGYKB1.js +0 -4
  243. package/dashboard/assets/overview-page-CmeWH17A.js +0 -1
  244. package/dashboard/assets/page-header-CIJyycfz.js +0 -1
  245. package/dashboard/assets/play-Dwo-9xt6.js +0 -1
  246. package/dashboard/assets/scans-page-CuhzWhHx.js +0 -1
  247. package/dashboard/assets/search-CiooTLck.js +0 -1
  248. package/dashboard/assets/siren-CCBwTSuk.js +0 -1
  249. package/dashboard/assets/table-BgsSBdke.js +0 -1
  250. package/dashboard/assets/tabs-vn6v7Bk6.js +0 -1
  251. package/dashboard/desktop.html +0 -21
@@ -0,0 +1,1950 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __0CreateRequire } from "node:module";
3
+ const require = __0CreateRequire(import.meta.url);
4
+
5
+ // packages/core/dist/disclose/cwe.js
6
+ var CWE_MAP = {
7
+ // LLM / agent
8
+ "prompt-injection": [
9
+ { id: "CWE-1039", name: "Inadequate Detection or Handling of Adversarial Input Perturbations in AI/ML Classifier", role: "primary" },
10
+ { id: "CWE-20", name: "Improper Input Validation", role: "secondary" },
11
+ { id: "CWE-94", name: "Improper Control of Generation of Code ('Code Injection')", role: "secondary" }
12
+ ],
13
+ "jailbreak": [
14
+ { id: "CWE-1039", name: "Inadequate Detection or Handling of Adversarial Input Perturbations in AI/ML Classifier", role: "primary" },
15
+ { id: "CWE-284", name: "Improper Access Control", role: "secondary" }
16
+ ],
17
+ "system-prompt-extraction": [
18
+ { id: "CWE-200", name: "Exposure of Sensitive Information to an Unauthorized Actor", role: "primary" },
19
+ { id: "CWE-1039", name: "Inadequate Detection or Handling of Adversarial Input Perturbations in AI/ML Classifier", role: "secondary" }
20
+ ],
21
+ "data-exfiltration": [
22
+ { id: "CWE-200", name: "Exposure of Sensitive Information to an Unauthorized Actor", role: "primary" },
23
+ { id: "CWE-522", name: "Insufficiently Protected Credentials", role: "secondary" }
24
+ ],
25
+ "tool-misuse": [
26
+ { id: "CWE-284", name: "Improper Access Control", role: "primary" },
27
+ { id: "CWE-441", name: "Unintended Proxy or Intermediary ('Confused Deputy')", role: "secondary" },
28
+ { id: "CWE-285", name: "Improper Authorization", role: "secondary" }
29
+ ],
30
+ "output-manipulation": [
31
+ { id: "CWE-116", name: "Improper Encoding or Escaping of Output", role: "primary" },
32
+ { id: "CWE-74", name: "Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')", role: "secondary" }
33
+ ],
34
+ "encoding-bypass": [
35
+ { id: "CWE-176", name: "Improper Handling of Unicode Encoding", role: "primary" },
36
+ { id: "CWE-20", name: "Improper Input Validation", role: "secondary" }
37
+ ],
38
+ "multi-turn": [
39
+ { id: "CWE-1039", name: "Inadequate Detection or Handling of Adversarial Input Perturbations in AI/ML Classifier", role: "primary" },
40
+ { id: "CWE-841", name: "Improper Enforcement of Behavioral Workflow", role: "secondary" }
41
+ ],
42
+ // Source-code audit
43
+ "prototype-pollution": [
44
+ { id: "CWE-1321", name: "Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')", role: "primary" },
45
+ { id: "CWE-915", name: "Improperly Controlled Modification of Dynamically-Determined Object Attributes", role: "secondary" }
46
+ ],
47
+ "path-traversal": [
48
+ { id: "CWE-22", name: "Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')", role: "primary" },
49
+ { id: "CWE-73", name: "External Control of File Name or Path", role: "secondary" },
50
+ { id: "CWE-284", name: "Improper Access Control", role: "secondary" }
51
+ ],
52
+ "command-injection": [
53
+ { id: "CWE-78", name: "Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')", role: "primary" },
54
+ { id: "CWE-77", name: "Improper Neutralization of Special Elements used in a Command ('Command Injection')", role: "secondary" }
55
+ ],
56
+ "code-injection": [
57
+ { id: "CWE-94", name: "Improper Control of Generation of Code ('Code Injection')", role: "primary" },
58
+ { id: "CWE-95", name: "Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')", role: "secondary" }
59
+ ],
60
+ "regex-dos": [
61
+ { id: "CWE-1333", name: "Inefficient Regular Expression Complexity", role: "primary" },
62
+ { id: "CWE-400", name: "Uncontrolled Resource Consumption", role: "secondary" }
63
+ ],
64
+ "unsafe-deserialization": [
65
+ { id: "CWE-502", name: "Deserialization of Untrusted Data", role: "primary" },
66
+ { id: "CWE-915", name: "Improperly Controlled Modification of Dynamically-Determined Object Attributes", role: "secondary" }
67
+ ],
68
+ "information-disclosure": [
69
+ { id: "CWE-200", name: "Exposure of Sensitive Information to an Unauthorized Actor", role: "primary" },
70
+ { id: "CWE-285", name: "Improper Authorization", role: "secondary" },
71
+ { id: "CWE-522", name: "Insufficiently Protected Credentials", role: "secondary" }
72
+ ],
73
+ "ssrf": [
74
+ { id: "CWE-918", name: "Server-Side Request Forgery (SSRF)", role: "primary" },
75
+ { id: "CWE-20", name: "Improper Input Validation", role: "secondary" },
76
+ { id: "CWE-441", name: "Unintended Proxy or Intermediary ('Confused Deputy')", role: "secondary" }
77
+ ],
78
+ "sql-injection": [
79
+ { id: "CWE-89", name: "Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')", role: "primary" }
80
+ ],
81
+ "xss": [
82
+ { id: "CWE-79", name: "Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')", role: "primary" },
83
+ { id: "CWE-80", name: "Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)", role: "secondary" }
84
+ ],
85
+ "cors": [
86
+ { id: "CWE-942", name: "Permissive Cross-domain Policy with Untrusted Domains", role: "primary" },
87
+ { id: "CWE-346", name: "Origin Validation Error", role: "secondary" }
88
+ ],
89
+ "security-misconfiguration": [
90
+ { id: "CWE-1188", name: "Initialization of a Resource with an Insecure Default", role: "primary" },
91
+ { id: "CWE-16", name: "Configuration", role: "secondary" }
92
+ ],
93
+ "missing-validation": [
94
+ { id: "CWE-20", name: "Improper Input Validation", role: "primary" }
95
+ ],
96
+ "crypto-misuse": [
97
+ { id: "CWE-327", name: "Use of a Broken or Risky Cryptographic Algorithm", role: "primary" },
98
+ { id: "CWE-328", name: "Use of Weak Hash", role: "secondary" },
99
+ { id: "CWE-321", name: "Use of Hard-coded Cryptographic Key", role: "secondary" },
100
+ { id: "CWE-329", name: "Generation of Predictable IV with CBC Mode", role: "secondary" },
101
+ { id: "CWE-330", name: "Use of Insufficiently Random Values", role: "secondary" },
102
+ { id: "CWE-347", name: "Improper Verification of Cryptographic Signature", role: "secondary" }
103
+ ],
104
+ // Memory corruption / binary
105
+ "heap-overflow": [
106
+ { id: "CWE-122", name: "Heap-based Buffer Overflow", role: "primary" },
107
+ { id: "CWE-787", name: "Out-of-bounds Write", role: "secondary" }
108
+ ],
109
+ "out-of-bounds-read": [
110
+ { id: "CWE-125", name: "Out-of-bounds Read", role: "primary" }
111
+ ],
112
+ "out-of-bounds-write": [
113
+ { id: "CWE-787", name: "Out-of-bounds Write", role: "primary" },
114
+ { id: "CWE-122", name: "Heap-based Buffer Overflow", role: "secondary" }
115
+ ],
116
+ "use-after-free": [
117
+ { id: "CWE-416", name: "Use After Free", role: "primary" },
118
+ { id: "CWE-672", name: "Operation on a Resource after Expiration or Release", role: "secondary" }
119
+ ],
120
+ "stack-buffer-overflow": [
121
+ { id: "CWE-121", name: "Stack-based Buffer Overflow", role: "primary" },
122
+ { id: "CWE-787", name: "Out-of-bounds Write", role: "secondary" }
123
+ ],
124
+ "null-pointer-deref": [
125
+ { id: "CWE-476", name: "NULL Pointer Dereference", role: "primary" }
126
+ ],
127
+ "null-deref": [
128
+ { id: "CWE-476", name: "NULL Pointer Dereference", role: "primary" }
129
+ ],
130
+ "integer-overflow": [
131
+ { id: "CWE-190", name: "Integer Overflow or Wraparound", role: "primary" },
132
+ { id: "CWE-191", name: "Integer Underflow (Wrap or Wraparound)", role: "secondary" }
133
+ ],
134
+ "integer-truncation": [
135
+ { id: "CWE-197", name: "Numeric Truncation Error", role: "primary" },
136
+ { id: "CWE-681", name: "Incorrect Conversion between Numeric Types", role: "secondary" }
137
+ ],
138
+ "denial-of-service": [
139
+ { id: "CWE-400", name: "Uncontrolled Resource Consumption", role: "primary" },
140
+ { id: "CWE-833", name: "Deadlock", role: "secondary" }
141
+ ],
142
+ "race-condition": [
143
+ { id: "CWE-362", name: "Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')", role: "primary" },
144
+ { id: "CWE-367", name: "Time-of-check Time-of-use (TOCTOU) Race Condition", role: "secondary" }
145
+ ],
146
+ "toctou": [
147
+ { id: "CWE-367", name: "Time-of-check Time-of-use (TOCTOU) Race Condition", role: "primary" },
148
+ { id: "CWE-362", name: "Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')", role: "secondary" }
149
+ ],
150
+ "type-confusion": [
151
+ { id: "CWE-843", name: "Access of Resource Using Incompatible Type ('Type Confusion')", role: "primary" }
152
+ ],
153
+ "double-free": [
154
+ { id: "CWE-415", name: "Double Free", role: "primary" }
155
+ ],
156
+ "format-string": [
157
+ { id: "CWE-134", name: "Use of Externally-Controlled Format String", role: "primary" }
158
+ ],
159
+ "uninitialized-memory": [
160
+ { id: "CWE-457", name: "Use of Uninitialized Variable", role: "primary" },
161
+ { id: "CWE-908", name: "Use of Uninitialized Resource", role: "secondary" }
162
+ ],
163
+ // Supply-chain / package
164
+ "known-vulnerable-package": [
165
+ { id: "CWE-1395", name: "Dependency on Vulnerable Third-Party Component", role: "primary" },
166
+ { id: "CWE-1104", name: "Use of Unmaintained Third Party Components", role: "secondary" },
167
+ { id: "CWE-937", name: "OWASP Top Ten 2013 Category A9 - Using Components with Known Vulnerabilities", role: "secondary" }
168
+ ],
169
+ "supply-chain": [
170
+ { id: "CWE-1357", name: "Reliance on Insufficiently Trustworthy Component", role: "primary" },
171
+ { id: "CWE-506", name: "Embedded Malicious Code", role: "secondary" },
172
+ { id: "CWE-829", name: "Inclusion of Functionality from Untrusted Control Sphere", role: "secondary" }
173
+ ],
174
+ "other": [
175
+ { id: "CWE-693", name: "Protection Mechanism Failure", role: "primary" }
176
+ ]
177
+ };
178
+ function suggestCwesForCategory(category) {
179
+ return CWE_MAP[category] ?? [
180
+ { id: "CWE-693", name: "Protection Mechanism Failure", role: "primary" }
181
+ ];
182
+ }
183
+ function formatCweSection(entries) {
184
+ if (entries.length === 0)
185
+ return "";
186
+ const lines = ["# CWE", ""];
187
+ lines.push("Pick these in the GHSA form's CWE selector (multi-select):");
188
+ lines.push("");
189
+ for (const entry of entries) {
190
+ const emphasis = entry.role === "primary" ? " *(primary)*" : "";
191
+ lines.push(`- **${entry.id}**: ${entry.name}${emphasis}`);
192
+ }
193
+ return lines.join("\n");
194
+ }
195
+
196
+ // packages/core/dist/disclose/cvss.js
197
+ var IMPACT_BY_CATEGORY = {
198
+ "prompt-injection": { C: "L", I: "L", A: "N", scope: "U" },
199
+ "jailbreak": { C: "L", I: "L", A: "N", scope: "U" },
200
+ "system-prompt-extraction": { C: "H", I: "N", A: "N", scope: "U" },
201
+ "data-exfiltration": { C: "H", I: "N", A: "N", scope: "C" },
202
+ "tool-misuse": { C: "H", I: "H", A: "L", scope: "C" },
203
+ "output-manipulation": { C: "L", I: "H", A: "N", scope: "U" },
204
+ "encoding-bypass": { C: "L", I: "L", A: "N", scope: "U" },
205
+ "multi-turn": { C: "L", I: "L", A: "N", scope: "U" },
206
+ "prototype-pollution": { C: "H", I: "H", A: "H", scope: "U" },
207
+ "path-traversal": { C: "H", I: "H", A: "L", scope: "U" },
208
+ "command-injection": { C: "H", I: "H", A: "H", scope: "U" },
209
+ "code-injection": { C: "H", I: "H", A: "H", scope: "U" },
210
+ "regex-dos": { C: "N", I: "N", A: "H", scope: "U" },
211
+ "unsafe-deserialization": { C: "H", I: "H", A: "H", scope: "U" },
212
+ "information-disclosure": { C: "H", I: "N", A: "N", scope: "C" },
213
+ "ssrf": { C: "H", I: "N", A: "N", scope: "C" },
214
+ "sql-injection": { C: "H", I: "H", A: "H", scope: "U" },
215
+ "xss": { C: "L", I: "L", A: "N", scope: "C" },
216
+ "cors": { C: "L", I: "L", A: "N", scope: "U" },
217
+ "security-misconfiguration": { C: "L", I: "L", A: "N", scope: "U" },
218
+ "missing-validation": { C: "L", I: "L", A: "L", scope: "U" },
219
+ "crypto-misuse": { C: "H", I: "H", A: "N", scope: "U" },
220
+ "heap-overflow": { C: "H", I: "H", A: "H", scope: "U" },
221
+ "out-of-bounds-read": { C: "H", I: "N", A: "L", scope: "U" },
222
+ "out-of-bounds-write": { C: "H", I: "H", A: "H", scope: "U" },
223
+ "use-after-free": { C: "H", I: "H", A: "H", scope: "U" },
224
+ "stack-buffer-overflow": { C: "H", I: "H", A: "H", scope: "U" },
225
+ "null-pointer-deref": { C: "N", I: "N", A: "H", scope: "U" },
226
+ "null-deref": { C: "N", I: "N", A: "H", scope: "U" },
227
+ "integer-overflow": { C: "L", I: "L", A: "L", scope: "U" },
228
+ "integer-truncation": { C: "L", I: "L", A: "L", scope: "U" },
229
+ "race-condition": { C: "L", I: "L", A: "L", scope: "U" },
230
+ "denial-of-service": { C: "N", I: "N", A: "H", scope: "U" },
231
+ "toctou": { C: "L", I: "L", A: "L", scope: "U" },
232
+ "type-confusion": { C: "H", I: "H", A: "H", scope: "U" },
233
+ "double-free": { C: "H", I: "H", A: "H", scope: "U" },
234
+ "format-string": { C: "H", I: "H", A: "H", scope: "U" },
235
+ "uninitialized-memory": { C: "H", I: "N", A: "L", scope: "U" },
236
+ "known-vulnerable-package": { C: "L", I: "L", A: "L", scope: "U" },
237
+ "supply-chain": { C: "H", I: "H", A: "H", scope: "C" },
238
+ "other": { C: "L", I: "L", A: "L", scope: "U" }
239
+ };
240
+ var W = {
241
+ AV: { N: 0.85, A: 0.62, L: 0.55, P: 0.2 },
242
+ AC: { L: 0.77, H: 0.44 },
243
+ PR_U: { N: 0.85, L: 0.62, H: 0.27 },
244
+ PR_C: { N: 0.85, L: 0.68, H: 0.5 },
245
+ UI: { N: 0.85, R: 0.62 },
246
+ CIA: { N: 0, L: 0.22, H: 0.56 }
247
+ };
248
+ function roundUp(n) {
249
+ return Math.ceil(n * 10) / 10;
250
+ }
251
+ function computeBaseScore(av, ac, pr, ui, scope, c, i, a) {
252
+ const iss = 1 - (1 - W.CIA[c]) * (1 - W.CIA[i]) * (1 - W.CIA[a]);
253
+ const impact = scope === "U" ? 6.42 * iss : 7.52 * (iss - 0.029) - 3.25 * Math.pow(iss - 0.02, 15);
254
+ const prWeight = (scope === "C" ? W.PR_C : W.PR_U)[pr];
255
+ const exploit = 8.22 * W.AV[av] * W.AC[ac] * prWeight * W.UI[ui];
256
+ if (impact <= 0)
257
+ return 0;
258
+ const base = scope === "U" ? Math.min(impact + exploit, 10) : Math.min(1.08 * (impact + exploit), 10);
259
+ return roundUp(base);
260
+ }
261
+ function prForSeverity(severity) {
262
+ switch (severity) {
263
+ case "critical":
264
+ return "N";
265
+ case "high":
266
+ return "L";
267
+ case "medium":
268
+ case "low":
269
+ return "L";
270
+ default:
271
+ return "H";
272
+ }
273
+ }
274
+ function metricsForReachability(tier) {
275
+ switch (tier) {
276
+ case "remote-unauth":
277
+ return { av: "N", pr: "N", ui: "N" };
278
+ case "remote-auth":
279
+ return { av: "N", pr: "L", ui: "N" };
280
+ case "proximity-rf":
281
+ return { av: "A", pr: "N", ui: "N" };
282
+ case "local-unpriv":
283
+ return { av: "L", pr: "L", ui: "N" };
284
+ case "local-priv":
285
+ return { av: "L", pr: "H", ui: "N" };
286
+ case "needs-hardware":
287
+ return { av: "P", pr: "N", ui: "N" };
288
+ case "needs-host-migration":
289
+ return { av: "L", pr: "N", ui: "R" };
290
+ }
291
+ }
292
+ function suggestCvss(finding) {
293
+ if (finding.cvssVector && finding.cvssScore !== void 0) {
294
+ return { vector: finding.cvssVector, score: finding.cvssScore, source: "finding" };
295
+ }
296
+ const impact = IMPACT_BY_CATEGORY[finding.category] ?? { C: "L", I: "L", A: "L", scope: "U" };
297
+ const ac = "L";
298
+ const assessed = finding.impactAssessment ? metricsForReachability(finding.impactAssessment.reachability_tier) : void 0;
299
+ const av = assessed?.av ?? "N";
300
+ const pr = assessed?.pr ?? prForSeverity(finding.severity);
301
+ const ui = assessed?.ui ?? "N";
302
+ const vector = `CVSS:3.1/AV:${av}/AC:${ac}/PR:${pr}/UI:${ui}/S:${impact.scope}/C:${impact.C}/I:${impact.I}/A:${impact.A}`;
303
+ const score = computeBaseScore(av, ac, pr, ui, impact.scope, impact.C, impact.I, impact.A);
304
+ return { vector, score, source: assessed ? "impact-assessment" : "heuristic" };
305
+ }
306
+ var Cvss4ParseError = class extends Error {
307
+ constructor(message) {
308
+ super(message);
309
+ this.name = "Cvss4ParseError";
310
+ }
311
+ };
312
+ var CVSS4_ALLOWED = {
313
+ AV: /* @__PURE__ */ new Set(["N", "A", "L", "P"]),
314
+ AC: /* @__PURE__ */ new Set(["L", "H"]),
315
+ AT: /* @__PURE__ */ new Set(["N", "P"]),
316
+ PR: /* @__PURE__ */ new Set(["N", "L", "H"]),
317
+ UI: /* @__PURE__ */ new Set(["N", "P", "A"]),
318
+ VC: /* @__PURE__ */ new Set(["H", "L", "N"]),
319
+ VI: /* @__PURE__ */ new Set(["H", "L", "N"]),
320
+ VA: /* @__PURE__ */ new Set(["H", "L", "N"]),
321
+ SC: /* @__PURE__ */ new Set(["H", "L", "N"]),
322
+ SI: /* @__PURE__ */ new Set(["H", "L", "N"]),
323
+ SA: /* @__PURE__ */ new Set(["H", "L", "N"]),
324
+ // Threat
325
+ E: /* @__PURE__ */ new Set(["X", "A", "P", "U"]),
326
+ // Environmental (requirements)
327
+ CR: /* @__PURE__ */ new Set(["X", "H", "M", "L"]),
328
+ IR: /* @__PURE__ */ new Set(["X", "H", "M", "L"]),
329
+ AR: /* @__PURE__ */ new Set(["X", "H", "M", "L"]),
330
+ // Environmental (modified base)
331
+ MAV: /* @__PURE__ */ new Set(["X", "N", "A", "L", "P"]),
332
+ MAC: /* @__PURE__ */ new Set(["X", "L", "H"]),
333
+ MAT: /* @__PURE__ */ new Set(["X", "N", "P"]),
334
+ MPR: /* @__PURE__ */ new Set(["X", "N", "L", "H"]),
335
+ MUI: /* @__PURE__ */ new Set(["X", "N", "P", "A"]),
336
+ MVC: /* @__PURE__ */ new Set(["X", "H", "L", "N"]),
337
+ MVI: /* @__PURE__ */ new Set(["X", "H", "L", "N"]),
338
+ MVA: /* @__PURE__ */ new Set(["X", "H", "L", "N"]),
339
+ MSC: /* @__PURE__ */ new Set(["X", "H", "L", "N"]),
340
+ MSI: /* @__PURE__ */ new Set(["X", "S", "H", "L", "N"]),
341
+ MSA: /* @__PURE__ */ new Set(["X", "S", "H", "L", "N"]),
342
+ // Supplemental (do not affect score)
343
+ S: /* @__PURE__ */ new Set(["X", "N", "P"]),
344
+ AU: /* @__PURE__ */ new Set(["X", "N", "Y"]),
345
+ R: /* @__PURE__ */ new Set(["X", "A", "U", "I"]),
346
+ V: /* @__PURE__ */ new Set(["X", "D", "C"]),
347
+ RE: /* @__PURE__ */ new Set(["X", "L", "M", "H"]),
348
+ U: /* @__PURE__ */ new Set(["X", "Clear", "Green", "Amber", "Red"])
349
+ };
350
+ var CVSS4_BASE_KEYS = [
351
+ "AV",
352
+ "AC",
353
+ "AT",
354
+ "PR",
355
+ "UI",
356
+ "VC",
357
+ "VI",
358
+ "VA",
359
+ "SC",
360
+ "SI",
361
+ "SA"
362
+ ];
363
+ var AV_levels = { N: 0, A: 0.1, L: 0.2, P: 0.3 };
364
+ var PR_levels = { N: 0, L: 0.1, H: 0.2 };
365
+ var UI_levels = { N: 0, P: 0.1, A: 0.2 };
366
+ var AC_levels = { L: 0, H: 0.1 };
367
+ var AT_levels = { N: 0, P: 0.1 };
368
+ var VC_levels = { H: 0, L: 0.1, N: 0.2 };
369
+ var VI_levels = { H: 0, L: 0.1, N: 0.2 };
370
+ var VA_levels = { H: 0, L: 0.1, N: 0.2 };
371
+ var SC_levels = { H: 0.1, L: 0.2, N: 0.3 };
372
+ var SI_levels = { S: 0, H: 0.1, L: 0.2, N: 0.3 };
373
+ var SA_levels = { S: 0, H: 0.1, L: 0.2, N: 0.3 };
374
+ var CR_levels = { H: 0, M: 0.1, L: 0.2 };
375
+ var IR_levels = { H: 0, M: 0.1, L: 0.2 };
376
+ var AR_levels = { H: 0, M: 0.1, L: 0.2 };
377
+ var CVSS40_LOOKUP = {
378
+ "000000": 10,
379
+ "000001": 9.9,
380
+ "000010": 9.8,
381
+ "000011": 9.5,
382
+ "000020": 9.5,
383
+ "000021": 9.2,
384
+ "000100": 10,
385
+ "000101": 9.6,
386
+ "000110": 9.3,
387
+ "000111": 8.7,
388
+ "000120": 9.1,
389
+ "000121": 8.1,
390
+ "000200": 9.3,
391
+ "000201": 9,
392
+ "000210": 8.9,
393
+ "000211": 8,
394
+ "000220": 8.1,
395
+ "000221": 6.8,
396
+ "001000": 9.8,
397
+ "001001": 9.5,
398
+ "001010": 9.5,
399
+ "001011": 9.2,
400
+ "001020": 9,
401
+ "001021": 8.4,
402
+ "001100": 9.3,
403
+ "001101": 9.2,
404
+ "001110": 8.9,
405
+ "001111": 8.1,
406
+ "001120": 8.1,
407
+ "001121": 6.5,
408
+ "001200": 8.8,
409
+ "001201": 8,
410
+ "001210": 7.8,
411
+ "001211": 7,
412
+ "001220": 6.9,
413
+ "001221": 4.8,
414
+ "002001": 9.2,
415
+ "002011": 8.2,
416
+ "002021": 7.2,
417
+ "002101": 7.9,
418
+ "002111": 6.9,
419
+ "002121": 5,
420
+ "002201": 6.9,
421
+ "002211": 5.5,
422
+ "002221": 2.7,
423
+ "010000": 9.9,
424
+ "010001": 9.7,
425
+ "010010": 9.5,
426
+ "010011": 9.2,
427
+ "010020": 9.2,
428
+ "010021": 8.5,
429
+ "010100": 9.5,
430
+ "010101": 9.1,
431
+ "010110": 9,
432
+ "010111": 8.3,
433
+ "010120": 8.4,
434
+ "010121": 7.1,
435
+ "010200": 9.2,
436
+ "010201": 8.1,
437
+ "010210": 8.2,
438
+ "010211": 7.1,
439
+ "010220": 7.2,
440
+ "010221": 5.3,
441
+ "011000": 9.5,
442
+ "011001": 9.3,
443
+ "011010": 9.2,
444
+ "011011": 8.5,
445
+ "011020": 8.5,
446
+ "011021": 7.3,
447
+ "011100": 9.2,
448
+ "011101": 8.2,
449
+ "011110": 8,
450
+ "011111": 7.2,
451
+ "011120": 7,
452
+ "011121": 5.9,
453
+ "011200": 8.4,
454
+ "011201": 7,
455
+ "011210": 7.1,
456
+ "011211": 5.2,
457
+ "011220": 5,
458
+ "011221": 3,
459
+ "012001": 8.6,
460
+ "012011": 7.5,
461
+ "012021": 5.2,
462
+ "012101": 7.1,
463
+ "012111": 5.2,
464
+ "012121": 2.9,
465
+ "012201": 6.3,
466
+ "012211": 2.9,
467
+ "012221": 1.7,
468
+ "100000": 9.8,
469
+ "100001": 9.5,
470
+ "100010": 9.4,
471
+ "100011": 8.7,
472
+ "100020": 9.1,
473
+ "100021": 8.1,
474
+ "100100": 9.4,
475
+ "100101": 8.9,
476
+ "100110": 8.6,
477
+ "100111": 7.4,
478
+ "100120": 7.7,
479
+ "100121": 6.4,
480
+ "100200": 8.7,
481
+ "100201": 7.5,
482
+ "100210": 7.4,
483
+ "100211": 6.3,
484
+ "100220": 6.3,
485
+ "100221": 4.9,
486
+ "101000": 9.4,
487
+ "101001": 8.9,
488
+ "101010": 8.8,
489
+ "101011": 7.7,
490
+ "101020": 7.6,
491
+ "101021": 6.7,
492
+ "101100": 8.6,
493
+ "101101": 7.6,
494
+ "101110": 7.4,
495
+ "101111": 5.8,
496
+ "101120": 5.9,
497
+ "101121": 5,
498
+ "101200": 7.2,
499
+ "101201": 5.7,
500
+ "101210": 5.7,
501
+ "101211": 5.2,
502
+ "101220": 5.2,
503
+ "101221": 2.5,
504
+ "102001": 8.3,
505
+ "102011": 7,
506
+ "102021": 5.4,
507
+ "102101": 6.5,
508
+ "102111": 5.8,
509
+ "102121": 2.6,
510
+ "102201": 5.3,
511
+ "102211": 2.1,
512
+ "102221": 1.3,
513
+ "110000": 9.5,
514
+ "110001": 9,
515
+ "110010": 8.8,
516
+ "110011": 7.6,
517
+ "110020": 7.6,
518
+ "110021": 7,
519
+ "110100": 9,
520
+ "110101": 7.7,
521
+ "110110": 7.5,
522
+ "110111": 6.2,
523
+ "110120": 6.1,
524
+ "110121": 5.3,
525
+ "110200": 7.7,
526
+ "110201": 6.6,
527
+ "110210": 6.8,
528
+ "110211": 5.9,
529
+ "110220": 5.2,
530
+ "110221": 3,
531
+ "111000": 8.9,
532
+ "111001": 7.8,
533
+ "111010": 7.6,
534
+ "111011": 6.7,
535
+ "111020": 6.2,
536
+ "111021": 5.8,
537
+ "111100": 7.4,
538
+ "111101": 5.9,
539
+ "111110": 5.7,
540
+ "111111": 5.7,
541
+ "111120": 4.7,
542
+ "111121": 2.3,
543
+ "111200": 6.1,
544
+ "111201": 5.2,
545
+ "111210": 5.7,
546
+ "111211": 2.9,
547
+ "111220": 2.4,
548
+ "111221": 1.6,
549
+ "112001": 7.1,
550
+ "112011": 5.9,
551
+ "112021": 3,
552
+ "112101": 5.8,
553
+ "112111": 2.6,
554
+ "112121": 1.5,
555
+ "112201": 2.3,
556
+ "112211": 1.3,
557
+ "112221": 0.6,
558
+ "200000": 9.3,
559
+ "200001": 8.7,
560
+ "200010": 8.6,
561
+ "200011": 7.2,
562
+ "200020": 7.5,
563
+ "200021": 5.8,
564
+ "200100": 8.6,
565
+ "200101": 7.4,
566
+ "200110": 7.4,
567
+ "200111": 6.1,
568
+ "200120": 5.6,
569
+ "200121": 3.4,
570
+ "200200": 7,
571
+ "200201": 5.4,
572
+ "200210": 5.2,
573
+ "200211": 4,
574
+ "200220": 4,
575
+ "200221": 2.2,
576
+ "201000": 8.5,
577
+ "201001": 7.5,
578
+ "201010": 7.4,
579
+ "201011": 5.5,
580
+ "201020": 6.2,
581
+ "201021": 5.1,
582
+ "201100": 7.2,
583
+ "201101": 5.7,
584
+ "201110": 5.5,
585
+ "201111": 4.1,
586
+ "201120": 4.6,
587
+ "201121": 1.9,
588
+ "201200": 5.3,
589
+ "201201": 3.6,
590
+ "201210": 3.4,
591
+ "201211": 1.9,
592
+ "201220": 1.9,
593
+ "201221": 0.8,
594
+ "202001": 6.4,
595
+ "202011": 5.1,
596
+ "202021": 2,
597
+ "202101": 4.7,
598
+ "202111": 2.1,
599
+ "202121": 1.1,
600
+ "202201": 2.4,
601
+ "202211": 0.9,
602
+ "202221": 0.4,
603
+ "210000": 8.8,
604
+ "210001": 7.5,
605
+ "210010": 7.3,
606
+ "210011": 5.3,
607
+ "210020": 6,
608
+ "210021": 5,
609
+ "210100": 7.3,
610
+ "210101": 5.5,
611
+ "210110": 5.9,
612
+ "210111": 4,
613
+ "210120": 4.1,
614
+ "210121": 2,
615
+ "210200": 5.4,
616
+ "210201": 4.3,
617
+ "210210": 4.5,
618
+ "210211": 2.2,
619
+ "210220": 2,
620
+ "210221": 1.1,
621
+ "211000": 7.5,
622
+ "211001": 5.5,
623
+ "211010": 5.8,
624
+ "211011": 4.5,
625
+ "211020": 4,
626
+ "211021": 2.1,
627
+ "211100": 6.1,
628
+ "211101": 5.1,
629
+ "211110": 4.8,
630
+ "211111": 1.8,
631
+ "211120": 2,
632
+ "211121": 0.9,
633
+ "211200": 4.6,
634
+ "211201": 1.8,
635
+ "211210": 1.7,
636
+ "211211": 0.7,
637
+ "211220": 0.8,
638
+ "211221": 0.2,
639
+ "212001": 5.3,
640
+ "212011": 2.4,
641
+ "212021": 1.4,
642
+ "212101": 2.4,
643
+ "212111": 1.2,
644
+ "212121": 0.5,
645
+ "212201": 1,
646
+ "212211": 0.3,
647
+ "212221": 0.1
648
+ };
649
+ var CVSS40_MAX_COMPOSED = {
650
+ eq1: {
651
+ 0: ["AV:N/PR:N/UI:N/"],
652
+ 1: ["AV:A/PR:N/UI:N/", "AV:N/PR:L/UI:N/", "AV:N/PR:N/UI:P/"],
653
+ 2: ["AV:P/PR:N/UI:N/", "AV:A/PR:L/UI:P/"]
654
+ },
655
+ eq2: {
656
+ 0: ["AC:L/AT:N/"],
657
+ 1: ["AC:H/AT:N/", "AC:L/AT:P/"]
658
+ },
659
+ eq3: {
660
+ 0: { "0": ["VC:H/VI:H/VA:H/CR:H/IR:H/AR:H/"], "1": ["VC:H/VI:H/VA:L/CR:M/IR:M/AR:H/", "VC:H/VI:H/VA:H/CR:M/IR:M/AR:M/"] },
661
+ 1: { "0": ["VC:L/VI:H/VA:H/CR:H/IR:H/AR:H/", "VC:H/VI:L/VA:H/CR:H/IR:H/AR:H/"], "1": ["VC:L/VI:H/VA:L/CR:H/IR:M/AR:H/", "VC:L/VI:H/VA:H/CR:H/IR:M/AR:M/", "VC:H/VI:L/VA:H/CR:M/IR:H/AR:M/", "VC:H/VI:L/VA:L/CR:M/IR:H/AR:H/", "VC:L/VI:L/VA:H/CR:H/IR:H/AR:M/"] },
662
+ 2: { "1": ["VC:L/VI:L/VA:L/CR:H/IR:H/AR:H/"] }
663
+ },
664
+ eq4: {
665
+ 0: ["SC:H/SI:S/SA:S/"],
666
+ 1: ["SC:H/SI:H/SA:H/"],
667
+ 2: ["SC:L/SI:L/SA:L/"]
668
+ },
669
+ eq5: {
670
+ 0: ["E:A/"],
671
+ 1: ["E:P/"],
672
+ 2: ["E:U/"]
673
+ }
674
+ };
675
+ var CVSS40_MAX_SEVERITY = {
676
+ eq1: { 0: 1, 1: 4, 2: 5 },
677
+ eq2: { 0: 1, 1: 2 },
678
+ eq3eq6: { 0: { 0: 7, 1: 6 }, 1: { 0: 8, 1: 8 }, 2: { 1: 10 } },
679
+ eq4: { 0: 6, 1: 5, 2: 4 },
680
+ eq5: { 0: 1, 1: 1, 2: 1 }
681
+ };
682
+ function m4(sel, metric) {
683
+ const selected = sel[metric];
684
+ if (metric === "E" && (selected === void 0 || selected === "X"))
685
+ return "A";
686
+ if ((metric === "CR" || metric === "IR" || metric === "AR") && (selected === void 0 || selected === "X")) {
687
+ return "H";
688
+ }
689
+ const modified = sel["M" + metric];
690
+ if (modified !== void 0 && modified !== "X")
691
+ return modified;
692
+ return selected ?? "";
693
+ }
694
+ function cvss4MacroVector(sel) {
695
+ let eq1;
696
+ if (m4(sel, "AV") === "N" && m4(sel, "PR") === "N" && m4(sel, "UI") === "N") {
697
+ eq1 = "0";
698
+ } else if ((m4(sel, "AV") === "N" || m4(sel, "PR") === "N" || m4(sel, "UI") === "N") && !(m4(sel, "AV") === "N" && m4(sel, "PR") === "N" && m4(sel, "UI") === "N") && m4(sel, "AV") !== "P") {
699
+ eq1 = "1";
700
+ } else {
701
+ eq1 = "2";
702
+ }
703
+ const eq2 = m4(sel, "AC") === "L" && m4(sel, "AT") === "N" ? "0" : "1";
704
+ let eq3;
705
+ if (m4(sel, "VC") === "H" && m4(sel, "VI") === "H") {
706
+ eq3 = "0";
707
+ } else if (!(m4(sel, "VC") === "H" && m4(sel, "VI") === "H") && (m4(sel, "VC") === "H" || m4(sel, "VI") === "H" || m4(sel, "VA") === "H")) {
708
+ eq3 = "1";
709
+ } else {
710
+ eq3 = "2";
711
+ }
712
+ let eq4;
713
+ if (m4(sel, "MSI") === "S" || m4(sel, "MSA") === "S") {
714
+ eq4 = "0";
715
+ } else if (m4(sel, "SC") === "H" || m4(sel, "SI") === "H" || m4(sel, "SA") === "H") {
716
+ eq4 = "1";
717
+ } else {
718
+ eq4 = "2";
719
+ }
720
+ let eq5;
721
+ if (m4(sel, "E") === "A")
722
+ eq5 = "0";
723
+ else if (m4(sel, "E") === "P")
724
+ eq5 = "1";
725
+ else
726
+ eq5 = "2";
727
+ const eq6 = m4(sel, "CR") === "H" && m4(sel, "VC") === "H" || m4(sel, "IR") === "H" && m4(sel, "VI") === "H" || m4(sel, "AR") === "H" && m4(sel, "VA") === "H" ? "0" : "1";
728
+ return eq1 + eq2 + eq3 + eq4 + eq5 + eq6;
729
+ }
730
+ function cvss4EqMaxes(macro, eq) {
731
+ const idx = Number(macro[eq - 1]);
732
+ if (eq === 1)
733
+ return CVSS40_MAX_COMPOSED.eq1[idx];
734
+ if (eq === 2)
735
+ return CVSS40_MAX_COMPOSED.eq2[idx];
736
+ if (eq === 4)
737
+ return CVSS40_MAX_COMPOSED.eq4[idx];
738
+ return CVSS40_MAX_COMPOSED.eq5[idx];
739
+ }
740
+ function extractValueMetric(metric, str) {
741
+ const start = str.indexOf(metric) + metric.length + 1;
742
+ const extracted = str.slice(start);
743
+ const slash = extracted.indexOf("/");
744
+ return slash > 0 ? extracted.substring(0, slash) : extracted;
745
+ }
746
+ function computeCvss4BaseScore(sel) {
747
+ if (["VC", "VI", "VA", "SC", "SI", "SA"].every((metric) => m4(sel, metric) === "N")) {
748
+ return 0;
749
+ }
750
+ const macroVectorResult = cvss4MacroVector(sel);
751
+ let value = CVSS40_LOOKUP[macroVectorResult];
752
+ const eq1 = parseInt(macroVectorResult[0], 10);
753
+ const eq2 = parseInt(macroVectorResult[1], 10);
754
+ const eq3 = parseInt(macroVectorResult[2], 10);
755
+ const eq4 = parseInt(macroVectorResult[3], 10);
756
+ const eq5 = parseInt(macroVectorResult[4], 10);
757
+ const eq6 = parseInt(macroVectorResult[5], 10);
758
+ const eq1_next_lower_macro = `${eq1 + 1}${eq2}${eq3}${eq4}${eq5}${eq6}`;
759
+ const eq2_next_lower_macro = `${eq1}${eq2 + 1}${eq3}${eq4}${eq5}${eq6}`;
760
+ let eq3eq6_next_lower_macro = "";
761
+ let eq3eq6_next_lower_macro_left = "";
762
+ let eq3eq6_next_lower_macro_right = "";
763
+ if (eq3 === 1 && eq6 === 1) {
764
+ eq3eq6_next_lower_macro = `${eq1}${eq2}${eq3 + 1}${eq4}${eq5}${eq6}`;
765
+ } else if (eq3 === 0 && eq6 === 1) {
766
+ eq3eq6_next_lower_macro = `${eq1}${eq2}${eq3 + 1}${eq4}${eq5}${eq6}`;
767
+ } else if (eq3 === 1 && eq6 === 0) {
768
+ eq3eq6_next_lower_macro = `${eq1}${eq2}${eq3}${eq4}${eq5}${eq6 + 1}`;
769
+ } else if (eq3 === 0 && eq6 === 0) {
770
+ eq3eq6_next_lower_macro_left = `${eq1}${eq2}${eq3}${eq4}${eq5}${eq6 + 1}`;
771
+ eq3eq6_next_lower_macro_right = `${eq1}${eq2}${eq3 + 1}${eq4}${eq5}${eq6}`;
772
+ } else {
773
+ eq3eq6_next_lower_macro = `${eq1}${eq2}${eq3 + 1}${eq4}${eq5}${eq6 + 1}`;
774
+ }
775
+ const eq4_next_lower_macro = `${eq1}${eq2}${eq3}${eq4 + 1}${eq5}${eq6}`;
776
+ const eq5_next_lower_macro = `${eq1}${eq2}${eq3}${eq4}${eq5 + 1}${eq6}`;
777
+ const score_eq1_next_lower_macro = CVSS40_LOOKUP[eq1_next_lower_macro];
778
+ const score_eq2_next_lower_macro = CVSS40_LOOKUP[eq2_next_lower_macro];
779
+ let score_eq3eq6_next_lower_macro;
780
+ if (eq3 === 0 && eq6 === 0) {
781
+ const left = CVSS40_LOOKUP[eq3eq6_next_lower_macro_left];
782
+ const right = CVSS40_LOOKUP[eq3eq6_next_lower_macro_right];
783
+ score_eq3eq6_next_lower_macro = left > right ? left : right;
784
+ } else {
785
+ score_eq3eq6_next_lower_macro = CVSS40_LOOKUP[eq3eq6_next_lower_macro];
786
+ }
787
+ const score_eq4_next_lower_macro = CVSS40_LOOKUP[eq4_next_lower_macro];
788
+ const score_eq5_next_lower_macro = CVSS40_LOOKUP[eq5_next_lower_macro];
789
+ const eq1_maxes = cvss4EqMaxes(macroVectorResult, 1);
790
+ const eq2_maxes = cvss4EqMaxes(macroVectorResult, 2);
791
+ const eq3_eq6_maxes = CVSS40_MAX_COMPOSED.eq3[eq3][macroVectorResult[5]];
792
+ const eq4_maxes = cvss4EqMaxes(macroVectorResult, 4);
793
+ const eq5_maxes = cvss4EqMaxes(macroVectorResult, 5);
794
+ const max_vectors = [];
795
+ for (const a of eq1_maxes)
796
+ for (const b of eq2_maxes)
797
+ for (const c of eq3_eq6_maxes)
798
+ for (const d of eq4_maxes)
799
+ for (const e of eq5_maxes)
800
+ max_vectors.push(a + b + c + d + e);
801
+ let severity_distance_AV = 0, severity_distance_PR = 0, severity_distance_UI = 0;
802
+ let severity_distance_AC = 0, severity_distance_AT = 0;
803
+ let severity_distance_VC = 0, severity_distance_VI = 0, severity_distance_VA = 0;
804
+ let severity_distance_SC = 0, severity_distance_SI = 0, severity_distance_SA = 0;
805
+ let severity_distance_CR = 0, severity_distance_IR = 0, severity_distance_AR = 0;
806
+ for (const max_vector of max_vectors) {
807
+ severity_distance_AV = AV_levels[m4(sel, "AV")] - AV_levels[extractValueMetric("AV", max_vector)];
808
+ severity_distance_PR = PR_levels[m4(sel, "PR")] - PR_levels[extractValueMetric("PR", max_vector)];
809
+ severity_distance_UI = UI_levels[m4(sel, "UI")] - UI_levels[extractValueMetric("UI", max_vector)];
810
+ severity_distance_AC = AC_levels[m4(sel, "AC")] - AC_levels[extractValueMetric("AC", max_vector)];
811
+ severity_distance_AT = AT_levels[m4(sel, "AT")] - AT_levels[extractValueMetric("AT", max_vector)];
812
+ severity_distance_VC = VC_levels[m4(sel, "VC")] - VC_levels[extractValueMetric("VC", max_vector)];
813
+ severity_distance_VI = VI_levels[m4(sel, "VI")] - VI_levels[extractValueMetric("VI", max_vector)];
814
+ severity_distance_VA = VA_levels[m4(sel, "VA")] - VA_levels[extractValueMetric("VA", max_vector)];
815
+ severity_distance_SC = SC_levels[m4(sel, "SC")] - SC_levels[extractValueMetric("SC", max_vector)];
816
+ severity_distance_SI = SI_levels[m4(sel, "SI")] - SI_levels[extractValueMetric("SI", max_vector)];
817
+ severity_distance_SA = SA_levels[m4(sel, "SA")] - SA_levels[extractValueMetric("SA", max_vector)];
818
+ severity_distance_CR = CR_levels[m4(sel, "CR")] - CR_levels[extractValueMetric("CR", max_vector)];
819
+ severity_distance_IR = IR_levels[m4(sel, "IR")] - IR_levels[extractValueMetric("IR", max_vector)];
820
+ severity_distance_AR = AR_levels[m4(sel, "AR")] - AR_levels[extractValueMetric("AR", max_vector)];
821
+ const anyNegative = [
822
+ severity_distance_AV,
823
+ severity_distance_PR,
824
+ severity_distance_UI,
825
+ severity_distance_AC,
826
+ severity_distance_AT,
827
+ severity_distance_VC,
828
+ severity_distance_VI,
829
+ severity_distance_VA,
830
+ severity_distance_SC,
831
+ severity_distance_SI,
832
+ severity_distance_SA,
833
+ severity_distance_CR,
834
+ severity_distance_IR,
835
+ severity_distance_AR
836
+ ].some((v) => v < 0);
837
+ if (anyNegative)
838
+ continue;
839
+ break;
840
+ }
841
+ const current_severity_distance_eq1 = severity_distance_AV + severity_distance_PR + severity_distance_UI;
842
+ const current_severity_distance_eq2 = severity_distance_AC + severity_distance_AT;
843
+ const current_severity_distance_eq3eq6 = severity_distance_VC + severity_distance_VI + severity_distance_VA + severity_distance_CR + severity_distance_IR + severity_distance_AR;
844
+ const current_severity_distance_eq4 = severity_distance_SC + severity_distance_SI + severity_distance_SA;
845
+ const step = 0.1;
846
+ const available_distance_eq1 = value - score_eq1_next_lower_macro;
847
+ const available_distance_eq2 = value - score_eq2_next_lower_macro;
848
+ const available_distance_eq3eq6 = value - score_eq3eq6_next_lower_macro;
849
+ const available_distance_eq4 = value - score_eq4_next_lower_macro;
850
+ const available_distance_eq5 = value - score_eq5_next_lower_macro;
851
+ let n_existing_lower = 0;
852
+ let normalized_severity_eq1 = 0;
853
+ let normalized_severity_eq2 = 0;
854
+ let normalized_severity_eq3eq6 = 0;
855
+ let normalized_severity_eq4 = 0;
856
+ let normalized_severity_eq5 = 0;
857
+ const maxSeverity_eq1 = CVSS40_MAX_SEVERITY.eq1[eq1] * step;
858
+ const maxSeverity_eq2 = CVSS40_MAX_SEVERITY.eq2[eq2] * step;
859
+ const maxSeverity_eq3eq6 = CVSS40_MAX_SEVERITY.eq3eq6[eq3][eq6] * step;
860
+ const maxSeverity_eq4 = CVSS40_MAX_SEVERITY.eq4[eq4] * step;
861
+ if (!Number.isNaN(available_distance_eq1)) {
862
+ n_existing_lower += 1;
863
+ normalized_severity_eq1 = available_distance_eq1 * (current_severity_distance_eq1 / maxSeverity_eq1);
864
+ }
865
+ if (!Number.isNaN(available_distance_eq2)) {
866
+ n_existing_lower += 1;
867
+ normalized_severity_eq2 = available_distance_eq2 * (current_severity_distance_eq2 / maxSeverity_eq2);
868
+ }
869
+ if (!Number.isNaN(available_distance_eq3eq6)) {
870
+ n_existing_lower += 1;
871
+ normalized_severity_eq3eq6 = available_distance_eq3eq6 * (current_severity_distance_eq3eq6 / maxSeverity_eq3eq6);
872
+ }
873
+ if (!Number.isNaN(available_distance_eq4)) {
874
+ n_existing_lower += 1;
875
+ normalized_severity_eq4 = available_distance_eq4 * (current_severity_distance_eq4 / maxSeverity_eq4);
876
+ }
877
+ if (!Number.isNaN(available_distance_eq5)) {
878
+ n_existing_lower += 1;
879
+ normalized_severity_eq5 = available_distance_eq5 * 0;
880
+ }
881
+ let mean_distance;
882
+ if (n_existing_lower === 0) {
883
+ mean_distance = 0;
884
+ } else {
885
+ mean_distance = (normalized_severity_eq1 + normalized_severity_eq2 + normalized_severity_eq3eq6 + normalized_severity_eq4 + normalized_severity_eq5) / n_existing_lower;
886
+ }
887
+ value -= mean_distance;
888
+ if (value < 0)
889
+ value = 0;
890
+ if (value > 10)
891
+ value = 10;
892
+ return Math.round(value * 10) / 10;
893
+ }
894
+ function cvss4Severity(score) {
895
+ if (score <= 0)
896
+ return "None";
897
+ if (score < 4)
898
+ return "Low";
899
+ if (score < 7)
900
+ return "Medium";
901
+ if (score < 9)
902
+ return "High";
903
+ return "Critical";
904
+ }
905
+ var CVSS4_METRIC_ORDER = [
906
+ "AV",
907
+ "AC",
908
+ "AT",
909
+ "PR",
910
+ "UI",
911
+ "VC",
912
+ "VI",
913
+ "VA",
914
+ "SC",
915
+ "SI",
916
+ "SA",
917
+ "E",
918
+ "CR",
919
+ "IR",
920
+ "AR",
921
+ "MAV",
922
+ "MAC",
923
+ "MAT",
924
+ "MPR",
925
+ "MUI",
926
+ "MVC",
927
+ "MVI",
928
+ "MVA",
929
+ "MSC",
930
+ "MSI",
931
+ "MSA",
932
+ "S",
933
+ "AU",
934
+ "R",
935
+ "V",
936
+ "RE",
937
+ "U"
938
+ ];
939
+ function parseCvss4Vector(vector) {
940
+ const trimmed = vector.trim();
941
+ if (!trimmed.startsWith("CVSS:4.0/")) {
942
+ throw new Cvss4ParseError(`Not a CVSS 4.0 vector (must start with "CVSS:4.0/"): ${vector}`);
943
+ }
944
+ const body = trimmed.slice("CVSS:4.0/".length);
945
+ const parts = body.split("/").filter((p) => p.length > 0);
946
+ if (parts.length === 0) {
947
+ throw new Cvss4ParseError(`CVSS 4.0 vector has no metrics: ${vector}`);
948
+ }
949
+ const sel = {};
950
+ for (const part of parts) {
951
+ const eq = part.indexOf(":");
952
+ if (eq < 0)
953
+ throw new Cvss4ParseError(`Malformed metric segment "${part}" in ${vector}`);
954
+ const key = part.slice(0, eq);
955
+ const val = part.slice(eq + 1);
956
+ const allowed = CVSS4_ALLOWED[key];
957
+ if (!allowed)
958
+ throw new Cvss4ParseError(`Unknown CVSS 4.0 metric "${key}" in ${vector}`);
959
+ if (!allowed.has(val)) {
960
+ throw new Cvss4ParseError(`Illegal value "${val}" for metric "${key}" in ${vector}`);
961
+ }
962
+ if (key in sel)
963
+ throw new Cvss4ParseError(`Duplicate metric "${key}" in ${vector}`);
964
+ sel[key] = val;
965
+ }
966
+ for (const base of CVSS4_BASE_KEYS) {
967
+ if (!(base in sel)) {
968
+ throw new Cvss4ParseError(`Missing mandatory base metric "${base}" in ${vector}`);
969
+ }
970
+ }
971
+ return sel;
972
+ }
973
+ function formatCvss4Vector(sel) {
974
+ const segs = [];
975
+ for (const key of CVSS4_METRIC_ORDER) {
976
+ const v = sel[key];
977
+ if (v !== void 0 && v !== "X")
978
+ segs.push(`${key}:${v}`);
979
+ }
980
+ return `CVSS:4.0/${segs.join("/")}`;
981
+ }
982
+ function scoreCvss4Vector(vector) {
983
+ const sel = parseCvss4Vector(vector);
984
+ const score = computeCvss4BaseScore(sel);
985
+ return {
986
+ vector: formatCvss4Vector(sel),
987
+ score,
988
+ severity: cvss4Severity(score),
989
+ macroVector: cvss4MacroVector(sel)
990
+ };
991
+ }
992
+ function cvss4MetricsForReachability(tier) {
993
+ switch (tier) {
994
+ case "remote-unauth":
995
+ return { AV: "N", AT: "N", PR: "N", UI: "N" };
996
+ case "remote-auth":
997
+ return { AV: "N", AT: "N", PR: "L", UI: "N" };
998
+ case "proximity-rf":
999
+ return { AV: "A", AT: "N", PR: "N", UI: "N" };
1000
+ case "local-unpriv":
1001
+ return { AV: "L", AT: "N", PR: "L", UI: "N" };
1002
+ case "local-priv":
1003
+ return { AV: "L", AT: "N", PR: "H", UI: "N" };
1004
+ case "needs-hardware":
1005
+ return { AV: "P", AT: "N", PR: "N", UI: "N" };
1006
+ case "needs-host-migration":
1007
+ return { AV: "L", AT: "N", PR: "N", UI: "A" };
1008
+ }
1009
+ }
1010
+ function suggestCvss4(finding) {
1011
+ const impact = IMPACT_BY_CATEGORY[finding.category] ?? { C: "L", I: "L", A: "L", scope: "U" };
1012
+ const assessed = finding.impactAssessment ? cvss4MetricsForReachability(finding.impactAssessment.reachability_tier) : void 0;
1013
+ const AV = assessed?.AV ?? "N";
1014
+ const AT = assessed?.AT ?? "N";
1015
+ const pr31 = assessed ? assessed.PR : prForSeverity(finding.severity);
1016
+ const UI = assessed?.UI ?? "N";
1017
+ const subsequent = impact.scope === "C";
1018
+ const sel = {
1019
+ AV,
1020
+ AC: "L",
1021
+ AT,
1022
+ PR: pr31,
1023
+ UI,
1024
+ VC: impact.C,
1025
+ VI: impact.I,
1026
+ VA: impact.A,
1027
+ SC: subsequent ? impact.C : "N",
1028
+ SI: subsequent ? impact.I : "N",
1029
+ SA: subsequent ? impact.A : "N"
1030
+ };
1031
+ const score = computeCvss4BaseScore(sel);
1032
+ return {
1033
+ vector: formatCvss4Vector(sel),
1034
+ score,
1035
+ severity: cvss4Severity(score),
1036
+ source: assessed ? "impact-assessment" : "heuristic"
1037
+ };
1038
+ }
1039
+ function renderCvssSection(opts) {
1040
+ const version = opts.vector.startsWith("CVSS:4.0/") ? "4.0" : opts.vector.startsWith("CVSS:3.1/") ? "3.1" : opts.vector.startsWith("CVSS:3.0/") ? "3.0" : void 0;
1041
+ const label = version ? `CVSS ${version}` : "CVSS";
1042
+ const rating = opts.severity ? ` (${opts.severity})` : "";
1043
+ return `**${label}: ${opts.score.toFixed(1)}${rating}** \u2014 \`${opts.vector}\``;
1044
+ }
1045
+
1046
+ // packages/core/dist/disclose/canary.js
1047
+ import { execFileSync } from "node:child_process";
1048
+ import { existsSync, readFileSync } from "node:fs";
1049
+ import { resolve, join } from "node:path";
1050
+ function extractFileRefs(finding) {
1051
+ const haystack = [
1052
+ finding.description,
1053
+ finding.evidence?.analysis,
1054
+ finding.evidence?.request,
1055
+ finding.evidence?.response
1056
+ ].filter((s) => typeof s === "string" && s.length > 0).join("\n\n");
1057
+ const seen = /* @__PURE__ */ new Map();
1058
+ const regex = /(?<![\w/\-:])([a-zA-Z0-9_./\-]+\.(?:ts|tsx|js|jsx|mjs|cjs|py|rb|go|rs|c|h|cc|cpp|java|kt|swift|php|sh|sql))(?::(\d+)(?:-\d+)?)?/g;
1059
+ let match;
1060
+ while ((match = regex.exec(haystack)) !== null) {
1061
+ const file = match[1];
1062
+ const line = match[2] ? Number(match[2]) : void 0;
1063
+ if (file.startsWith("http:") || file.startsWith("https:"))
1064
+ continue;
1065
+ const key = `${file}:${line ?? ""}`;
1066
+ if (!seen.has(key))
1067
+ seen.set(key, { file, line });
1068
+ }
1069
+ return Array.from(seen.values());
1070
+ }
1071
+ function gitCmd(repoPath, args) {
1072
+ try {
1073
+ return execFileSync("git", args, { cwd: repoPath, stdio: ["ignore", "pipe", "pipe"], encoding: "utf8" });
1074
+ } catch {
1075
+ return null;
1076
+ }
1077
+ }
1078
+ function verifyAgainstRef(finding, options) {
1079
+ const refs = extractFileRefs(finding);
1080
+ const repoPath = resolve(options.repoPath);
1081
+ if (options.checkout && options.ref) {
1082
+ gitCmd(repoPath, ["checkout", "-q", options.ref]);
1083
+ }
1084
+ const currentRef = options.ref ?? gitCmd(repoPath, ["rev-parse", "--abbrev-ref", "HEAD"])?.trim() ?? gitCmd(repoPath, ["rev-parse", "--short", "HEAD"])?.trim() ?? "HEAD";
1085
+ if (refs.length === 0) {
1086
+ return {
1087
+ status: "unknown",
1088
+ ref: currentRef,
1089
+ notes: ["Could not extract any file:line references from the finding. Consider adding `server/src/.../file.ts:NNN` style citations to the description before re-running."],
1090
+ refsChecked: [],
1091
+ refsStillPresent: [],
1092
+ refsMissing: []
1093
+ };
1094
+ }
1095
+ const notes = [];
1096
+ const refsStillPresent = [];
1097
+ const refsMissing = [];
1098
+ for (const ref of refs) {
1099
+ const abs = join(repoPath, ref.file);
1100
+ if (!existsSync(abs)) {
1101
+ refsMissing.push(ref);
1102
+ notes.push(`${ref.file} \u2014 file does not exist at ${currentRef}.`);
1103
+ continue;
1104
+ }
1105
+ if (ref.line !== void 0) {
1106
+ try {
1107
+ const content = readFileSync(abs, "utf8").split("\n");
1108
+ if (ref.line > content.length) {
1109
+ refsMissing.push(ref);
1110
+ notes.push(`${ref.file}:${ref.line} \u2014 line is out of range (file has ${content.length} lines at ${currentRef}).`);
1111
+ continue;
1112
+ }
1113
+ } catch {
1114
+ }
1115
+ }
1116
+ refsStillPresent.push(ref);
1117
+ }
1118
+ let status;
1119
+ if (refsStillPresent.length === 0) {
1120
+ status = refsMissing.some((r) => !existsSync(join(repoPath, r.file))) ? "file-removed" : "fixed";
1121
+ } else if (refsMissing.length === 0) {
1122
+ status = "still-vulnerable";
1123
+ } else {
1124
+ status = "partial-fix";
1125
+ }
1126
+ if (status === "still-vulnerable") {
1127
+ notes.unshift(`All ${refsStillPresent.length} cited file${refsStillPresent.length === 1 ? "" : "s"} still resolve at ${currentRef}. Status is conservative \u2014 a human should confirm the *shape* of the code at each line hasn't been patched.`);
1128
+ }
1129
+ return {
1130
+ status,
1131
+ ref: currentRef,
1132
+ notes,
1133
+ refsChecked: refs,
1134
+ refsStillPresent,
1135
+ refsMissing
1136
+ };
1137
+ }
1138
+ function refsMatch(a, b) {
1139
+ return a.file === b.file && a.line === b.line;
1140
+ }
1141
+ function formatPatchStatusSection(result) {
1142
+ const banner = {
1143
+ "still-vulnerable": `**Still vulnerable** on \`${result.ref}\`.`,
1144
+ "partial-fix": `**Partial fix** on \`${result.ref}\` \u2014 some cited references changed, others remain.`,
1145
+ "fixed": `**Fixed** on \`${result.ref}\`. All cited references have been edited or removed upstream.`,
1146
+ "file-removed": `**Vulnerable file removed** on \`${result.ref}\`. The affected path no longer exists in the tree.`,
1147
+ "unknown": `**Could not auto-verify** against \`${result.ref}\`. No machine-checkable references were extractable from the finding.`
1148
+ };
1149
+ const lines = [];
1150
+ lines.push(banner[result.status]);
1151
+ if (result.refsChecked.length > 0) {
1152
+ lines.push("");
1153
+ lines.push(`Refs checked (${result.refsChecked.length}):`);
1154
+ for (const ref of result.refsChecked) {
1155
+ const present = result.refsStillPresent.some((r) => refsMatch(r, ref));
1156
+ const marker = present ? "\u2713" : "\u2717";
1157
+ lines.push(`- ${marker} \`${ref.file}${ref.line ? `:${ref.line}` : ""}\``);
1158
+ }
1159
+ }
1160
+ if (result.notes.length > 0) {
1161
+ lines.push("");
1162
+ for (const note of result.notes)
1163
+ lines.push(`> ${note}`);
1164
+ }
1165
+ return lines.join("\n");
1166
+ }
1167
+
1168
+ // packages/core/dist/disclose/version-range.js
1169
+ import { execFileSync as execFileSync2 } from "node:child_process";
1170
+ import { resolve as resolve2 } from "node:path";
1171
+ function gitCmd2(repoPath, args) {
1172
+ try {
1173
+ return execFileSync2("git", args, {
1174
+ cwd: repoPath,
1175
+ stdio: ["ignore", "pipe", "pipe"],
1176
+ encoding: "utf8",
1177
+ maxBuffer: 4 * 1024 * 1024
1178
+ }).trim();
1179
+ } catch {
1180
+ return null;
1181
+ }
1182
+ }
1183
+ function listTags(repoPath, limit, glob) {
1184
+ const baseArgs = ["tag"];
1185
+ if (glob)
1186
+ baseArgs.push("-l", glob);
1187
+ const byVersion = gitCmd2(repoPath, [...baseArgs, "--sort=-v:refname"]);
1188
+ if (byVersion && byVersion.length > 0) {
1189
+ return byVersion.split("\n").filter(Boolean).slice(0, limit);
1190
+ }
1191
+ const byDate = gitCmd2(repoPath, [...baseArgs, "--sort=-creatordate"]);
1192
+ if (!byDate)
1193
+ return [];
1194
+ return byDate.split("\n").filter(Boolean).slice(0, limit);
1195
+ }
1196
+ function fileExistsAtRef(repoPath, ref, filePath) {
1197
+ const out = gitCmd2(repoPath, ["cat-file", "-e", `${ref}:${filePath}`]);
1198
+ return out !== null;
1199
+ }
1200
+ function lineExistsAtRef(repoPath, ref, filePath, line) {
1201
+ const content = gitCmd2(repoPath, ["show", `${ref}:${filePath}`]);
1202
+ if (content === null)
1203
+ return false;
1204
+ const lineCount = content.split("\n").length;
1205
+ return line <= lineCount;
1206
+ }
1207
+ function findingPresentAtRef(repoPath, ref, refs) {
1208
+ if (refs.length === 0)
1209
+ return false;
1210
+ for (const r of refs) {
1211
+ if (!fileExistsAtRef(repoPath, ref, r.file))
1212
+ return false;
1213
+ if (r.line !== void 0 && !lineExistsAtRef(repoPath, ref, r.file, r.line))
1214
+ return false;
1215
+ }
1216
+ return true;
1217
+ }
1218
+ function detectVersionRange(finding, options) {
1219
+ const repoPath = resolve2(options.repoPath);
1220
+ const tagLimit = options.tagLimit ?? 30;
1221
+ const refs = extractFileRefs(finding);
1222
+ const notes = [];
1223
+ if (refs.length === 0) {
1224
+ return {
1225
+ affectedTags: [],
1226
+ presentOnHead: false,
1227
+ status: "indeterminate",
1228
+ notes: ["Could not extract file:line references from the finding. Add explicit `path/to/file.ts:NNN` citations to the description and re-run."]
1229
+ };
1230
+ }
1231
+ const tags = listTags(repoPath, tagLimit, options.tagGlob);
1232
+ const presentOnHead = findingPresentAtRef(repoPath, "HEAD", refs);
1233
+ if (tags.length === 0) {
1234
+ notes.push(`No tags found in ${repoPath}${options.tagGlob ? ` matching '${options.tagGlob}'` : ""}.`);
1235
+ return {
1236
+ affectedTags: [],
1237
+ presentOnHead,
1238
+ status: "no-tags",
1239
+ notes
1240
+ };
1241
+ }
1242
+ const classified = tags.map((tag) => ({
1243
+ tag,
1244
+ present: findingPresentAtRef(repoPath, tag, refs)
1245
+ }));
1246
+ const affectedTags = classified.filter((c) => c.present).map((c) => c.tag);
1247
+ const introducedIn = affectedTags[affectedTags.length - 1];
1248
+ let fixedIn;
1249
+ const firstPresentIdx = classified.findIndex((c) => c.present);
1250
+ if (firstPresentIdx > 0) {
1251
+ fixedIn = classified[firstPresentIdx - 1]?.tag;
1252
+ }
1253
+ let status;
1254
+ if (presentOnHead)
1255
+ status = "present-on-head";
1256
+ else if (affectedTags.length > 0)
1257
+ status = "removed-upstream";
1258
+ else
1259
+ status = "indeterminate";
1260
+ if (affectedTags.length === tagLimit) {
1261
+ notes.push(`Hit the ${tagLimit}-tag walk limit \u2014 the introducing tag may be older than reported. Pass --tag-limit to extend.`);
1262
+ }
1263
+ return {
1264
+ affectedTags,
1265
+ introducedIn,
1266
+ fixedIn,
1267
+ presentOnHead,
1268
+ status,
1269
+ notes
1270
+ };
1271
+ }
1272
+ function formatVersionRangeLine(result) {
1273
+ switch (result.status) {
1274
+ case "present-on-head":
1275
+ if (result.introducedIn) {
1276
+ return `\`>= ${result.introducedIn}\`, including the repo's current \`HEAD\`. Confirmed on: ${result.affectedTags.map((t) => "`" + t + "`").join(", ")}.`;
1277
+ }
1278
+ return "Present on the repo's current `HEAD` (no tagged introduction point detected).";
1279
+ case "removed-upstream":
1280
+ if (result.introducedIn && result.fixedIn) {
1281
+ return `\`>= ${result.introducedIn}\`, \`< ${result.fixedIn}\`. Confirmed affected: ${result.affectedTags.map((t) => "`" + t + "`").join(", ")}. Fixed from \`${result.fixedIn}\` onward.`;
1282
+ }
1283
+ if (result.introducedIn) {
1284
+ return `\`>= ${result.introducedIn}\`. Confirmed affected: ${result.affectedTags.map((t) => "`" + t + "`").join(", ")}. Fixed upstream at HEAD.`;
1285
+ }
1286
+ return "Removed upstream since the last release.";
1287
+ case "no-tags":
1288
+ return "_No release tags available in the target repo to infer a range._";
1289
+ case "indeterminate":
1290
+ default:
1291
+ return "_Could not auto-detect a version range \u2014 add file:line citations to the finding and re-run._";
1292
+ }
1293
+ }
1294
+
1295
+ // packages/core/dist/disclose/template.js
1296
+ var EmptyPocError = class extends Error {
1297
+ findingId;
1298
+ constructor(findingId) {
1299
+ super(`Finding ${findingId} has no PoC content (pocSteps, evidence, or screenshots) \u2014 refusing to render advisory.`);
1300
+ this.name = "EmptyPocError";
1301
+ this.findingId = findingId;
1302
+ }
1303
+ };
1304
+ var SENSITIVE_HEADER_NAMES = /* @__PURE__ */ new Set([
1305
+ "authorization",
1306
+ "proxy-authorization",
1307
+ "cookie",
1308
+ "set-cookie",
1309
+ "x-auth-token",
1310
+ "x-api-key",
1311
+ "x-csrf-token",
1312
+ "x-xsrf-token"
1313
+ ]);
1314
+ var AWS_KEY_RE = /\bAKIA[0-9A-Z]{16}\b/g;
1315
+ var JWT_RE = /\b[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+={0,2}\b/g;
1316
+ var INLINE_BEARER_RE = /\b(Bearer)\s+([^\s"'`]+)/gi;
1317
+ var INLINE_CURL_HEADER_RE = /(-H|--header)(\s+|=)(["']?)([A-Za-z][A-Za-z0-9-]*)\s*:\s*([^"'\n]*)\3/gi;
1318
+ function redactSensitiveHeaders(text) {
1319
+ if (!text)
1320
+ return text;
1321
+ let out = redactAuthHeaders(text);
1322
+ out = out.replace(AWS_KEY_RE, "<REDACTED-AWS-KEY>");
1323
+ out = out.replace(JWT_RE, (match) => {
1324
+ if (match.length < 80)
1325
+ return match;
1326
+ return "<REDACTED-JWT>";
1327
+ });
1328
+ return out;
1329
+ }
1330
+ function redactAuthHeaders(text) {
1331
+ if (!text)
1332
+ return text;
1333
+ const lines = text.split("\n");
1334
+ const redactedLines = lines.map((line) => {
1335
+ const m = /^(\s*)([A-Za-z][A-Za-z0-9-]*)\s*:\s*(.*)$/.exec(line);
1336
+ if (m && SENSITIVE_HEADER_NAMES.has(m[2].toLowerCase())) {
1337
+ return `${m[1]}${m[2]}: <REDACTED-${m[2]}>`;
1338
+ }
1339
+ return line;
1340
+ });
1341
+ let out = redactedLines.join("\n");
1342
+ out = out.replace(INLINE_CURL_HEADER_RE, (match, flag, sep, quote, name, _value) => {
1343
+ if (!SENSITIVE_HEADER_NAMES.has(name.toLowerCase()))
1344
+ return match;
1345
+ return `${flag}${sep}${quote}${name}: <REDACTED-${name}>${quote}`;
1346
+ });
1347
+ return out.replace(INLINE_BEARER_RE, "$1 <REDACTED-Bearer>");
1348
+ }
1349
+ function reachabilityLabel(tier) {
1350
+ switch (tier) {
1351
+ case "remote-unauth":
1352
+ return "remote, unauthenticated \u2014 reachable over the network with no credentials";
1353
+ case "remote-auth":
1354
+ return "remote, authenticated \u2014 requires an account or contributor access";
1355
+ case "proximity-rf":
1356
+ return "RF/physical proximity \u2014 attacker must be within radio range (NFC/BLE/Wi-Fi)";
1357
+ case "local-unpriv":
1358
+ return "local, unprivileged \u2014 requires an unprivileged account on the host";
1359
+ case "local-priv":
1360
+ return "local, privileged \u2014 requires an already-privileged local account";
1361
+ case "needs-hardware":
1362
+ return "requires specific or attacker-supplied hardware";
1363
+ case "needs-host-migration":
1364
+ return "requires the victim to mount/import an attacker-supplied artifact";
1365
+ }
1366
+ }
1367
+ function weaponizabilityLabel(w) {
1368
+ switch (w) {
1369
+ case "rce":
1370
+ return "remote code execution";
1371
+ case "lpe-to-root":
1372
+ return "local privilege escalation to root/SYSTEM";
1373
+ case "integrity-tampering":
1374
+ return "workflow integrity manipulation";
1375
+ case "info-leak":
1376
+ return "information disclosure";
1377
+ case "dos-crash":
1378
+ return "denial of service (crash)";
1379
+ }
1380
+ }
1381
+ function severityHeading(severity) {
1382
+ const upper = severity.toUpperCase();
1383
+ return upper === "CRITICAL" || upper === "HIGH" || upper === "MEDIUM" || upper === "LOW" ? upper : severity;
1384
+ }
1385
+ function slugifyTitle(title, max = 80) {
1386
+ return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, max);
1387
+ }
1388
+ function indentEvidenceBlock(raw, lang = "") {
1389
+ const trimmed = raw.trim();
1390
+ if (!trimmed)
1391
+ return "";
1392
+ return "```" + lang + "\n" + trimmed + "\n```";
1393
+ }
1394
+ function renderPocSteps(finding) {
1395
+ if (!finding.pocSteps || finding.pocSteps.length === 0)
1396
+ return [];
1397
+ const lines = ["**Step graph:**", ""];
1398
+ for (const [index, step] of finding.pocSteps.entries()) {
1399
+ lines.push(`${index + 1}. **${step.kind}** \u2014 ${step.summary} _(id: \`${step.id}\`)_`);
1400
+ if (step.action.type === "shell") {
1401
+ lines.push("", indentEvidenceBlock(step.action.cmd, "bash"));
1402
+ } else if (step.action.type === "http") {
1403
+ const method = step.action.method.toUpperCase();
1404
+ lines.push("", indentEvidenceBlock(`${method} ${step.action.url}${step.action.body ? `
1405
+
1406
+ ${step.action.body}` : ""}`, "http"));
1407
+ } else if (step.action.type === "docker") {
1408
+ lines.push("", indentEvidenceBlock(`docker run ${step.action.image} ${step.action.args.join(" ")}`.trim(), "bash"));
1409
+ } else {
1410
+ lines.push("", step.action.text);
1411
+ }
1412
+ if (step.expect) {
1413
+ lines.push("", `Expected result: \`${step.expect.type}\``);
1414
+ }
1415
+ lines.push("");
1416
+ }
1417
+ return lines;
1418
+ }
1419
+ function renderAdvisoryMarkdown(finding, ctx = {}) {
1420
+ const cwes = suggestCwesForCategory(finding.category);
1421
+ const cvss = suggestCvss(finding);
1422
+ const severity = severityHeading(finding.severity);
1423
+ const rank = { critical: "1", high: "2", medium: "3", low: "4", info: "5" };
1424
+ const filenameSlug = slugifyTitle(finding.title);
1425
+ const filename = `${rank[finding.severity] ?? "9"}-${finding.severity}-${filenameSlug}.md`;
1426
+ let affectedLine;
1427
+ if (ctx.versionRange) {
1428
+ affectedLine = formatVersionRangeLine(ctx.versionRange);
1429
+ } else if (ctx.target) {
1430
+ affectedLine = `\`${ctx.target}\`${ctx.targetRef ? ` at \`${ctx.targetRef}\`` : ""}${ctx.commitHash ? ` (commit \`${ctx.commitHash.slice(0, 12)}\`)` : ""}`;
1431
+ } else {
1432
+ affectedLine = "_Pass `--repo <path>` to `@0/cli disclose` to auto-detect the affected version range from git tags._";
1433
+ }
1434
+ const cvssSource = cvss.source === "finding" ? "populated on the finding by 0" : cvss.source === "impact-assessment" ? "exploitability metrics derived from 0's reachability assessment; impact from category \u2014 verify against your deployment" : "heuristic from category + severity \u2014 override in the GHSA editor if the operator disagrees";
1435
+ const remediation = finding.remediation;
1436
+ const suggestedFixParts = [];
1437
+ if (remediation?.summary)
1438
+ suggestedFixParts.push(remediation.summary);
1439
+ if (remediation?.steps?.length) {
1440
+ suggestedFixParts.push(remediation.steps.map((step, i) => `${i + 1}. ${step}`).join("\n"));
1441
+ }
1442
+ if (remediation?.codeExample?.after) {
1443
+ const lang = remediation.codeExample.language || "";
1444
+ suggestedFixParts.push(remediation.codeExample.before ? `**Before:**
1445
+
1446
+ \`\`\`${lang}
1447
+ ${remediation.codeExample.before}
1448
+ \`\`\`
1449
+
1450
+ **After:**
1451
+
1452
+ \`\`\`${lang}
1453
+ ${remediation.codeExample.after}
1454
+ \`\`\`` : `\`\`\`${lang}
1455
+ ${remediation.codeExample.after}
1456
+ \`\`\``);
1457
+ } else if (ctx.siblingFix) {
1458
+ const ref = `${ctx.siblingFix.fileRef.file}${ctx.siblingFix.fileRef.line ? `:${ctx.siblingFix.fileRef.line}` : ""}`;
1459
+ suggestedFixParts.push(`**Correct pattern already present in the repo at \`${ref}\`** *(extracted by 0):*
1460
+
1461
+ \`\`\`${ctx.siblingFix.language}
1462
+ ${ctx.siblingFix.snippet}
1463
+ \`\`\``);
1464
+ }
1465
+ const suggestedFix = suggestedFixParts.length > 0 ? suggestedFixParts.join("\n\n") : "_To fill in: copy-paste the correct pattern from a sibling handler in the same repo._";
1466
+ const evidenceAnalysis = finding.evidence?.analysis?.trim() ?? "";
1467
+ const out = [];
1468
+ out.push("# Title", "");
1469
+ out.push(finding.title, "");
1470
+ out.push("# Severity", "");
1471
+ out.push(`**${severity}** \u2014 ${cvss.vector} (~${cvss.score.toFixed(1)})`, "");
1472
+ out.push(`_CVSS source: ${cvssSource}._`, "");
1473
+ const impactAssessment = finding.impactAssessment;
1474
+ if (impactAssessment) {
1475
+ out.push("# Impact", "");
1476
+ out.push(`**Attacker gains:** ${weaponizabilityLabel(impactAssessment.weaponizability)}`, "");
1477
+ out.push(`**Attack prerequisites:** ${reachabilityLabel(impactAssessment.reachability_tier)}`, "");
1478
+ if (impactAssessment.blast_radius) {
1479
+ out.push(`**Blast radius:** ${impactAssessment.blast_radius}`, "");
1480
+ }
1481
+ if (impactAssessment.rationale) {
1482
+ out.push(`_${impactAssessment.rationale}_`, "");
1483
+ }
1484
+ }
1485
+ out.push(formatCweSection(cwes), "");
1486
+ out.push("# Affected versions", "");
1487
+ out.push(affectedLine, "");
1488
+ if (ctx.osecVersion || ctx.scanId) {
1489
+ const bits = [];
1490
+ if (ctx.osecVersion)
1491
+ bits.push(`0 \`${ctx.osecVersion}\``);
1492
+ if (ctx.scanId)
1493
+ bits.push(`scan \`${ctx.scanId.slice(0, 8)}\``);
1494
+ const canaryPositive = ctx.patchStatus?.status === "still-vulnerable";
1495
+ const behaviouralPositive = ctx.pocExecution?.overallVerdict === "exploit_still_works";
1496
+ if (canaryPositive && behaviouralPositive) {
1497
+ out.push(`> Code-verified by ${bits.join(", ")}.`, "");
1498
+ } else {
1499
+ out.push(`_Generated by ${bits.join(", ")}._`, "");
1500
+ }
1501
+ }
1502
+ out.push("## Summary", "");
1503
+ out.push(finding.description.trim(), "");
1504
+ if (evidenceAnalysis && evidenceAnalysis !== finding.description.trim()) {
1505
+ out.push("## Analysis", "");
1506
+ out.push(evidenceAnalysis, "");
1507
+ }
1508
+ const pocStepsBlock = renderPocSteps(finding);
1509
+ const hasRequest = !!finding.evidence?.request?.trim();
1510
+ const hasResponse = !!finding.evidence?.response?.trim();
1511
+ const hasScreenshots = !!ctx.screenshots && ctx.screenshots.length > 0;
1512
+ if (pocStepsBlock.length === 0 && !hasRequest && !hasResponse && !hasScreenshots) {
1513
+ throw new EmptyPocError(finding.id);
1514
+ }
1515
+ out.push("## PoC", "");
1516
+ if (pocStepsBlock.length > 0) {
1517
+ const redactedSteps = redactSensitiveHeaders(pocStepsBlock.join("\n")).split("\n");
1518
+ out.push(...redactedSteps);
1519
+ }
1520
+ if (hasScreenshots) {
1521
+ for (const shot of ctx.screenshots) {
1522
+ const width = shot.width ? ` width="${shot.width}"` : "";
1523
+ out.push(`<img${width} alt="${shot.alt}" src="${shot.relativePath}" />`, "");
1524
+ if (shot.caption) {
1525
+ out.push(`> ${shot.caption}`, "");
1526
+ }
1527
+ }
1528
+ }
1529
+ if (hasRequest) {
1530
+ out.push("**Request:**", "");
1531
+ out.push(indentEvidenceBlock(redactSensitiveHeaders(finding.evidence.request), "http"), "");
1532
+ }
1533
+ if (hasResponse) {
1534
+ out.push("**Response:**", "");
1535
+ out.push(indentEvidenceBlock(redactSensitiveHeaders(finding.evidence.response), "http"), "");
1536
+ }
1537
+ out.push("## Suggested fix", "");
1538
+ out.push(suggestedFix, "");
1539
+ out.push("## Patch status", "");
1540
+ if (ctx.patchStatus) {
1541
+ out.push(formatPatchStatusSection(ctx.patchStatus), "");
1542
+ } else {
1543
+ out.push("_Pass `--repo <path>` to `@0/cli disclose` to auto-verify this against the target's current HEAD or a specific tag._", "");
1544
+ }
1545
+ if (ctx.pocExecution) {
1546
+ const verdict = ctx.pocExecution.overallVerdict === "exploit_still_works" ? "**Behavioural check: exploit still reproducible.**" : ctx.pocExecution.overallVerdict === "exploit_broken" ? "**Behavioural check: exploit no longer reproducible.**" : "**Behavioural check: could not run.**";
1547
+ out.push(verdict, "");
1548
+ out.push(`> Verdict: \`${ctx.pocExecution.overallVerdict}\` (${ctx.pocExecution.steps.length} step${ctx.pocExecution.steps.length === 1 ? "" : "s"} executed).`, "");
1549
+ }
1550
+ out.push("## Credits", "");
1551
+ out.push("Discovered by **0.security**, the 0.security AI-assisted security engine ([0.security](https://0.security)).", "", "Reporter: _(your github handle)_", "");
1552
+ return {
1553
+ filename,
1554
+ markdown: out.join("\n").replace(/\n{3,}/g, "\n\n"),
1555
+ cvssVector: cvss.vector,
1556
+ cvssScore: cvss.score,
1557
+ primaryCwe: cwes[0]?.id ?? "",
1558
+ severity: finding.severity
1559
+ };
1560
+ }
1561
+ function buildAffectedLine(finding, ctx) {
1562
+ if (ctx.versionRange)
1563
+ return formatVersionRangeLine(ctx.versionRange);
1564
+ if (ctx.target) {
1565
+ return `\`${ctx.target}\`${ctx.targetRef ? ` at \`${ctx.targetRef}\`` : ""}${ctx.commitHash ? ` (commit \`${ctx.commitHash.slice(0, 12)}\`)` : ""}`;
1566
+ }
1567
+ return "_Affected component/version: to be filled in by the operator before submission._";
1568
+ }
1569
+ function buildImpactNarrative(finding) {
1570
+ const a = finding.impactAssessment;
1571
+ if (!a) {
1572
+ return `This ${finding.category.replace(/-/g, " ")} issue is rated **${severityHeading(finding.severity)}**. ` + finding.description.trim();
1573
+ }
1574
+ const parts = [];
1575
+ parts.push(`An attacker gains **${weaponizabilityLabel(a.weaponizability)}**. Attack prerequisites: ${reachabilityLabel(a.reachability_tier)}.`);
1576
+ if (a.blast_radius)
1577
+ parts.push(`**Blast radius:** ${a.blast_radius}`);
1578
+ if (a.rationale)
1579
+ parts.push(a.rationale);
1580
+ return parts.join("\n\n");
1581
+ }
1582
+ function buildAttackScenario(finding) {
1583
+ const a = finding.impactAssessment;
1584
+ if (!a)
1585
+ return "";
1586
+ return `1. Attacker position: ${reachabilityLabel(a.reachability_tier)}.
1587
+ 2. Trigger the ${finding.category.replace(/-/g, " ")} condition described above.
1588
+ 3. Result: ${weaponizabilityLabel(a.weaponizability)}${a.blast_radius ? ` \u2014 ${a.blast_radius}` : ""}.`;
1589
+ }
1590
+ function buildStepsToReproduce(finding) {
1591
+ const block = renderPocSteps(finding);
1592
+ if (block.length === 0)
1593
+ return "";
1594
+ return redactSensitiveHeaders(block.join("\n"));
1595
+ }
1596
+ function buildPocEvidence(finding, ctx) {
1597
+ const out = [];
1598
+ if (ctx.screenshots && ctx.screenshots.length > 0) {
1599
+ for (const shot of ctx.screenshots) {
1600
+ const width = shot.width ? ` width="${shot.width}"` : "";
1601
+ out.push(`<img${width} alt="${shot.alt}" src="${shot.relativePath}" />`, "");
1602
+ if (shot.caption)
1603
+ out.push(`> ${shot.caption}`, "");
1604
+ }
1605
+ }
1606
+ if (finding.evidence?.request?.trim()) {
1607
+ out.push("**Request:**", "", indentEvidenceBlock(redactSensitiveHeaders(finding.evidence.request), "http"), "");
1608
+ }
1609
+ if (finding.evidence?.response?.trim()) {
1610
+ out.push("**Response:**", "", indentEvidenceBlock(redactSensitiveHeaders(finding.evidence.response), "http"), "");
1611
+ }
1612
+ return out.join("\n").trim();
1613
+ }
1614
+ function buildRemediation(finding, ctx) {
1615
+ const remediation = finding.remediation;
1616
+ const parts = [];
1617
+ if (remediation?.summary)
1618
+ parts.push(remediation.summary);
1619
+ if (remediation?.steps?.length) {
1620
+ parts.push(remediation.steps.map((step, i) => `${i + 1}. ${step}`).join("\n"));
1621
+ }
1622
+ if (remediation?.codeExample?.after) {
1623
+ const lang = remediation.codeExample.language || "";
1624
+ parts.push(remediation.codeExample.before ? `**Before:**
1625
+
1626
+ \`\`\`${lang}
1627
+ ${remediation.codeExample.before}
1628
+ \`\`\`
1629
+
1630
+ **After:**
1631
+
1632
+ \`\`\`${lang}
1633
+ ${remediation.codeExample.after}
1634
+ \`\`\`` : `\`\`\`${lang}
1635
+ ${remediation.codeExample.after}
1636
+ \`\`\``);
1637
+ } else if (ctx.siblingFix) {
1638
+ const ref = `${ctx.siblingFix.fileRef.file}${ctx.siblingFix.fileRef.line ? `:${ctx.siblingFix.fileRef.line}` : ""}`;
1639
+ parts.push(`**Correct pattern already present in the repo at \`${ref}\`** *(extracted by 0):*
1640
+
1641
+ \`\`\`${ctx.siblingFix.language}
1642
+ ${ctx.siblingFix.snippet}
1643
+ \`\`\``);
1644
+ }
1645
+ return parts.length > 0 ? parts.join("\n\n") : "_Recommended fix: apply input validation / correct handling per the referenced CWE guidance._";
1646
+ }
1647
+ function buildReferences(finding, cwes) {
1648
+ const lines = [];
1649
+ for (const cwe of cwes) {
1650
+ const num = cwe.id.replace(/^CWE-/i, "");
1651
+ lines.push(`- [${cwe.id}: ${cwe.name}](https://cwe.mitre.org/data/definitions/${num}.html)`);
1652
+ }
1653
+ for (const ref of finding.remediation?.references ?? []) {
1654
+ lines.push(`- ${ref}`);
1655
+ }
1656
+ return lines.length > 0 ? lines.join("\n") : "_No external references._";
1657
+ }
1658
+ function bugcrowdPriority(severity) {
1659
+ switch (severity) {
1660
+ case "critical":
1661
+ return "P1 (Critical)";
1662
+ case "high":
1663
+ return "P2 (High)";
1664
+ case "medium":
1665
+ return "P3 (Medium)";
1666
+ case "low":
1667
+ return "P4 (Low)";
1668
+ default:
1669
+ return "P5 (Informational)";
1670
+ }
1671
+ }
1672
+ function immunefiSeverity(severity) {
1673
+ switch (severity) {
1674
+ case "critical":
1675
+ return "Critical \u2014 direct loss/freezing of funds or protocol insolvency";
1676
+ case "high":
1677
+ return "High \u2014 significant impact to funds or protocol integrity";
1678
+ case "medium":
1679
+ return "Medium \u2014 limited impact, bounded or conditional";
1680
+ default:
1681
+ return "Low \u2014 informational / minor impact";
1682
+ }
1683
+ }
1684
+ function buildCommonParts(finding, ctx) {
1685
+ const cwes = suggestCwesForCategory(finding.category);
1686
+ const cvss = suggestCvss(finding);
1687
+ const cvss4 = suggestCvss4(finding);
1688
+ const severity = severityHeading(finding.severity);
1689
+ const steps = buildStepsToReproduce(finding);
1690
+ const poc = buildPocEvidence(finding, ctx);
1691
+ if (!steps && !poc)
1692
+ throw new EmptyPocError(finding.id);
1693
+ return {
1694
+ cvss,
1695
+ cwes,
1696
+ severity,
1697
+ title: finding.title,
1698
+ summary: finding.description.trim(),
1699
+ impact: buildImpactNarrative(finding),
1700
+ attackScenario: buildAttackScenario(finding),
1701
+ steps,
1702
+ poc,
1703
+ affected: buildAffectedLine(finding, ctx),
1704
+ remediation: buildRemediation(finding, ctx),
1705
+ references: buildReferences(finding, cwes),
1706
+ severityCvss31: renderCvssSection({ vector: cvss.vector, score: cvss.score, severity }),
1707
+ severityCvss40: renderCvssSection({
1708
+ vector: cvss4.vector,
1709
+ score: cvss4.score,
1710
+ severity: cvss4.severity
1711
+ })
1712
+ };
1713
+ }
1714
+ function assembleReport(platform, parts, sections) {
1715
+ const out = [`# ${parts.title}`, ""];
1716
+ for (const s of sections) {
1717
+ out.push(`## ${s.heading}`, "", s.body, "");
1718
+ }
1719
+ return {
1720
+ platform,
1721
+ title: parts.title,
1722
+ markdown: out.join("\n").replace(/\n{3,}/g, "\n\n"),
1723
+ cvssVector: parts.cvss.vector,
1724
+ cvssScore: parts.cvss.score,
1725
+ severity: parts.severity,
1726
+ sections
1727
+ };
1728
+ }
1729
+ function stepsBodyOrPoc(parts) {
1730
+ return parts.steps || "_See the Proof of Concept section below for the reproduction._";
1731
+ }
1732
+ var HACKERONE_TEMPLATE = {
1733
+ id: "hackerone",
1734
+ label: "HackerOne",
1735
+ description: "H1 field order: Summary \u2192 Steps To Reproduce \u2192 PoC \u2192 Impact \u2192 Severity (CVSS) \u2192 Remediation \u2192 Supporting Material.",
1736
+ requiredSections: [
1737
+ "Summary",
1738
+ "Steps To Reproduce",
1739
+ "Proof of Concept",
1740
+ "Impact",
1741
+ "Severity",
1742
+ "Remediation",
1743
+ "Supporting Material / References"
1744
+ ],
1745
+ render(finding, ctx = {}) {
1746
+ const parts = buildCommonParts(finding, ctx);
1747
+ const sections = [
1748
+ { heading: "Summary", body: parts.summary },
1749
+ { heading: "Affected Asset", body: parts.affected },
1750
+ { heading: "Steps To Reproduce", body: stepsBodyOrPoc(parts) },
1751
+ { heading: "Proof of Concept", body: parts.poc || "_See Steps To Reproduce._" },
1752
+ { heading: "Impact", body: parts.impact },
1753
+ { heading: "Severity", body: `${parts.severityCvss31}
1754
+
1755
+ _${cvssSourceLabel(parts.cvss)}_` },
1756
+ { heading: "Remediation", body: parts.remediation },
1757
+ { heading: "Supporting Material / References", body: parts.references }
1758
+ ];
1759
+ return assembleReport("hackerone", parts, sections);
1760
+ }
1761
+ };
1762
+ var BUGCROWD_TEMPLATE = {
1763
+ id: "bugcrowd",
1764
+ label: "Bugcrowd",
1765
+ description: "Bugcrowd VRT-first: leads with Business Impact + VRT priority (P1\u2013P5), then Vulnerability Details, Steps, PoC, Remediation.",
1766
+ requiredSections: [
1767
+ "Vulnerability Details",
1768
+ "Business Impact",
1769
+ "Bugcrowd VRT / Priority",
1770
+ "Steps to Reproduce",
1771
+ "Proof of Concept",
1772
+ "Remediation",
1773
+ "References"
1774
+ ],
1775
+ render(finding, ctx = {}) {
1776
+ const parts = buildCommonParts(finding, ctx);
1777
+ const sections = [
1778
+ { heading: "Business Impact", body: parts.impact },
1779
+ {
1780
+ heading: "Bugcrowd VRT / Priority",
1781
+ body: `**${bugcrowdPriority(finding.severity)}**
1782
+
1783
+ ${parts.severityCvss31}`
1784
+ },
1785
+ { heading: "Vulnerability Details", body: parts.summary },
1786
+ { heading: "Affected Target", body: parts.affected },
1787
+ { heading: "Steps to Reproduce", body: stepsBodyOrPoc(parts) },
1788
+ { heading: "Proof of Concept", body: parts.poc || "_See Steps to Reproduce._" },
1789
+ { heading: "Remediation", body: parts.remediation },
1790
+ { heading: "References", body: parts.references }
1791
+ ];
1792
+ return assembleReport("bugcrowd", parts, sections);
1793
+ }
1794
+ };
1795
+ var INTIGRITI_TEMPLATE = {
1796
+ id: "intigriti",
1797
+ label: "Intigriti",
1798
+ description: "Intigriti order: Summary \u2192 Domain/Endpoint \u2192 Vulnerability Type (CWE) \u2192 Impact \u2192 Steps \u2192 PoC \u2192 Severity (CVSS) \u2192 Recommended Fix.",
1799
+ requiredSections: [
1800
+ "Summary",
1801
+ "Domain / Endpoint",
1802
+ "Vulnerability Type",
1803
+ "Impact",
1804
+ "Steps to Reproduce",
1805
+ "Proof of Concept",
1806
+ "Severity",
1807
+ "Recommended Fix"
1808
+ ],
1809
+ render(finding, ctx = {}) {
1810
+ const parts = buildCommonParts(finding, ctx);
1811
+ const primaryCwe = parts.cwes[0];
1812
+ const sections = [
1813
+ { heading: "Summary", body: parts.summary },
1814
+ { heading: "Domain / Endpoint", body: parts.affected },
1815
+ {
1816
+ heading: "Vulnerability Type",
1817
+ body: primaryCwe ? `${primaryCwe.id}: ${primaryCwe.name} (category: \`${finding.category}\`)` : `Category: \`${finding.category}\``
1818
+ },
1819
+ { heading: "Impact", body: parts.impact },
1820
+ { heading: "Steps to Reproduce", body: stepsBodyOrPoc(parts) },
1821
+ { heading: "Proof of Concept", body: parts.poc || "_See Steps to Reproduce._" },
1822
+ { heading: "Severity", body: parts.severityCvss31 },
1823
+ { heading: "Recommended Fix", body: parts.remediation },
1824
+ { heading: "References", body: parts.references }
1825
+ ];
1826
+ return assembleReport("intigriti", parts, sections);
1827
+ }
1828
+ };
1829
+ var IMMUNEFI_TEMPLATE = {
1830
+ id: "immunefi",
1831
+ label: "Immunefi (web3)",
1832
+ description: "Immunefi web3 order: Bug Description \u2192 Impact (funds/assets at risk) \u2192 Impact-in-Detail \u2192 Attack Scenario \u2192 PoC \u2192 Affected Assets \u2192 Recommendation. Impact-based severity + CVSS 4.0.",
1833
+ requiredSections: [
1834
+ "Bug Description",
1835
+ "Impact",
1836
+ "Severity",
1837
+ "Attack Scenario",
1838
+ "Proof of Concept",
1839
+ "Affected Assets",
1840
+ "Recommendation"
1841
+ ],
1842
+ render(finding, ctx = {}) {
1843
+ const parts = buildCommonParts(finding, ctx);
1844
+ const sections = [
1845
+ { heading: "Bug Description", body: parts.summary },
1846
+ { heading: "Impact", body: parts.impact },
1847
+ {
1848
+ heading: "Severity",
1849
+ body: `**${immunefiSeverity(finding.severity)}**
1850
+
1851
+ ${parts.severityCvss40}
1852
+
1853
+ ${parts.severityCvss31}`
1854
+ },
1855
+ {
1856
+ heading: "Attack Scenario",
1857
+ body: parts.attackScenario || stepsBodyOrPoc(parts)
1858
+ },
1859
+ {
1860
+ heading: "Proof of Concept",
1861
+ body: [parts.steps, parts.poc].filter(Boolean).join("\n\n") || "_Attach a runnable PoC / test before submission._"
1862
+ },
1863
+ { heading: "Affected Assets", body: parts.affected },
1864
+ { heading: "Recommendation", body: parts.remediation },
1865
+ { heading: "References", body: parts.references }
1866
+ ];
1867
+ return assembleReport("immunefi", parts, sections);
1868
+ }
1869
+ };
1870
+ var GENERIC_TEMPLATE = {
1871
+ id: "generic",
1872
+ label: "Generic / Default",
1873
+ description: "Platform-neutral, impact-first structure: Summary \u2192 Impact \u2192 Affected \u2192 Steps \u2192 PoC \u2192 Severity (CVSS) \u2192 Remediation \u2192 References.",
1874
+ requiredSections: [
1875
+ "Summary",
1876
+ "Impact",
1877
+ "Affected Assets",
1878
+ "Steps to Reproduce",
1879
+ "Proof of Concept",
1880
+ "Severity",
1881
+ "Remediation",
1882
+ "References"
1883
+ ],
1884
+ render(finding, ctx = {}) {
1885
+ const parts = buildCommonParts(finding, ctx);
1886
+ const sections = [
1887
+ { heading: "Summary", body: parts.summary },
1888
+ { heading: "Impact", body: parts.impact },
1889
+ { heading: "Affected Assets", body: parts.affected },
1890
+ { heading: "Steps to Reproduce", body: stepsBodyOrPoc(parts) },
1891
+ { heading: "Proof of Concept", body: parts.poc || "_See Steps to Reproduce._" },
1892
+ { heading: "Severity", body: `${parts.severityCvss31}
1893
+
1894
+ _${cvssSourceLabel(parts.cvss)}_` },
1895
+ { heading: "Remediation", body: parts.remediation },
1896
+ { heading: "References", body: parts.references }
1897
+ ];
1898
+ return assembleReport("generic", parts, sections);
1899
+ }
1900
+ };
1901
+ function cvssSourceLabel(cvss) {
1902
+ return cvss.source === "finding" ? "CVSS source: populated on the finding by 0." : cvss.source === "impact-assessment" ? "CVSS source: exploitability derived from 0's reachability assessment; impact from category \u2014 verify against your deployment." : "CVSS source: heuristic from category + severity \u2014 verify before submission.";
1903
+ }
1904
+ var TEMPLATE_REGISTRY = {
1905
+ hackerone: HACKERONE_TEMPLATE,
1906
+ bugcrowd: BUGCROWD_TEMPLATE,
1907
+ intigriti: INTIGRITI_TEMPLATE,
1908
+ immunefi: IMMUNEFI_TEMPLATE,
1909
+ generic: GENERIC_TEMPLATE
1910
+ };
1911
+ var REPORT_PLATFORMS = Object.values(TEMPLATE_REGISTRY).map((t) => ({
1912
+ id: t.id,
1913
+ label: t.label,
1914
+ description: t.description
1915
+ }));
1916
+ function reportTemplate(platform) {
1917
+ if (platform && platform in TEMPLATE_REGISTRY) {
1918
+ return TEMPLATE_REGISTRY[platform];
1919
+ }
1920
+ return GENERIC_TEMPLATE;
1921
+ }
1922
+ function renderPlatformReport(finding, platform, ctx = {}) {
1923
+ return reportTemplate(platform).render(finding, ctx);
1924
+ }
1925
+
1926
+ export {
1927
+ suggestCwesForCategory,
1928
+ formatCweSection,
1929
+ suggestCvss,
1930
+ Cvss4ParseError,
1931
+ computeCvss4BaseScore,
1932
+ cvss4Severity,
1933
+ parseCvss4Vector,
1934
+ formatCvss4Vector,
1935
+ scoreCvss4Vector,
1936
+ suggestCvss4,
1937
+ renderCvssSection,
1938
+ extractFileRefs,
1939
+ verifyAgainstRef,
1940
+ formatPatchStatusSection,
1941
+ detectVersionRange,
1942
+ formatVersionRangeLine,
1943
+ EmptyPocError,
1944
+ redactSensitiveHeaders,
1945
+ redactAuthHeaders,
1946
+ renderAdvisoryMarkdown,
1947
+ REPORT_PLATFORMS,
1948
+ reportTemplate,
1949
+ renderPlatformReport
1950
+ };