@cyclonedx/cdxgen 12.3.0 → 12.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +15 -5
  2. package/bin/audit.js +7 -0
  3. package/bin/cdxgen.js +241 -81
  4. package/bin/repl.js +138 -0
  5. package/data/rules/ai-agent-governance.yaml +249 -0
  6. package/data/rules/dependency-sources.yaml +41 -0
  7. package/data/rules/mcp-servers.yaml +304 -0
  8. package/data/rules/package-integrity.yaml +123 -0
  9. package/lib/audit/index.js +353 -29
  10. package/lib/audit/index.poku.js +247 -7
  11. package/lib/audit/reporters.js +26 -0
  12. package/lib/audit/scoring.js +262 -13
  13. package/lib/audit/scoring.poku.js +179 -0
  14. package/lib/audit/targets.js +391 -2
  15. package/lib/audit/targets.poku.js +416 -3
  16. package/lib/cli/index.js +588 -45
  17. package/lib/cli/index.poku.js +735 -1
  18. package/lib/evinser/evinser.js +8 -5
  19. package/lib/helpers/agentFormulationParser.js +318 -0
  20. package/lib/helpers/aiInventory.js +262 -0
  21. package/lib/helpers/aiInventory.poku.js +111 -0
  22. package/lib/helpers/analyzer.js +1769 -0
  23. package/lib/helpers/analyzer.poku.js +284 -3
  24. package/lib/helpers/auditCategories.js +76 -0
  25. package/lib/helpers/ciParsers/githubActions.js +140 -16
  26. package/lib/helpers/ciParsers/githubActions.poku.js +110 -0
  27. package/lib/helpers/communityAiConfigParser.js +672 -0
  28. package/lib/helpers/communityAiConfigParser.poku.js +63 -0
  29. package/lib/helpers/depsUtils.js +108 -0
  30. package/lib/helpers/depsUtils.poku.js +72 -1
  31. package/lib/helpers/display.js +325 -3
  32. package/lib/helpers/display.poku.js +301 -0
  33. package/lib/helpers/formulationParsers.js +28 -0
  34. package/lib/helpers/formulationParsers.poku.js +504 -1
  35. package/lib/helpers/jsonLike.js +102 -0
  36. package/lib/helpers/jsonLike.poku.js +34 -0
  37. package/lib/helpers/mcp.js +248 -0
  38. package/lib/helpers/mcp.poku.js +101 -0
  39. package/lib/helpers/mcpConfigParser.js +656 -0
  40. package/lib/helpers/mcpConfigParser.poku.js +126 -0
  41. package/lib/helpers/mcpDiscovery.js +84 -0
  42. package/lib/helpers/mcpDiscovery.poku.js +21 -0
  43. package/lib/helpers/protobom.js +3 -3
  44. package/lib/helpers/provenanceUtils.js +29 -4
  45. package/lib/helpers/provenanceUtils.poku.js +29 -3
  46. package/lib/helpers/registryProvenance.js +210 -0
  47. package/lib/helpers/registryProvenance.poku.js +144 -0
  48. package/lib/helpers/rustFormulationParser.js +330 -0
  49. package/lib/helpers/source.js +21 -2
  50. package/lib/helpers/source.poku.js +38 -0
  51. package/lib/helpers/utils.js +1331 -83
  52. package/lib/helpers/utils.poku.js +599 -188
  53. package/lib/helpers/vsixutils.js +12 -4
  54. package/lib/helpers/vsixutils.poku.js +34 -0
  55. package/lib/managers/binary.js +36 -12
  56. package/lib/managers/binary.poku.js +68 -0
  57. package/lib/managers/docker.js +59 -9
  58. package/lib/managers/docker.poku.js +61 -0
  59. package/lib/managers/piptree.js +12 -7
  60. package/lib/managers/piptree.poku.js +44 -0
  61. package/lib/stages/postgen/annotator.js +2 -1
  62. package/lib/stages/postgen/annotator.poku.js +15 -0
  63. package/lib/stages/postgen/auditBom.js +20 -6
  64. package/lib/stages/postgen/auditBom.poku.js +694 -1
  65. package/lib/stages/postgen/postgen.js +262 -11
  66. package/lib/stages/postgen/postgen.poku.js +306 -2
  67. package/lib/stages/postgen/ruleEngine.js +49 -1
  68. package/lib/stages/postgen/spdxConverter.poku.js +70 -0
  69. package/lib/stages/pregen/pregen.js +6 -4
  70. package/package.json +1 -1
  71. package/types/bin/repl.d.ts.map +1 -1
  72. package/types/lib/audit/index.d.ts.map +1 -1
  73. package/types/lib/audit/reporters.d.ts.map +1 -1
  74. package/types/lib/audit/scoring.d.ts.map +1 -1
  75. package/types/lib/audit/targets.d.ts +12 -0
  76. package/types/lib/audit/targets.d.ts.map +1 -1
  77. package/types/lib/cli/index.d.ts +2 -8
  78. package/types/lib/cli/index.d.ts.map +1 -1
  79. package/types/lib/evinser/evinser.d.ts.map +1 -1
  80. package/types/lib/helpers/agentFormulationParser.d.ts +19 -0
  81. package/types/lib/helpers/agentFormulationParser.d.ts.map +1 -0
  82. package/types/lib/helpers/aiInventory.d.ts +23 -0
  83. package/types/lib/helpers/aiInventory.d.ts.map +1 -0
  84. package/types/lib/helpers/analyzer.d.ts +10 -0
  85. package/types/lib/helpers/analyzer.d.ts.map +1 -1
  86. package/types/lib/helpers/auditCategories.d.ts +12 -0
  87. package/types/lib/helpers/auditCategories.d.ts.map +1 -0
  88. package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -1
  89. package/types/lib/helpers/communityAiConfigParser.d.ts +29 -0
  90. package/types/lib/helpers/communityAiConfigParser.d.ts.map +1 -0
  91. package/types/lib/helpers/depsUtils.d.ts +8 -0
  92. package/types/lib/helpers/depsUtils.d.ts.map +1 -1
  93. package/types/lib/helpers/display.d.ts +17 -1
  94. package/types/lib/helpers/display.d.ts.map +1 -1
  95. package/types/lib/helpers/formulationParsers.d.ts.map +1 -1
  96. package/types/lib/helpers/jsonLike.d.ts +4 -0
  97. package/types/lib/helpers/jsonLike.d.ts.map +1 -0
  98. package/types/lib/helpers/mcp.d.ts +29 -0
  99. package/types/lib/helpers/mcp.d.ts.map +1 -0
  100. package/types/lib/helpers/mcpConfigParser.d.ts +30 -0
  101. package/types/lib/helpers/mcpConfigParser.d.ts.map +1 -0
  102. package/types/lib/helpers/mcpDiscovery.d.ts +5 -0
  103. package/types/lib/helpers/mcpDiscovery.d.ts.map +1 -0
  104. package/types/lib/helpers/provenanceUtils.d.ts +5 -3
  105. package/types/lib/helpers/provenanceUtils.d.ts.map +1 -1
  106. package/types/lib/helpers/registryProvenance.d.ts +9 -0
  107. package/types/lib/helpers/registryProvenance.d.ts.map +1 -1
  108. package/types/lib/helpers/rustFormulationParser.d.ts +17 -0
  109. package/types/lib/helpers/rustFormulationParser.d.ts.map +1 -0
  110. package/types/lib/helpers/source.d.ts.map +1 -1
  111. package/types/lib/helpers/utils.d.ts +31 -1
  112. package/types/lib/helpers/utils.d.ts.map +1 -1
  113. package/types/lib/helpers/vsixutils.d.ts.map +1 -1
  114. package/types/lib/managers/binary.d.ts.map +1 -1
  115. package/types/lib/managers/docker.d.ts.map +1 -1
  116. package/types/lib/managers/piptree.d.ts.map +1 -1
  117. package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
  118. package/types/lib/stages/postgen/auditBom.d.ts.map +1 -1
  119. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  120. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
  121. package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
