@cdxgen/cdxgen 13.1.0 → 13.2.0

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 (186) hide show
  1. package/README.md +8 -7
  2. package/bin/cdxgen.js +16 -3
  3. package/bin/evinse.js +2 -0
  4. package/data/crypto-oid.json +88 -12
  5. package/data/remediations.json +23 -0
  6. package/data/rules/ai-bom.yaml +78 -0
  7. package/data/rules/cargo-rust.yaml +132 -0
  8. package/data/rules/mcp-servers.yaml +122 -0
  9. package/lib/audit/targets.js +6 -1
  10. package/lib/cli/bomAssembly.js +12 -0
  11. package/lib/cli/index.js +192 -1
  12. package/lib/cli/jsBom.js +59 -2
  13. package/lib/cli/jvmBom.js +22 -0
  14. package/lib/cli/managedBom.js +152 -0
  15. package/lib/cli/nativeBom.js +798 -1
  16. package/lib/core/activity.js +120 -2
  17. package/lib/core/env.js +39 -1
  18. package/lib/core/userAgent.js +151 -0
  19. package/lib/ecosystems/cargoCache.js +364 -0
  20. package/lib/ecosystems/caxa.js +13 -5
  21. package/lib/ecosystems/cppEvidence.js +40 -2
  22. package/lib/ecosystems/ecosystems.js +241 -91
  23. package/lib/ecosystems/golem.js +11 -1
  24. package/lib/ecosystems/gradleutils.js +143 -2
  25. package/lib/ecosystems/kosi.js +1256 -0
  26. package/lib/ecosystems/parsers-crystal.js +179 -0
  27. package/lib/ecosystems/parsers-dotnet.js +69 -39
  28. package/lib/ecosystems/parsers-elm.js +816 -0
  29. package/lib/ecosystems/parsers-gleam.js +1 -1
  30. package/lib/ecosystems/parsers-julia.js +268 -0
  31. package/lib/ecosystems/parsers-lua.js +218 -0
  32. package/lib/ecosystems/parsers-misc.js +172 -0
  33. package/lib/ecosystems/parsers-nim.js +221 -0
  34. package/lib/ecosystems/parsers-opam.js +180 -0
  35. package/lib/ecosystems/parsers-perl.js +277 -0
  36. package/lib/ecosystems/parsers-python.js +1 -1
  37. package/lib/ecosystems/parsers-r.js +148 -0
  38. package/lib/ecosystems/parsers-rebar.js +411 -0
  39. package/lib/ecosystems/parsers-rust.js +932 -17
  40. package/lib/ecosystems/parsers-spack.js +204 -0
  41. package/lib/ecosystems/parsers-stack.js +264 -0
  42. package/lib/ecosystems/parsers-terraform.js +194 -0
  43. package/lib/ecosystems/rusi.js +126 -6
  44. package/lib/evinser/evinser.js +111 -1
  45. package/lib/helpers/agenticToolutils.js +925 -0
  46. package/lib/inventory/agentFormulationParser.js +57 -4
  47. package/lib/inventory/aiCollector.js +504 -10
  48. package/lib/inventory/aiInventory.js +12 -0
  49. package/lib/inventory/analyzer.js +488 -30
  50. package/lib/inventory/astWorker.js +6 -0
  51. package/lib/inventory/auditCategories.js +8 -0
  52. package/lib/inventory/cbomutils.js +30 -0
  53. package/lib/inventory/cdxrs.js +7 -2
  54. package/lib/inventory/communityAiConfigParser.js +215 -2
  55. package/lib/inventory/dosai.js +77 -0
  56. package/lib/inventory/envcontext.js +9 -6
  57. package/lib/inventory/evidenceUtils.js +13 -0
  58. package/lib/inventory/fetchBatch.js +74 -2
  59. package/lib/inventory/fetchRate.js +74 -11
  60. package/lib/inventory/forgeEnricher.js +3 -2
  61. package/lib/inventory/jvmToolEnv.js +6 -5
  62. package/lib/inventory/mcpConfigParser.js +166 -2
  63. package/lib/inventory/mcpDiscovery.js +11 -0
  64. package/lib/inventory/mcpServerManifest.js +389 -0
  65. package/lib/inventory/mcpbBundle.js +419 -0
  66. package/lib/inventory/plugins.js +3 -0
  67. package/lib/inventory/protobom.js +54 -88
  68. package/lib/inventory/protobomLoader.js +4 -0
  69. package/lib/inventory/rustFormulationParser.js +1 -1
  70. package/lib/inventory/source.js +10 -4
  71. package/lib/inventory/stylePackageRefs.js +41 -0
  72. package/lib/inventory/svelteUtils.js +524 -0
  73. package/lib/parsers/huggingfaceUtils.js +15 -7
  74. package/lib/parsers/onnx.js +294 -0
  75. package/lib/parsers/safetensors.js +114 -0
  76. package/lib/stages/postgen/introspection/markers.js +29 -6
  77. package/lib/stages/postgen/postgen.js +169 -1
  78. package/lib/third-party/arborist/snapshots/calc-dep-flags.test.cjs +462 -0
  79. package/package.json +25 -25
  80. package/types/lib/audit/targets.d.ts.map +1 -1
  81. package/types/lib/cli/bomAssembly.d.ts.map +1 -1
  82. package/types/lib/cli/index.d.ts +2 -2
  83. package/types/lib/cli/index.d.ts.map +1 -1
  84. package/types/lib/cli/jsBom.d.ts +23 -0
  85. package/types/lib/cli/jsBom.d.ts.map +1 -1
  86. package/types/lib/cli/jvmBom.d.ts.map +1 -1
  87. package/types/lib/cli/managedBom.d.ts +33 -0
  88. package/types/lib/cli/managedBom.d.ts.map +1 -1
  89. package/types/lib/cli/nativeBom.d.ts +88 -8
  90. package/types/lib/cli/nativeBom.d.ts.map +1 -1
  91. package/types/lib/core/activity.d.ts.map +1 -1
  92. package/types/lib/core/env.d.ts +21 -0
  93. package/types/lib/core/env.d.ts.map +1 -1
  94. package/types/lib/core/userAgent.d.ts +56 -0
  95. package/types/lib/core/userAgent.d.ts.map +1 -0
  96. package/types/lib/ecosystems/cargoCache.d.ts +75 -0
  97. package/types/lib/ecosystems/cargoCache.d.ts.map +1 -0
  98. package/types/lib/ecosystems/caxa.d.ts.map +1 -1
  99. package/types/lib/ecosystems/cppEvidence.d.ts +1 -1
  100. package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
  101. package/types/lib/ecosystems/ecosystems.d.ts +15 -1
  102. package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
  103. package/types/lib/ecosystems/gradleutils.d.ts +20 -0
  104. package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
  105. package/types/lib/ecosystems/kosi.d.ts +73 -0
  106. package/types/lib/ecosystems/kosi.d.ts.map +1 -0
  107. package/types/lib/ecosystems/parsers-crystal.d.ts +27 -0
  108. package/types/lib/ecosystems/parsers-crystal.d.ts.map +1 -0
  109. package/types/lib/ecosystems/parsers-dotnet.d.ts +19 -0
  110. package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
  111. package/types/lib/ecosystems/parsers-elm.d.ts +79 -0
  112. package/types/lib/ecosystems/parsers-elm.d.ts.map +1 -0
  113. package/types/lib/ecosystems/parsers-julia.d.ts +57 -0
  114. package/types/lib/ecosystems/parsers-julia.d.ts.map +1 -0
  115. package/types/lib/ecosystems/parsers-lua.d.ts +50 -0
  116. package/types/lib/ecosystems/parsers-lua.d.ts.map +1 -0
  117. package/types/lib/ecosystems/parsers-misc.d.ts +23 -0
  118. package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
  119. package/types/lib/ecosystems/parsers-nim.d.ts +43 -0
  120. package/types/lib/ecosystems/parsers-nim.d.ts.map +1 -0
  121. package/types/lib/ecosystems/parsers-opam.d.ts +31 -0
  122. package/types/lib/ecosystems/parsers-opam.d.ts.map +1 -0
  123. package/types/lib/ecosystems/parsers-perl.d.ts +36 -0
  124. package/types/lib/ecosystems/parsers-perl.d.ts.map +1 -0
  125. package/types/lib/ecosystems/parsers-r.d.ts +35 -0
  126. package/types/lib/ecosystems/parsers-r.d.ts.map +1 -0
  127. package/types/lib/ecosystems/parsers-rebar.d.ts +42 -0
  128. package/types/lib/ecosystems/parsers-rebar.d.ts.map +1 -0
  129. package/types/lib/ecosystems/parsers-rust.d.ts +199 -0
  130. package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
  131. package/types/lib/ecosystems/parsers-spack.d.ts +33 -0
  132. package/types/lib/ecosystems/parsers-spack.d.ts.map +1 -0
  133. package/types/lib/ecosystems/parsers-stack.d.ts +35 -0
  134. package/types/lib/ecosystems/parsers-stack.d.ts.map +1 -0
  135. package/types/lib/ecosystems/parsers-terraform.d.ts +34 -0
  136. package/types/lib/ecosystems/parsers-terraform.d.ts.map +1 -0
  137. package/types/lib/ecosystems/pythonutils.d.ts +1 -1
  138. package/types/lib/ecosystems/rusi.d.ts.map +1 -1
  139. package/types/lib/evinser/evinser.d.ts +29 -0
  140. package/types/lib/evinser/evinser.d.ts.map +1 -1
  141. package/types/lib/helpers/agenticToolutils.d.ts +87 -0
  142. package/types/lib/helpers/agenticToolutils.d.ts.map +1 -0
  143. package/types/lib/inventory/agentFormulationParser.d.ts.map +1 -1
  144. package/types/lib/inventory/aiCollector.d.ts.map +1 -1
  145. package/types/lib/inventory/aiInventory.d.ts.map +1 -1
  146. package/types/lib/inventory/analyzer.d.ts.map +1 -1
  147. package/types/lib/inventory/auditCategories.d.ts +4 -0
  148. package/types/lib/inventory/auditCategories.d.ts.map +1 -1
  149. package/types/lib/inventory/cbomutils.d.ts.map +1 -1
  150. package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
  151. package/types/lib/inventory/dosai.d.ts +23 -0
  152. package/types/lib/inventory/dosai.d.ts.map +1 -1
  153. package/types/lib/inventory/envcontext.d.ts.map +1 -1
  154. package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
  155. package/types/lib/inventory/fetchBatch.d.ts +34 -0
  156. package/types/lib/inventory/fetchBatch.d.ts.map +1 -1
  157. package/types/lib/inventory/fetchRate.d.ts +9 -6
  158. package/types/lib/inventory/fetchRate.d.ts.map +1 -1
  159. package/types/lib/inventory/forgeEnricher.d.ts.map +1 -1
  160. package/types/lib/inventory/jvmToolEnv.d.ts +5 -4
  161. package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
  162. package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
  163. package/types/lib/inventory/mcpDiscovery.d.ts.map +1 -1
  164. package/types/lib/inventory/mcpServerManifest.d.ts +19 -0
  165. package/types/lib/inventory/mcpServerManifest.d.ts.map +1 -0
  166. package/types/lib/inventory/mcpbBundle.d.ts +19 -0
  167. package/types/lib/inventory/mcpbBundle.d.ts.map +1 -0
  168. package/types/lib/inventory/plugins.d.ts.map +1 -1
  169. package/types/lib/inventory/protobom.d.ts +18 -13
  170. package/types/lib/inventory/protobom.d.ts.map +1 -1
  171. package/types/lib/inventory/protobomLoader.d.ts.map +1 -1
  172. package/types/lib/inventory/source.d.ts.map +1 -1
  173. package/types/lib/inventory/stylePackageRefs.d.ts +17 -0
  174. package/types/lib/inventory/stylePackageRefs.d.ts.map +1 -0
  175. package/types/lib/inventory/svelteUtils.d.ts +124 -0
  176. package/types/lib/inventory/svelteUtils.d.ts.map +1 -0
  177. package/types/lib/parsers/huggingfaceUtils.d.ts +8 -1
  178. package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
  179. package/types/lib/parsers/onnx.d.ts +28 -0
  180. package/types/lib/parsers/onnx.d.ts.map +1 -0
  181. package/types/lib/parsers/safetensors.d.ts +22 -0
  182. package/types/lib/parsers/safetensors.d.ts.map +1 -0
  183. package/types/lib/stages/postgen/introspection/markers.d.ts +3 -2
  184. package/types/lib/stages/postgen/introspection/markers.d.ts.map +1 -1
  185. package/types/lib/stages/postgen/postgen.d.ts +33 -0
  186. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