@@ -0,0 +1,304 @@
1
+ - id: MCP-001
2
+ name: "Unauthenticated MCP tool server endpoint"
3
+ description: "HTTP-based MCP servers that expose tools without authentication let unauthenticated clients invoke model-controlled actions directly."
4
+ severity: critical
5
+ category: mcp-server
6
+ attack:
7
+ tactics: [TA0001, TA0004]
8
+ techniques: [T1190, T1059]
9
+ standards:
10
+ owasp-ai-top-10:
11
+ - "LLM07: Insecure Plugin Design"
12
+ - "LLM08: Excessive Agency"
13
+ nist-ai-rmf:
14
+ - "Map"
15
+ - "Manage"
16
+ nist-ssdf:
17
+ - "Protect externally reachable AI control surfaces"
18
+ condition: |
19
+ $auditServices($)[
20
+ $contains($nullSafeProp($, 'cdx:mcp:transport'), 'streamable-http')
21
+ and authenticated != true
22
+ and (
23
+ $prop($, 'cdx:mcp:capabilities:tools') = 'true'
24
+ or $prop($, 'cdx:mcp:toolCount') != '0'
25
+ )
26
+ ]
27
+ location: |
28
+ {
29
+ "bomRef": $."bom-ref",
30
+ "file": $prop($, 'SrcFile'),
31
+ "purl": endpoints[0]
32
+ }
33
+ message: "MCP server '{{ name }}' exposes tool endpoints without authentication"
34
+ mitigation: "Require bearer-token or equivalent authentication before exposing HTTP MCP tool endpoints."
35
+ evidence: |
36
+ {
37
+ "transport": $prop($, 'cdx:mcp:transport'),
38
+ "toolCount": $prop($, 'cdx:mcp:toolCount'),
39
+ "endpoints": endpoints,
40
+ "sdkImports": $prop($, 'cdx:mcp:sdkImports')
41
+ }
42
+ - id: MCP-002
43
+ name: "Unauthenticated MCP HTTP server"
44
+ description: "Streamable HTTP MCP servers should authenticate incoming requests before serving prompts, resources, or tools."
45
+ severity: high
46
+ category: mcp-server
47
+ attack:
48
+ tactics: [TA0001]
49
+ techniques: [T1190]
50
+ standards:
51
+ owasp-ai-top-10:
52
+ - "LLM07: Insecure Plugin Design"
53
+ nist-ai-rmf:
54
+ - "Map"
55
+ - "Manage"
56
+ nist-ssdf:
57
+ - "Authenticate and authorize AI-facing service endpoints"
58
+ condition: |
59
+ $auditServices($)[
60
+ $contains($nullSafeProp($, 'cdx:mcp:transport'), 'streamable-http')
61
+ and authenticated != true
62
+ ]
63
+ location: |
64
+ {
65
+ "bomRef": $."bom-ref",
66
+ "file": $prop($, 'SrcFile'),
67
+ "purl": endpoints[0]
68
+ }
69
+ message: "MCP HTTP endpoint '{{ endpoints[0] }}' is reachable without authentication"
70
+ mitigation: "Protect MCP HTTP endpoints with authentication and validate Origin/host binding for local deployments."
71
+ evidence: |
72
+ {
73
+ "officialSdk": $prop($, 'cdx:mcp:officialSdk'),
74
+ "transport": $prop($, 'cdx:mcp:transport'),
75
+ "promptCount": $prop($, 'cdx:mcp:promptCount'),
76
+ "resourceCount": $prop($, 'cdx:mcp:resourceCount'),
77
+ "toolCount": $prop($, 'cdx:mcp:toolCount')
78
+ }
79
+ - id: MCP-003
80
+ name: "Network-exposed non-official MCP server"
81
+ description: "MCP servers built on non-official SDKs or wrappers deserve extra review before being exposed over HTTP, especially when they register tools."
82
+ severity: medium
83
+ category: mcp-server
84
+ attack:
85
+ tactics: [TA0001, TA0005]
86
+ techniques: [T1195.001]
87
+ standards:
88
+ owasp-ai-top-10:
89
+ - "LLM05: Supply Chain Vulnerabilities"
90
+ - "LLM07: Insecure Plugin Design"
91
+ nist-ai-rmf:
92
+ - "Govern"
93
+ - "Map"
94
+ nist-ssdf:
95
+ - "Verify provenance of AI and automation integrations"
96
+ condition: |
97
+ $auditServices($)[
98
+ $contains($nullSafeProp($, 'cdx:mcp:transport'), 'streamable-http')
99
+ and $prop($, 'cdx:mcp:officialSdk') = 'false'
100
+ and (
101
+ $prop($, 'cdx:mcp:capabilities:tools') = 'true'
102
+ or $prop($, 'cdx:mcp:toolCount') != '0'
103
+ or $count(endpoints) > 0
104
+ )
105
+ ]
106
+ location: |
107
+ {
108
+ "bomRef": $."bom-ref",
109
+ "file": $prop($, 'SrcFile'),
110
+ "purl": endpoints[0]
111
+ }
112
+ message: "MCP server '{{ name }}' is network-accessible but relies on a non-official SDK or wrapper"
113
+ mitigation: "Review the SDK provenance, pin exact versions, and harden authentication/authorization before exposing the server."
114
+ evidence: |
115
+ {
116
+ "sdkImports": $prop($, 'cdx:mcp:sdkImports'),
117
+ "toolCount": $prop($, 'cdx:mcp:toolCount'),
118
+ "providerNames": $prop($, 'cdx:mcp:providerNames'),
119
+ "modelNames": $prop($, 'cdx:mcp:modelNames')
120
+ }
121
+
122
+ - id: MCP-004
123
+ name: "Configured MCP endpoint lacks auth posture"
124
+ description: "MCP services discovered only from client configuration files still need explicit authentication or OAuth posture when they resolve to network-accessible HTTP endpoints."
125
+ severity: high
126
+ category: mcp-server
127
+ attack:
128
+ tactics: [TA0001]
129
+ techniques: [T1190]
130
+ standards:
131
+ owasp-ai-top-10:
132
+ - "LLM07: Insecure Plugin Design"
133
+ - "LLM08: Excessive Agency"
134
+ nist-ai-rmf:
135
+ - "Map"
136
+ - "Manage"
137
+ nist-ssdf:
138
+ - "Review and harden configured external AI control surfaces"
139
+ condition: |
140
+ $auditServices($)[
141
+ $prop($, 'cdx:mcp:inventorySource') = 'config-file'
142
+ and $contains($nullSafeProp($, 'cdx:mcp:transport'), 'http')
143
+ and authenticated != true
144
+ ]
145
+ location: |
146
+ {
147
+ "bomRef": $."bom-ref",
148
+ "file": $prop($, 'SrcFile'),
149
+ "purl": endpoints[0]
150
+ }
151
+ message: "Configured MCP endpoint '{{ endpoints[0] }}' lacks any discovered auth posture"
152
+ mitigation: "Document bearer or OAuth requirements for configured MCP endpoints before allowing clients to auto-connect."
153
+ evidence: |
154
+ {
155
+ "configFormat": $prop($, 'cdx:mcp:configFormat'),
156
+ "configKey": $prop($, 'cdx:mcp:configKey'),
157
+ "authPosture": $prop($, 'cdx:mcp:authPosture'),
158
+ "trustProfile": $prop($, 'cdx:mcp:trustProfile')
159
+ }
160
+
161
+ - id: MCP-005
162
+ name: "MCP configuration exposes inline credentials"
163
+ description: "MCP configs that embed tokens, API keys, or other secrets directly in args, env values, or headers create immediate credential-handling and supply-chain review risk."
164
+ severity: critical
165
+ category: mcp-server
166
+ attack:
167
+ tactics: [TA0006]
168
+ techniques: [T1552]
169
+ standards:
170
+ owasp-ai-top-10:
171
+ - "LLM05: Supply Chain Vulnerabilities"
172
+ - "LLM07: Insecure Plugin Design"
173
+ nist-ai-rmf:
174
+ - "Govern"
175
+ - "Manage"
176
+ nist-ssdf:
177
+ - "Protect secrets used by automation and AI integrations"
178
+ condition: |
179
+ $auditServices($)[
180
+ $prop($, 'cdx:mcp:inventorySource') = 'config-file'
181
+ and $prop($, 'cdx:mcp:credentialExposure') = 'true'
182
+ ]
183
+ location: |
184
+ {
185
+ "bomRef": $."bom-ref",
186
+ "file": $prop($, 'SrcFile')
187
+ }
188
+ message: "MCP config entry '{{ name }}' exposes inline credentials"
189
+ mitigation: "Move secrets out of config files and command args into secret stores or environment references that can be managed separately."
190
+ evidence: |
191
+ {
192
+ "configFormat": $prop($, 'cdx:mcp:configFormat'),
193
+ "configKey": $prop($, 'cdx:mcp:configKey'),
194
+ "credentialExposureFieldCount": $prop($, 'cdx:mcp:credentialExposureFieldCount'),
195
+ "credentialIndicatorCount": $prop($, 'cdx:mcp:credentialIndicatorCount'),
196
+ "credentialReferenceCount": $prop($, 'cdx:mcp:credentialReferenceCount')
197
+ }
198
+
199
+ - id: MCP-006
200
+ name: "MCP configuration suggests confused-deputy risk"
201
+ description: "Dynamic client registration combined with a static configured client ID can create confused-deputy style authorization risk in MCP deployments."
202
+ severity: high
203
+ category: mcp-server
204
+ attack:
205
+ tactics: [TA0004]
206
+ techniques: [T1528]
207
+ standards:
208
+ owasp-ai-top-10:
209
+ - "LLM07: Insecure Plugin Design"
210
+ - "LLM08: Excessive Agency"
211
+ nist-ai-rmf:
212
+ - "Govern"
213
+ - "Map"
214
+ nist-ssdf:
215
+ - "Review AI authorization delegation and client registration flows"
216
+ condition: |
217
+ $auditServices($)[
218
+ $prop($, 'cdx:mcp:inventorySource') = 'config-file'
219
+ and $prop($, 'cdx:mcp:security:confusedDeputyRisk') = 'high'
220
+ ]
221
+ location: |
222
+ {
223
+ "bomRef": $."bom-ref",
224
+ "file": $prop($, 'SrcFile')
225
+ }
226
+ message: "MCP config entry '{{ name }}' combines dynamic client registration with a static client identity"
227
+ mitigation: "Avoid mixing DCR with shared static client identities; isolate delegated clients and validate downstream authorization assumptions."
228
+ evidence: |
229
+ {
230
+ "configFormat": $prop($, 'cdx:mcp:configFormat'),
231
+ "configKey": $prop($, 'cdx:mcp:configKey'),
232
+ "supportsDCR": $prop($, 'cdx:mcp:auth:supportsDCR'),
233
+ "authPosture": $prop($, 'cdx:mcp:authPosture')
234
+ }
235
+
236
+ - id: MCP-007
237
+ name: "MCP configuration forwards bearer or access tokens"
238
+ description: "Token-forwarding and passthrough settings in MCP configs deserve review because they can propagate delegated credentials across trust boundaries."
239
+ severity: high
240
+ category: mcp-server
241
+ attack:
242
+ tactics: [TA0006]
243
+ techniques: [T1528]
244
+ standards:
245
+ owasp-ai-top-10:
246
+ - "LLM07: Insecure Plugin Design"
247
+ - "LLM08: Excessive Agency"
248
+ nist-ai-rmf:
249
+ - "Govern"
250
+ - "Manage"
251
+ nist-ssdf:
252
+ - "Review delegated token forwarding and trust-boundary crossings"
253
+ condition: |
254
+ $auditServices($)[
255
+ $prop($, 'cdx:mcp:inventorySource') = 'config-file'
256
+ and $prop($, 'cdx:mcp:security:tokenPassthroughRisk') = 'high'
257
+ ]
258
+ location: |
259
+ {
260
+ "bomRef": $."bom-ref",
261
+ "file": $prop($, 'SrcFile')
262
+ }
263
+ message: "MCP config entry '{{ name }}' forwards or passes through bearer-like credentials"
264
+ mitigation: "Prefer server-side credential exchange or scoped token minting instead of forwarding end-user tokens through MCP configs."
265
+ evidence: |
266
+ {
267
+ "configFormat": $prop($, 'cdx:mcp:configFormat'),
268
+ "configKey": $prop($, 'cdx:mcp:configKey'),
269
+ "trustProfile": $prop($, 'cdx:mcp:trustProfile'),
270
+ "authPosture": $prop($, 'cdx:mcp:authPosture')
271
+ }
272
+
273
+ - id: MCP-008
274
+ name: "MCP configuration file is included in a build or post-build SBOM"
275
+ description: "Committed MCP client configuration files can carry trust, auth, and distribution sensitivity even when they are not actively used during the current scan."
276
+ severity: medium
277
+ category: mcp-server
278
+ standards:
279
+ owasp-ai-top-10:
280
+ - "LLM07: Insecure Plugin Design"
281
+ - "LLM08: Excessive Agency"
282
+ nist-ai-rmf:
283
+ - "Govern"
284
+ - "Map"
285
+ nist-ssdf:
286
+ - "Review configured AI control surfaces before release"
287
+ condition: |
288
+ components[
289
+ $prop($, 'cdx:file:kind') = 'mcp-config'
290
+ and $count($$.metadata.lifecycles[phase = 'build' or phase = 'post-build']) > 0
291
+ ]
292
+ location: |
293
+ {
294
+ "bomRef": $."bom-ref",
295
+ "file": $prop($, 'SrcFile')
296
+ }
297
+ message: "MCP config file '{{ name }}' is included in a build/post-build SBOM"
298
+ mitigation: "Review the config with '--bom-audit --bom-audit-categories mcp-server', consider '--tlp-classification AMBER' before sharing the BOM broadly, or rerun with '--exclude-type mcp' if config artifacts should be omitted."
299
+ evidence: |
300
+ {
301
+ "configFormat": $prop($, 'cdx:mcp:configFormat'),
302
+ "configuredServiceCount": $prop($, 'cdx:mcp:configuredServiceCount'),
303
+ "configuredServiceNames": $prop($, 'cdx:mcp:configuredServiceNames')
304
+ }
@@ -182,3 +182,126 @@
182
182
  "indicatorMap": $prop($, 'cdx:npm:lifecycleIndicatorMap')
183
183
  }
184
184
 
185
+ - id: INT-010
186
+ name: "Yanked Cargo crate in dependency tree"
187
+ description: "Crates yanked from crates.io are often removed because of security, correctness, or ecosystem breakage issues"
188
+ severity: high
189
+ category: package-integrity
190
+ condition: |
191
+ components[
192
+ $prop($, 'cdx:cargo:yanked') = 'true'
193
+ ]
194
+ location: |
195
+ { "bomRef": $."bom-ref", "purl": purl }
196
+ message: "Cargo crate '{{ name }}@{{ version }}' has been yanked from crates.io"
197
+ mitigation: "Update to a non-yanked release and review any recent publisher or release-cadence changes before upgrading"
198
+ evidence: |
199
+ {
200
+ "publisher": $prop($, 'cdx:cargo:publisher'),
201
+ "priorPublisher": $prop($, 'cdx:cargo:priorPublisher'),
202
+ "publishTime": $prop($, 'cdx:cargo:publishTime'),
203
+ "releaseGapDays": $prop($, 'cdx:cargo:releaseGapDays')
204
+ }
205
+
206
+ - id: INT-011
207
+ name: "Rust project uses native Cargo build surface"
208
+ description: "Cargo build scripts and native build helpers expand execution surface during build and deserve additional review before release"
209
+ severity: medium
210
+ category: package-integrity
211
+ condition: |
212
+ formulation.components[
213
+ $prop($, 'cdx:rust:buildTool') = 'cargo'
214
+ and $prop($, 'cdx:cargo:hasNativeBuild') = 'true'
215
+ ]
216
+ location: |
217
+ {
218
+ "bomRef": $."bom-ref",
219
+ "file": $prop($, 'SrcFile')
220
+ }
221
+ message: "Rust project '{{ name }}' uses Cargo build.rs or native build helpers"
222
+ mitigation: "Review `build.rs`, native build dependencies, and release workflows to ensure the build remains hermetic and expected"
223
+ evidence: |
224
+ {
225
+ "buildScript": $prop($, 'cdx:cargo:buildScript'),
226
+ "nativeBuildIndicators": $prop($, 'cdx:cargo:nativeBuildIndicators'),
227
+ "releaseProfiles": $prop($, 'cdx:cargo:releaseProfiles')
228
+ }
229
+
230
+ - id: INT-012
231
+ name: "Rust native build uses mutable Cargo setup action"
232
+ description: "Native Cargo build surfaces deserve additional scrutiny when the workflow relies on mutable Cargo toolchain setup actions instead of immutable SHA-pinned references"
233
+ severity: medium
234
+ category: package-integrity
235
+ condition: |
236
+ formulation.components[
237
+ $prop($, 'cdx:rust:buildTool') = 'cargo'
238
+ and $prop($, 'cdx:cargo:hasNativeBuild') = 'true'
239
+ and $count($$.components[
240
+ $prop($, 'cdx:github:action:ecosystem') = 'cargo'
241
+ and $contains($prop($, 'cdx:github:action:role'), 'toolchain')
242
+ and $prop($, 'cdx:github:action:versionPinningType') != 'sha'
243
+ ]) > 0
244
+ ]
245
+ location: |
246
+ {
247
+ "bomRef": $."bom-ref",
248
+ "file": $prop($, 'SrcFile')
249
+ }
250
+ message: "Rust project '{{ name }}' combines native Cargo build surfaces with mutable Cargo toolchain setup actions"
251
+ mitigation: "Prefer SHA-pinned Cargo toolchain setup actions for release workflows, especially when build.rs or native helpers run during CI"
252
+ evidence: |
253
+ {
254
+ "buildScript": $prop($, 'cdx:cargo:buildScript'),
255
+ "buildScriptCapabilities": $prop($, 'cdx:cargo:buildScriptCapabilities'),
256
+ "toolchainActions": $$.components[
257
+ $prop($, 'cdx:github:action:ecosystem') = 'cargo'
258
+ and $contains($prop($, 'cdx:github:action:role'), 'toolchain')
259
+ and $prop($, 'cdx:github:action:versionPinningType') != 'sha'
260
+ ].$prop($, 'cdx:github:action:uses')
261
+ }
262
+
263
+ - id: INT-013
264
+ name: "Rust native build is exercised by Cargo workflow steps"
265
+ description: "Cargo workflows that execute build/test/package/publish steps against native build surfaces increase the impact of build-script or native-helper changes"
266
+ severity: medium
267
+ category: package-integrity
268
+ condition: |
269
+ formulation.components[
270
+ $prop($, 'cdx:rust:buildTool') = 'cargo'
271
+ and $prop($, 'cdx:cargo:hasNativeBuild') = 'true'
272
+ and (
273
+ $contains($prop($, 'cdx:cargo:buildScriptCapabilities'), 'process-execution')
274
+ or $contains($prop($, 'cdx:cargo:buildScriptCapabilities'), 'network-access')
275
+ or $contains($prop($, 'cdx:cargo:nativeBuildIndicators'), '-sys')
276
+ )
277
+ and $count($$.components[
278
+ $prop($, 'cdx:github:step:usesCargo') = 'true'
279
+ and (
280
+ $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'build')
281
+ or $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'test')
282
+ or $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'package')
283
+ or $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'publish')
284
+ )
285
+ ]) > 0
286
+ ]
287
+ location: |
288
+ {
289
+ "bomRef": $."bom-ref",
290
+ "file": $prop($, 'SrcFile')
291
+ }
292
+ message: "Rust project '{{ name }}' runs Cargo build/test/package workflow steps against a native build surface"
293
+ mitigation: "Review build.rs, native helper crates, and workflow command scope before merging or publishing releases that exercise native build logic"
294
+ evidence: |
295
+ {
296
+ "buildScriptCapabilities": $prop($, 'cdx:cargo:buildScriptCapabilities'),
297
+ "nativeBuildIndicators": $prop($, 'cdx:cargo:nativeBuildIndicators'),
298
+ "cargoCommands": $$.components[
299
+ $prop($, 'cdx:github:step:usesCargo') = 'true'
300
+ and (
301
+ $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'build')
302
+ or $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'test')
303
+ or $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'package')
304
+ or $contains($prop($, 'cdx:github:step:cargoSubcommands'), 'publish')
305
+ )
306
+ ].$prop($, 'cdx:github:step:command')
307
+ }