package/README.md CHANGED
@@ -216,7 +216,7 @@ Common asset names:
216
216
  #### Linux
217
217
 
218
218
  ```bash
219
- VERSION="v13.1.0"
219
+ VERSION="v13.2.0"
220
220
  ASSET="cdx-audit-linux-amd64"
221
221
  BASE_URL="https://github.com/cdxgen/cdxgen/releases/download/${VERSION}"
222
222
 
@@ -230,7 +230,7 @@ chmod +x "${ASSET}"
230
230
  #### macOS
231
231
 
232
232
  ```bash
233
- VERSION="v13.1.0"
233
+ VERSION="v13.2.0"
234
234
  ASSET="cdx-audit-darwin-arm64"
235
235
  BASE_URL="https://github.com/cdxgen/cdxgen/releases/download/${VERSION}"
236
236
 
@@ -244,7 +244,7 @@ chmod +x "${ASSET}"
244
244
  #### Windows (PowerShell)
245
245
 
246
246
  ```powershell
247
- $Version = "v13.1.0"
247
+ $Version = "v13.2.0"
248
248
  $Asset = "cdx-audit-windows-amd64.exe"
249
249
  $BaseUrl = "https://github.com/cdxgen/cdxgen/releases/download/$Version"
250
250
 
@@ -269,7 +269,7 @@ steps:
269
269
  env:
270
270
  GH_TOKEN: ${{ github.token }}
271
271
  run: |
272
- gh release download v13.1.0 \
272
+ gh release download v13.2.0 \
273
273
  --repo cdxgen/cdxgen \
274
274
  --pattern 'cdx-audit-linux-amd64' \
275
275
  --pattern 'cdx-audit-linux-amd64.sha256'
@@ -497,14 +497,13 @@ Use repeated `--component-type` values to include only selected CycloneDX compon
497
497
  cdxgen -t docker alpine:3.20 --spec-version 1.6 --component-type library --component-type data
498
498
  ```
499
499
 
500
- To generate SBOM for C or Python, ensure Java >= 21 is installed.
500
+ To generate SBOM for C or Python, cdxgen uses the bundled atom companion. On linux-amd64, linux-arm64 (glibc), linux-amd64-musl, darwin-arm64, and windows-amd64, atom ships as a native binary and needs no JDK. Only the jar-based triples (darwin-amd64, windows-arm64, and linux-arm64-musl) run atom on the JVM.
501
501
 
502
502
  ```shell
503
- # Install java >= 21
504
503
  cdxgen -t c -o bom.json
505
504
  ```
506
505
 
507
- NOTE: cdxgen is known to freeze with Java 8 or 11, so ensure >= 21 is installed and JAVA_HOME environment variable is configured correctly. If in doubt, use the cdxgen container image.
506
+ NOTE: On the jar-based triples, atom requires Java >= 23 and is known to freeze with Java 8 or 11, so ensure a suitable version is installed and the JAVA_HOME environment variable is configured correctly. If in doubt, use the cdxgen container image.
508
507
 
509
508
  ## Universal SBOM
510
509
 
@@ -788,6 +787,8 @@ pnpm dlx @cdxgen/cdxgen cdx-sign -i bom.json -k private.key
788
787
 
789
788
  For node.js projects, lock files are parsed initially, so the SBOM would include all dependencies, including dev ones. An AST parser powered by babel-parser is then used to detect packages that are imported and used by non-test code. Such imported packages would automatically set their scope property to `required` in the resulting SBOM. You can turn off this analysis by passing the argument `--no-babel`. Scope property would then be set based on the `dev` attribute in the lock file.
790
789
 
790
+ Single-file component frameworks are handled natively by this analysis: `.vue` and `.svelte` templates are segmented position-preservingly so script imports recover with correct file and line evidence. For Svelte and SvelteKit, framework usage signals are additionally collected — SvelteKit virtual modules such as `$app/stores` are attributed to `@sveltejs/kit`, `$lib/*` imports resolve through `kit.alias`, `svelte.config.js` adapters and preprocessors, CSS preprocessor packages implied by `<style lang="...">` blocks together with their `@use`/`@import` package references, npm script executables such as `svelte-kit sync` and `svelte-check`, and rune usage (`$state`, `$derived`, ...) which marks `svelte` required even in components that never import it. This works in every installation; when the optional `@appthreat/atom-parsetools` package is present, template expressions also contribute usage occurrences.
791
+
791
792
  This attribute can be later used for various purposes. For example, [dep-scan][depscan-github] uses this attribute to prioritize vulnerabilities. Unfortunately, tools such as dependency track, do not include this feature and might over-report the CVEs.
792
793
 
793
794
  With the argument `--required-only`, you can limit the SBOM only to include packages with the scope "required", commonly called production or non-dev dependencies. Combine with `--no-babel` to limit this list to only non-dev dependencies based on the `dev` attribute being false in the lock files.
package/bin/cdxgen.js CHANGED
@@ -19,6 +19,7 @@ import { parse as _load } from "yaml";
19
19
  import yargs from "yargs";
20
20
  import { hideBin } from "yargs/helpers";
21
21
 
22
+ import { getExactAiInventoryType } from "../lib/cli/bomAssembly.js";
22
23
  import {
23
24
  applyAdvancedOptions as applyAdvancedOptionsImpl,
24
25
  buildOptionsFromArgs,
@@ -123,7 +124,10 @@ import {
123
124
  } from "../lib/inventory/source.js";
124
125
  import { executeOsQuery } from "../lib/managers/binary.js";
125
126
  import { getBomWithOras } from "../lib/managers/oci.js";
126
- import { postProcess } from "../lib/stages/postgen/postgen.js";
127
+ import {
128
+ applyEvidenceBasedFilter,
129
+ postProcess,
130
+ } from "../lib/stages/postgen/postgen.js";
127
131
  import { convertCycloneDxToSpdx } from "../lib/stages/postgen/spdxConverter.js";
128
132
  import { auditEnvironment } from "../lib/stages/pregen/envAudit.js";
129
133
  import { prepareEnv } from "../lib/stages/pregen/pregen.js";
@@ -1601,7 +1605,14 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
1601
1605
  }
1602
1606
  let sourcePath = filePath;
1603
1607
  let purlResolution;
1604
- const directHuggingFaceSource = normalizeHuggingFaceReference(sourcePath);
1608
+ // Direct HuggingFace interpretation of the source path is opt-in: bare
1609
+ // `owner/repo`-shaped values are ordinary relative paths (eg: repotests/
1610
+ // sveltejs-realworld) unless an AI inventory type such as `-t ai` is
1611
+ // explicitly selected. Unambiguous purls and huggingface.co URLs always
1612
+ // resolve.
1613
+ const directHuggingFaceSource = normalizeHuggingFaceReference(sourcePath, {
1614
+ explicitOnly: getExactAiInventoryType(options) !== "ai",
1615
+ });
1605
1616
  if (isDryRun && directHuggingFaceSource) {
1606
1617
  recordActivity({
1607
1618
  kind: "read",
@@ -2075,7 +2086,9 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
2075
2086
  sliceArtefacts,
2076
2087
  evinseOptions,
2077
2088
  );
2078
- bomNSData.bomJson = evinseJson;
2089
+ // The scope filter is deferred until here so the analyzers get to
2090
+ // prove that an optional dependency is actually used.
2091
+ bomNSData.bomJson = applyEvidenceBasedFilter(evinseJson, options);
2079
2092
  if (options.print && evinseJson) {
2080
2093
  printOccurrences(evinseJson);
2081
2094
  printCallStack(evinseJson);
package/bin/evinse.js CHANGED
@@ -45,6 +45,8 @@ const args = yargs(hideBin(process.argv))
45
45
  choices: [
46
46
  "java",
47
47
  "jar",
48
+ "kotlin",
49
+ "kt",
48
50
  "js",
49
51
  "ts",
50
52
  "javascript",
@@ -40,11 +40,11 @@
40
40
  "description": "Korean SEED algorithm, CBC mode"
41
41
  },
42
42
  "seedOFB": {
43
- "oid": "1.2.410.200004.1.5",
43
+ "oid": "1.2.410.200004.1.6",
44
44
  "description": "Korean SEED algorithm, OFB mode"
45
45
  },
46
46
  "seedCFB": {
47
- "oid": "1.2.410.200004.1.6",
47
+ "oid": "1.2.410.200004.1.5",
48
48
  "description": "Korean SEED algorithm, CFB mode"
49
49
  },
50
50
  "seedMAC": {
@@ -233,11 +233,11 @@
233
233
  },
234
234
  "cryptoProECDH256": {
235
235
  "oid": "1.2.643.7.1.1.6.1",
236
- "description": "CryptoPro ECC DH algorithm for GOST R 34.10-2012 256 bit key"
236
+ "description": "TC26 GOST R 34.10-2012 256-bit key agreement"
237
237
  },
238
238
  "cryptoProECDH512": {
239
239
  "oid": "1.2.643.7.1.1.6.2",
240
- "description": "CryptoPro ECC DH algorithm for GOST R 34.10-2012 512 bit key"
240
+ "description": "TC26 GOST R 34.10-2012 512-bit key agreement"
241
241
  },
242
242
  "dsa": {
243
243
  "oid": "1.2.840.10040.4.1",
@@ -932,8 +932,8 @@
932
932
  "description": "Teletrust algorithm"
933
933
  },
934
934
  "rsaSignature": {
935
- "oid": "1.3.36.3.3.1",
936
- "description": "Teletrust signature algorithm"
935
+ "oid": "1.3.14.3.2.11",
936
+ "description": "RSA signature (OIW secsig)"
937
937
  },
938
938
  "rsaSignatureWithsha1": {
939
939
  "oid": "1.3.36.3.3.1.1",
@@ -1412,8 +1412,8 @@
1412
1412
  "description": "Novell encryption algorithm"
1413
1413
  },
1414
1414
  "sha-1": {
1415
- "oid": "2.16.840.1.113719.1.2.8.82",
1416
- "description": "Novell digest algorithm"
1415
+ "oid": "1.3.14.3.2.26",
1416
+ "description": "SHA-1 secure hash standard (OIW)"
1417
1417
  },
1418
1418
  "rc2BSafe1Cbc": {
1419
1419
  "oid": "2.16.840.1.113719.1.2.8.92",
@@ -1959,10 +1959,6 @@
1959
1959
  "oid": "1.2.156.10197.1.301.3",
1960
1960
  "description": "Chinese Cryptography Standardization Technology Committee (CCSTC)"
1961
1961
  },
1962
- "sm2sign_with_": {
1963
- "oid": "1.2.156.10197.1.501",
1964
- "description": "Chinese Cryptography Standardization Technology Committee (CCSTC)"
1965
- },
1966
1962
  "PBKDF2": {
1967
1963
  "oid": "1.2.840.113549.1.5.12",
1968
1964
  "description": "PBKDF2 key derivation algorithm"
@@ -1994,5 +1990,85 @@
1994
1990
  "pbeWithSHA1AndRC2-CBC": {
1995
1991
  "oid": "1.2.840.113549.1.5.11",
1996
1992
  "description": "Password Based Encryption Algorithm. Uses RC2 in Cipher Block Chaining Mode (RC2-CBC)."
1993
+ },
1994
+ "ml-dsa-44": {
1995
+ "oid": "2.16.840.1.101.3.4.3.17",
1996
+ "description": "ML-DSA-44 post-quantum signature (FIPS 204)"
1997
+ },
1998
+ "ml-dsa-65": {
1999
+ "oid": "2.16.840.1.101.3.4.3.18",
2000
+ "description": "ML-DSA-65 post-quantum signature (FIPS 204)"
2001
+ },
2002
+ "ml-dsa-87": {
2003
+ "oid": "2.16.840.1.101.3.4.3.19",
2004
+ "description": "ML-DSA-87 post-quantum signature (FIPS 204)"
2005
+ },
2006
+ "ml-kem-512": {
2007
+ "oid": "2.16.840.1.101.3.4.4.1",
2008
+ "description": "ML-KEM-512 post-quantum key encapsulation (FIPS 203)"
2009
+ },
2010
+ "ml-kem-768": {
2011
+ "oid": "2.16.840.1.101.3.4.4.2",
2012
+ "description": "ML-KEM-768 post-quantum key encapsulation (FIPS 203)"
2013
+ },
2014
+ "ml-kem-1024": {
2015
+ "oid": "2.16.840.1.101.3.4.4.3",
2016
+ "description": "ML-KEM-1024 post-quantum key encapsulation (FIPS 203)"
2017
+ },
2018
+ "x25519": {
2019
+ "oid": "1.3.101.110",
2020
+ "description": "X25519 Diffie-Hellman key agreement (RFC 7748)"
2021
+ },
2022
+ "slh-dsa-sha2-128s": {
2023
+ "oid": "2.16.840.1.101.3.4.3.20",
2024
+ "description": "SLH-DSA-SHA2-128s hash-based signature (FIPS 205)"
2025
+ },
2026
+ "slh-dsa-sha2-128f": {
2027
+ "oid": "2.16.840.1.101.3.4.3.21",
2028
+ "description": "SLH-DSA-SHA2-128f hash-based signature (FIPS 205)"
2029
+ },
2030
+ "slh-dsa-sha2-192s": {
2031
+ "oid": "2.16.840.1.101.3.4.3.22",
2032
+ "description": "SLH-DSA-SHA2-192s hash-based signature (FIPS 205)"
2033
+ },
2034
+ "slh-dsa-sha2-192f": {
2035
+ "oid": "2.16.840.1.101.3.4.3.23",
2036
+ "description": "SLH-DSA-SHA2-192f hash-based signature (FIPS 205)"
2037
+ },
2038
+ "slh-dsa-sha2-256s": {
2039
+ "oid": "2.16.840.1.101.3.4.3.24",
2040
+ "description": "SLH-DSA-SHA2-256s hash-based signature (FIPS 205)"
2041
+ },
2042
+ "slh-dsa-sha2-256f": {
2043
+ "oid": "2.16.840.1.101.3.4.3.25",
2044
+ "description": "SLH-DSA-SHA2-256f hash-based signature (FIPS 205)"
2045
+ },
2046
+ "slh-dsa-shake-128s": {
2047
+ "oid": "2.16.840.1.101.3.4.3.26",
2048
+ "description": "SLH-DSA-SHAKE-128s hash-based signature (FIPS 205)"
2049
+ },
2050
+ "slh-dsa-shake-128f": {
2051
+ "oid": "2.16.840.1.101.3.4.3.27",
2052
+ "description": "SLH-DSA-SHAKE-128f hash-based signature (FIPS 205)"
2053
+ },
2054
+ "slh-dsa-shake-192s": {
2055
+ "oid": "2.16.840.1.101.3.4.3.28",
2056
+ "description": "SLH-DSA-SHAKE-192s hash-based signature (FIPS 205)"
2057
+ },
2058
+ "slh-dsa-shake-192f": {
2059
+ "oid": "2.16.840.1.101.3.4.3.29",
2060
+ "description": "SLH-DSA-SHAKE-192f hash-based signature (FIPS 205)"
2061
+ },
2062
+ "slh-dsa-shake-256s": {
2063
+ "oid": "2.16.840.1.101.3.4.3.30",
2064
+ "description": "SLH-DSA-SHAKE-256s hash-based signature (FIPS 205)"
2065
+ },
2066
+ "slh-dsa-shake-256f": {
2067
+ "oid": "2.16.840.1.101.3.4.3.31",
2068
+ "description": "SLH-DSA-SHAKE-256f hash-based signature (FIPS 205)"
2069
+ },
2070
+ "sm2sign_with_sm3": {
2071
+ "oid": "1.2.156.10197.1.501",
2072
+ "description": "Chinese Cryptography Standardization Technology Committee (CCSTC)"
1997
2073
  }
1998
2074
  }
@@ -905,6 +905,29 @@
905
905
  },
906
906
  "docs": "https://cyclonedx.github.io/cdxgen/#/PROJECT_TYPES?id=rust"
907
907
  },
908
+ "rust.cargo-metadata-unavailable": {
909
+ "ecosystem": "rust",
910
+ "kind": "command.failed",
911
+ "impact": "components",
912
+ "title": "cargo metadata could not be executed, so dependency kinds and platform gates were recovered from the manifests alone",
913
+ "targetTier": "lockfile",
914
+ "actions": [
915
+ {
916
+ "kind": "build",
917
+ "command": "{{cargo}} metadata --format-version 1 --locked"
918
+ },
919
+ {
920
+ "kind": "rerun"
921
+ }
922
+ ],
923
+ "verify": {
924
+ "rules": [
925
+ "BF-RS-001"
926
+ ],
927
+ "expectTier": "lockfile"
928
+ },
929
+ "docs": "https://cyclonedx.github.io/cdxgen/#/PROJECT_TYPES?id=rust"
930
+ },
908
931
  "php.composer.missing": {
909
932
  "ecosystem": "php",
910
933
  "kind": "evidence.degraded",
@@ -266,3 +266,81 @@
266
266
  "parameterCount": $prop($, 'cdx:ai:parameterCount'),
267
267
  "source": $prop($, 'cdx:ai:source')
268
268
  }
269
+
270
+ - id: AIS-003
271
+ name: "Model artifact uses unsafe pickle deserialization"
272
+ description: "PyTorch pickle model artifacts (.bin/.pt/.pth/.ckpt) execute arbitrary code when loaded, so an untrusted or unverified artifact can run attacker-controlled code in the loading process."
273
+ severity: high
274
+ category: ai-security
275
+ dry-run-support: full
276
+ attack:
277
+ tactics: [TA0002]
278
+ techniques: [T1059, T1195.002]
279
+ standards:
280
+ owasp-ai-top-10:
281
+ - "LLM05: Supply Chain Vulnerabilities"
282
+ - "LLM03:2025 Supply Chain"
283
+ owasp-agentic-top-10-2026:
284
+ - "Agentic Supply Chain"
285
+ eu-ai-act:
286
+ - "Accuracy, robustness and cybersecurity"
287
+ - "Technical documentation and traceability"
288
+ eu-cra:
289
+ - "Software supply chain visibility"
290
+ - "Protection against untrusted code execution"
291
+ nist-ai-rmf:
292
+ - "Map"
293
+ - "Manage"
294
+ nist-ssdf:
295
+ - "Verify provenance of model artifacts before loading"
296
+ condition: |
297
+ components[
298
+ type = 'machine-learning-model'
299
+ and $prop($, 'cdx:ai:unsafeDeserialization') = 'true'
300
+ ]
301
+ location: |
302
+ {
303
+ "bomRef": $."bom-ref"
304
+ }
305
+ message: "Model artifact '{{ name }}' loads via unsafe pickle deserialization"
306
+ mitigation: "Prefer safetensors over pickle checkpoints, or verify artifact provenance and load pickle models only from trusted sources in a sandbox."
307
+ evidence: |
308
+ {
309
+ "artifactFormat": $prop($, 'cdx:ai:artifactFormat'),
310
+ "source": $prop($, 'cdx:ai:source'),
311
+ "quantizationMethod": $prop($, 'cdx:ai:quantizationMethod')
312
+ }
313
+
314
+ - id: AIS-004
315
+ name: "ONNX model artifact lacks exporter provenance"
316
+ description: "ONNX files record the exporting framework and opset versions in their protobuf header. An artifact without this metadata cannot be traced to the toolchain that produced it, which weakens provenance review and can hide compatibility or security-relevant export settings."
317
+ severity: low
318
+ category: ai-governance
319
+ dry-run-support: full
320
+ standards:
321
+ owasp-ai-top-10:
322
+ - "LLM05: Supply Chain Vulnerabilities"
323
+ - "LLM03:2025 Supply Chain"
324
+ eu-ai-act:
325
+ - "Technical documentation and traceability"
326
+ nist-ai-rmf:
327
+ - "Map"
328
+ - "Govern"
329
+ condition: |
330
+ components[
331
+ type = 'machine-learning-model'
332
+ and $prop($, 'cdx:ai:artifactFormat') = 'onnx'
333
+ and not $hasProp($, 'cdx:onnx:producer')
334
+ ]
335
+ location: |
336
+ {
337
+ "bomRef": $."bom-ref"
338
+ }
339
+ message: "ONNX model artifact '{{ name }}' carries no exporter provenance"
340
+ mitigation: "Re-export the model with a producer that records framework and opset metadata, or record the exporter and opset versions as component properties so the artifact remains traceable."
341
+ evidence: |
342
+ {
343
+ "artifactFormat": $prop($, 'cdx:ai:artifactFormat'),
344
+ "source": $prop($, 'cdx:ai:source'),
345
+ "modelId": $prop($, 'cdx:ai:modelId')
346
+ }
@@ -0,0 +1,132 @@
1
+ # Cargo and Rust Rules
2
+ # Categories: cargo-security, cargo-compliance
3
+ # Evaluates the cdx:cargo:* properties cdxgen emits for Rust projects, with the
4
+ # native-library rules keyed on the `links` evidence that only `--deep` can
5
+ # produce.
6
+
7
+ - id: CARGO-SEC-001
8
+ name: "Statically linked native library has no resolvable version"
9
+ description: "A -sys crate compiles a C library into the artifact, but nothing in the build states which version, so no advisory can be matched against it"
10
+ severity: medium
11
+ category: cargo-security
12
+ dry-run-support: full
13
+ condition: |
14
+ components[
15
+ $prop($, 'cdx:cargo:linkage') = 'static'
16
+ and ($not($exists(version)) or version = '')
17
+ ]
18
+ location: |
19
+ { "bomRef": $."bom-ref", "purl": purl }
20
+ message: "Native library '{{ name }}' is compiled into the artifact by '{{ $prop($, 'cdx:cargo:providedBy') }}' with no resolvable version"
21
+ mitigation: "Pin the library version explicitly, or build against a crate release whose version encodes the upstream version as build metadata. Until the version is known, the bundled library has to be reviewed by hand: a vulnerability scanner matching on purl cannot see it"
22
+ evidence: |
23
+ {
24
+ "nativeLibrary": $prop($, 'cdx:cargo:nativeLibrary'),
25
+ "providedBy": $prop($, 'cdx:cargo:providedBy'),
26
+ "linkageEvidence": $prop($, 'cdx:cargo:linkageEvidence'),
27
+ "versionCandidates": $prop($, 'cdx:cargo:upstreamVersionCandidates')
28
+ }
29
+
30
+ - id: CARGO-SEC-002
31
+ name: "Native C library is vendored into the Rust artifact"
32
+ description: "The resolver enabled a vendoring feature, so the library's own advisories and license obligations travel with the binary rather than with the host"
33
+ severity: low
34
+ category: cargo-security
35
+ dry-run-support: full
36
+ condition: |
37
+ components[
38
+ $prop($, 'cdx:cargo:linkage') = 'static'
39
+ and $exists(version)
40
+ and version != ''
41
+ ]
42
+ location: |
43
+ { "bomRef": $."bom-ref", "purl": purl }
44
+ message: "Native library '{{ name }}' version '{{ version }}' is compiled into the artifact by '{{ $prop($, 'cdx:cargo:providedBy') }}'"
45
+ mitigation: "Track this library's advisories directly; the cargo dependency graph will not report them. Confirm that updating the -sys crate is enough to pick up a library fix, and that the vendored build is rebuilt when the library is patched"
46
+ evidence: |
47
+ {
48
+ "nativeLibrary": $prop($, 'cdx:cargo:nativeLibrary'),
49
+ "providedBy": $prop($, 'cdx:cargo:providedBy'),
50
+ "linkageEvidence": $prop($, 'cdx:cargo:linkageEvidence'),
51
+ "upstreamVersionSource": $prop($, 'cdx:cargo:upstreamVersionSource')
52
+ }
53
+
54
+ - id: CARGO-SEC-003
55
+ name: "Rust artifact links a native library the environment must provide"
56
+ description: "A -sys crate links a C library dynamically, so the deployed artifact depends on a library version this BOM cannot state"
57
+ severity: low
58
+ category: cargo-security
59
+ dry-run-support: full
60
+ condition: |
61
+ components[$prop($, 'cdx:cargo:linkage') = 'dynamic']
62
+ location: |
63
+ { "bomRef": $."bom-ref", "purl": purl }
64
+ message: "Native library '{{ name }}' is linked dynamically by '{{ $prop($, 'cdx:cargo:providedBy') }}' and has to be present and patched on the deployment host"
65
+ mitigation: "Record the library version the deployment environment provides, through a container or host inventory. Where the artifact must be self-contained, enable the crate's vendoring feature so the version becomes part of this BOM"
66
+ evidence: |
67
+ {
68
+ "nativeLibrary": $prop($, 'cdx:cargo:nativeLibrary'),
69
+ "providedBy": $prop($, 'cdx:cargo:providedBy')
70
+ }
71
+
72
+ - id: CARGO-COMP-001
73
+ name: "Vendored library version is ambiguous between shipped variants"
74
+ description: "The crate ships several variants of the library and the enabled features do not say which one is compiled, so the version was left unstated"
75
+ severity: medium
76
+ category: cargo-compliance
77
+ dry-run-support: full
78
+ condition: |
79
+ components[
80
+ $prop($, 'cdx:cargo:upstreamVersionCandidates') != null
81
+ ]
82
+ location: |
83
+ { "bomRef": $."bom-ref", "purl": purl }
84
+ message: "Native library '{{ name }}' could be any of '{{ $prop($, 'cdx:cargo:upstreamVersionCandidates') }}' depending on which variant '{{ $prop($, 'cdx:cargo:providedBy') }}' compiles"
85
+ mitigation: "Read the crate's build script to see which variant the enabled features select, then record the version. The variants can carry different licenses, so a license review cannot be completed from this BOM alone"
86
+ evidence: |
87
+ {
88
+ "versionCandidates": $prop($, 'cdx:cargo:upstreamVersionCandidates'),
89
+ "providedBy": $prop($, 'cdx:cargo:providedBy'),
90
+ "resolvedFeatures": $prop($, 'cdx:cargo:resolvedFeatures')
91
+ }
92
+
93
+ - id: CARGO-SEC-004
94
+ name: "Crate resolved from a registry other than crates.io"
95
+ description: "A crate came from an alternative or private registry, which can publish any name and version, including ones that also exist on crates.io"
96
+ severity: medium
97
+ category: cargo-security
98
+ dry-run-support: full
99
+ condition: |
100
+ $append(components, formulation.components)[
101
+ $prop($, 'cdx:cargo:alternateRegistry') = 'true'
102
+ ]
103
+ location: |
104
+ { "bomRef": $."bom-ref", "purl": purl }
105
+ message: "Crate '{{ name }}' was resolved from '{{ $prop($, 'cdx:cargo:sourceUrl') }}' rather than crates.io"
106
+ mitigation: "Confirm the registry is one your organisation operates and that the crate name is not also claimed on crates.io, which would let a resolver change pull a different crate. Verify the registry authenticates publishers and serves checksums"
107
+ evidence: |
108
+ {
109
+ "sourceKind": $prop($, 'cdx:cargo:sourceKind'),
110
+ "sourceUrl": $prop($, 'cdx:cargo:sourceUrl')
111
+ }
112
+
113
+ - id: CARGO-SEC-005
114
+ name: "Procedural macro crate executes during compilation"
115
+ description: "A proc-macro crate runs arbitrary code in the compiler on the build host, before any of the project's own code runs"
116
+ severity: low
117
+ category: cargo-security
118
+ dry-run-support: full
119
+ condition: |
120
+ $append(components, formulation.components)[
121
+ $prop($, 'cdx:cargo:procMacro') = 'true'
122
+ ]
123
+ location: |
124
+ { "bomRef": $."bom-ref", "purl": purl }
125
+ message: "Crate '{{ name }}' is a procedural macro and runs in the compiler on every build"
126
+ mitigation: "Treat this crate's compromise as equivalent to build-host compromise. Review its publisher and release history, pin it, and confirm the build host has no credentials a compile-time macro should not reach"
127
+ evidence: |
128
+ {
129
+ "dependencyKind": $prop($, 'cdx:cargo:dependencyKind'),
130
+ "publisher": $prop($, 'cdx:cargo:publisher'),
131
+ "resolvedFeatures": $prop($, 'cdx:cargo:resolvedFeatures')
132
+ }
@@ -386,3 +386,125 @@
386
386
  "configuredServiceCount": $prop($, 'cdx:mcp:configuredServiceCount'),
387
387
  "configuredServiceNames": $prop($, 'cdx:mcp:configuredServiceNames')
388
388
  }
389
+
390
+ - id: MCP-009
391
+ name: "MCP configuration relies on deprecated protocol features"
392
+ description: "The MCP 2026-07-28 specification deprecates the legacy HTTP+SSE transport, dynamic client registration, sampling, logging, and roots. Configurations that still depend on these features need a migration plan before the deprecation window closes."
393
+ severity: medium
394
+ category: mcp-server
395
+ dry-run-support: full
396
+ standards:
397
+ owasp-ai-top-10:
398
+ - "LLM05: Supply Chain Vulnerabilities"
399
+ - "LLM03:2025 Supply Chain"
400
+ owasp-agentic-top-10-2026:
401
+ - "Agentic Supply Chain"
402
+ eu-ai-act:
403
+ - "Technical documentation and traceability"
404
+ eu-cra:
405
+ - "Technical documentation for software components"
406
+ nist-ai-rmf:
407
+ - "Govern"
408
+ - "Map"
409
+ nist-ssdf:
410
+ - "Plan migration away from deprecated protocol features"
411
+ condition: |
412
+ $auditServices($)[
413
+ $nullSafeProp($, 'cdx:mcp:deprecatedFeatures') != ''
414
+ ]
415
+ location: |
416
+ {
417
+ "bomRef": $."bom-ref",
418
+ "file": $prop($, 'internal:SrcFile')
419
+ }
420
+ message: "MCP service '{{ name }}' uses deprecated protocol features"
421
+ mitigation: "Migrate off legacy SSE transport, dynamic client registration, sampling, logging, and roots to the MCP 2026-07-28 replacements within the deprecation window."
422
+ evidence: |
423
+ {
424
+ "protocolVersion": $prop($, 'cdx:mcp:protocolVersion'),
425
+ "deprecatedFeatures": $prop($, 'cdx:mcp:deprecatedFeatures'),
426
+ "transport": $prop($, 'cdx:mcp:transport')
427
+ }
428
+
429
+ - id: MCP-010
430
+ name: "MCP bundle declares secret configuration fields"
431
+ description: "MCPB/DXT bundles that declare secret-typed user_config fields have those values injected into the bundled server's environment on launch. Declaring such a field is the correct way to build a bundle, so this is an inventory disclosure to aid credential-handling review rather than a defect."
432
+ severity: low
433
+ category: mcp-server
434
+ dry-run-support: full
435
+ standards:
436
+ owasp-ai-top-10:
437
+ - "LLM05: Supply Chain Vulnerabilities"
438
+ - "LLM03:2025 Supply Chain"
439
+ owasp-agentic-top-10-2026:
440
+ - "Agentic Supply Chain"
441
+ eu-ai-act:
442
+ - "Technical documentation and traceability"
443
+ eu-cra:
444
+ - "Software supply chain visibility"
445
+ nist-ai-rmf:
446
+ - "Govern"
447
+ nist-ssdf:
448
+ - "Review secret handling in installable AI extensions"
449
+ condition: |
450
+ components[
451
+ $prop($, 'cdx:file:kind') = 'mcp-bundle'
452
+ and $prop($, 'cdx:mcpb:injectsSecretEnv') = 'true'
453
+ ]
454
+ location: |
455
+ {
456
+ "bomRef": $."bom-ref",
457
+ "file": $prop($, 'internal:SrcFile')
458
+ }
459
+ message: "MCP bundle '{{ name }}' declares secret configuration fields injected as environment variables"
460
+ mitigation: "Review the declared secret fields and prefer runtime secret stores or references over values captured through the extension manifest."
461
+ evidence: |
462
+ {
463
+ "serverType": $prop($, 'cdx:mcpb:serverType'),
464
+ "secretFieldCount": $prop($, 'cdx:mcpb:secretFieldCount'),
465
+ "platformBinaryCount": $prop($, 'cdx:mcpb:platformBinaryCount')
466
+ }
467
+
468
+ - id: MCP-011
469
+ name: "MCP bundle ships precompiled platform binaries"
470
+ description: "MCPB/DXT bundles that ship precompiled per-platform binaries execute vendor-provided native code on the host with no build-from-source step. These binaries deserve provenance and signing review before a bundle is installed."
471
+ severity: medium
472
+ category: mcp-server
473
+ dry-run-support: full
474
+ attack:
475
+ tactics: [TA0002]
476
+ techniques: [T1195.002]
477
+ standards:
478
+ owasp-ai-top-10:
479
+ - "LLM05: Supply Chain Vulnerabilities"
480
+ - "LLM03:2025 Supply Chain"
481
+ owasp-agentic-top-10-2026:
482
+ - "Agentic Supply Chain"
483
+ eu-ai-act:
484
+ - "Technical documentation and traceability"
485
+ - "Accuracy, robustness and cybersecurity"
486
+ eu-cra:
487
+ - "Software supply chain visibility"
488
+ - "Protection against untrusted code execution"
489
+ nist-ai-rmf:
490
+ - "Map"
491
+ - "Manage"
492
+ nist-ssdf:
493
+ - "Verify provenance of precompiled binaries before execution"
494
+ condition: |
495
+ components[
496
+ $prop($, 'cdx:file:kind') = 'mcp-bundle'
497
+ and $number($nullSafeProp($, 'cdx:mcpb:platformBinaryCount')) > 0
498
+ ]
499
+ location: |
500
+ {
501
+ "bomRef": $."bom-ref",
502
+ "file": $prop($, 'internal:SrcFile')
503
+ }
504
+ message: "MCP bundle '{{ name }}' ships precompiled platform binaries"
505
+ mitigation: "Verify the provenance and signatures of the bundled platform binaries, or prefer a bundle that builds from source, before installing."
506
+ evidence: |
507
+ {
508
+ "serverType": $prop($, 'cdx:mcpb:serverType'),
509
+ "platformBinaryCount": $prop($, 'cdx:mcpb:platformBinaryCount')
510
+ }
@@ -465,8 +465,13 @@ export async function enrichInputBomsWithRegistryMetadata(inputBoms) {
465
465
  process.env.CDXGEN_FETCH_PKG_METADATA = "true";
466
466
  try {
467
467
  const enrichedCandidates = [
468
+ // The audit scores publisher drift, ownership and release cadence, none
469
+ // of which the local Cargo registry records: it knows when a version was
470
+ // published but not by whom. This path pays the registry's rate limit
471
+ // deliberately rather than audit against metadata that cannot answer the
472
+ // questions the rules ask.
468
473
  ...(cargoCandidates.length
469
- ? await getCratesMetadata(cargoCandidates)
474
+ ? await getCratesMetadata(cargoCandidates, { preferLocalCache: false })
470
475
  : []),
471
476
  ...(npmCandidates.length ? await getNpmMetadata(npmCandidates) : []),
472
477
  ...(pypiCandidates.length