@cdxgen/cdxgen 13.4.0 → 13.6.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 (305) hide show
  1. package/README.md +9 -9
  2. package/bin/cdxgen-secure.js +15 -0
  3. package/bin/cdxgen.js +29 -5
  4. package/bin/evinse.js +8 -0
  5. package/bin/hbom.js +15 -7
  6. package/bin/repl.js +29 -0
  7. package/bin/validate.js +6 -0
  8. package/data/cbomosdb-queries.json +13 -1
  9. package/data/component-tags.json +8 -0
  10. package/data/license-aliases.json +24 -2
  11. package/data/queries-darwin.json +25 -1
  12. package/data/queries-win.json +19 -1
  13. package/data/queries.json +41 -0
  14. package/data/remediations.json +407 -1
  15. package/data/rules/ai-bom.yaml +1 -1
  16. package/data/rules/brotli-decoder.yaml +107 -0
  17. package/data/rules/cbom-security.yaml +235 -4
  18. package/data/rules/go-binaries.yaml +46 -0
  19. package/data/rules/golem-go.yaml +80 -0
  20. package/data/rules/hbom-compliance.yaml +40 -22
  21. package/data/rules/hbom-performance.yaml +7 -1
  22. package/data/rules/host-topology.yaml +1 -1
  23. package/data/rules/obom-runtime.yaml +31 -2
  24. package/data/rules/php-runtime.yaml +143 -0
  25. package/data/rules/vscode-extensions.yaml +75 -0
  26. package/data/spdx-license-list.json +121 -7
  27. package/data/spdx-licenses.json +69 -0
  28. package/data/spdx.schema.json +845 -2
  29. package/lib/audit/index.js +14 -0
  30. package/lib/cli/bomAssembly.js +120 -6
  31. package/lib/cli/cliOptions.js +110 -3
  32. package/lib/cli/index.js +182 -6
  33. package/lib/cli/jsBom.js +153 -64
  34. package/lib/cli/jvmBom.js +363 -66
  35. package/lib/cli/managedBom.js +853 -87
  36. package/lib/cli/nativeBom.js +267 -33
  37. package/lib/core/boundedFile.js +344 -0
  38. package/lib/core/brotliProbe.js +182 -0
  39. package/lib/core/env.js +38 -8
  40. package/lib/core/fs.js +40 -19
  41. package/lib/core/httpClient.js +172 -46
  42. package/lib/core/lockPaths.js +38 -0
  43. package/lib/core/paths.js +24 -1
  44. package/lib/core/processTree.js +5 -0
  45. package/lib/core/projectConfig.js +1 -0
  46. package/lib/core/projectTooling.js +97 -0
  47. package/lib/core/propertySanitizer.js +72 -0
  48. package/lib/core/toolRegistry.js +170 -0
  49. package/lib/ecosystems/cppEvidence.js +263 -106
  50. package/lib/ecosystems/cppIncludeResolver.js +16 -5
  51. package/lib/ecosystems/ecosystems.js +25 -10
  52. package/lib/ecosystems/gemHostProbe.js +301 -0
  53. package/lib/ecosystems/golem.js +550 -6
  54. package/lib/ecosystems/gradleutils.js +858 -244
  55. package/lib/ecosystems/parsers-bazel.js +107 -6
  56. package/lib/ecosystems/parsers-dotnet.js +117 -18
  57. package/lib/ecosystems/parsers-go.js +1090 -367
  58. package/lib/ecosystems/parsers-js.js +505 -22
  59. package/lib/ecosystems/parsers-jvm.js +259 -17
  60. package/lib/ecosystems/parsers-misc.js +438 -64
  61. package/lib/ecosystems/parsers-python.js +100 -12
  62. package/lib/ecosystems/pythonutils.js +128 -2
  63. package/lib/ecosystems/rubyutils.js +544 -34
  64. package/lib/ecosystems/rusi.js +10 -0
  65. package/lib/ecosystems/scalacliutils.js +4 -1
  66. package/lib/ecosystems/scalasem.js +798 -151
  67. package/lib/ecosystems/vendoredCode.js +237 -3
  68. package/lib/ecosystems/venvProbe.js +360 -0
  69. package/lib/evinser/evinser.js +472 -61
  70. package/lib/evinser/swiftsem.js +68 -5
  71. package/lib/helpers/agenticToolutils.js +413 -93
  72. package/lib/helpers/vsixutils.js +1574 -315
  73. package/lib/inventory/agentSkillSpec.js +17 -0
  74. package/lib/inventory/apkInstalledDb.js +243 -0
  75. package/lib/inventory/atomUtils.js +110 -0
  76. package/lib/inventory/auditCategories.js +3 -3
  77. package/lib/inventory/brotliDecoder.js +142 -0
  78. package/lib/inventory/buildToolRateLimit.js +1 -1
  79. package/lib/inventory/cacheDir.js +52 -9
  80. package/lib/inventory/cbomutils.js +56 -7
  81. package/lib/inventory/certificates.js +2371 -0
  82. package/lib/inventory/communityAiConfigParser.js +4 -9
  83. package/lib/inventory/deps.js +41 -4
  84. package/lib/inventory/display.js +200 -3
  85. package/lib/inventory/dosai.js +639 -63
  86. package/lib/inventory/dotnetRuntime.js +217 -0
  87. package/lib/inventory/dynamic.js +45 -3
  88. package/lib/inventory/envcontext.js +475 -18
  89. package/lib/inventory/evidenceUtils.js +447 -23
  90. package/lib/inventory/fetchBatch.js +1 -1
  91. package/lib/inventory/formulationParsers.js +32 -3
  92. package/lib/inventory/goBuildInfo.js +140 -0
  93. package/lib/inventory/gtfobins.js +13 -0
  94. package/lib/inventory/hbom.js +67 -7
  95. package/lib/inventory/hbomAnalysis.js +16 -0
  96. package/lib/inventory/hostRuntimeProbe.js +686 -0
  97. package/lib/inventory/hostTopology.js +21 -0
  98. package/lib/inventory/jvmLocalRepos.js +9 -2
  99. package/lib/inventory/jvmToolEnv.js +29 -0
  100. package/lib/inventory/licenseEnhancer.js +12 -0
  101. package/lib/inventory/mavenCentralMirror.js +534 -0
  102. package/lib/inventory/nodeBuildInfo.js +218 -0
  103. package/lib/inventory/nodeHostProbe.js +202 -0
  104. package/lib/inventory/osPackagePurl.js +244 -0
  105. package/lib/inventory/osPackageResolver.js +271 -87
  106. package/lib/inventory/osinfo.js +79 -31
  107. package/lib/inventory/osqueryTransform.js +114 -5
  108. package/lib/inventory/phpBuildInfo.js +438 -0
  109. package/lib/inventory/phpHostProbe.js +185 -0
  110. package/lib/inventory/rootfsCerts.js +426 -0
  111. package/lib/inventory/rubyBuildInfo.js +972 -0
  112. package/lib/inventory/rubyHostProbe.js +218 -0
  113. package/lib/inventory/scalaCoords.js +4 -3
  114. package/lib/inventory/scalaDedupe.js +440 -0
  115. package/lib/inventory/source.js +256 -5
  116. package/lib/inventory/spdx.js +144 -0
  117. package/lib/inventory/traceRunner.js +5 -1
  118. package/lib/inventory/tracedCrypto.js +129 -0
  119. package/lib/managers/binary.js +866 -186
  120. package/lib/managers/docker.js +245 -12
  121. package/lib/parsers/email.js +277 -0
  122. package/lib/parsers/largeJson.js +62 -13
  123. package/lib/parsers/vscodeExtensionId.js +183 -0
  124. package/lib/server/server.js +198 -2
  125. package/lib/stages/postgen/annotator.js +17 -1
  126. package/lib/stages/postgen/introspection/reflect.js +4 -1
  127. package/lib/stages/postgen/postgen.js +5 -5
  128. package/lib/stages/postgen/ruleEngine.js +71 -6
  129. package/lib/stages/postgen/specVersionCompat.js +30 -0
  130. package/lib/stages/pregen/envAudit.js +1 -0
  131. package/lib/stages/pregen/pregen.js +231 -62
  132. package/lib/validator/bomValidator.js +32 -6
  133. package/lib/validator/generated/runtime.mjs +13 -0
  134. package/lib/validator/generated/validate-1.6.mjs +27 -8
  135. package/lib/validator/generated/validate-1.7.mjs +32 -13
  136. package/lib/validator/generated/validate-2.0.mjs +31 -12
  137. package/lib/validator/index.js +1 -1
  138. package/package.json +19 -18
  139. package/types/bin/cdxgen-secure.d.ts +3 -0
  140. package/types/bin/cdxgen-secure.d.ts.map +1 -0
  141. package/types/bin/repl.d.ts.map +1 -1
  142. package/types/lib/audit/index.d.ts.map +1 -1
  143. package/types/lib/cli/bomAssembly.d.ts +22 -3
  144. package/types/lib/cli/bomAssembly.d.ts.map +1 -1
  145. package/types/lib/cli/cliOptions.d.ts +43 -0
  146. package/types/lib/cli/cliOptions.d.ts.map +1 -1
  147. package/types/lib/cli/index.d.ts.map +1 -1
  148. package/types/lib/cli/jsBom.d.ts +1 -17
  149. package/types/lib/cli/jsBom.d.ts.map +1 -1
  150. package/types/lib/cli/jvmBom.d.ts +20 -0
  151. package/types/lib/cli/jvmBom.d.ts.map +1 -1
  152. package/types/lib/cli/managedBom.d.ts.map +1 -1
  153. package/types/lib/cli/nativeBom.d.ts.map +1 -1
  154. package/types/lib/core/boundedFile.d.ts +70 -0
  155. package/types/lib/core/boundedFile.d.ts.map +1 -0
  156. package/types/lib/core/brotliProbe.d.ts +37 -0
  157. package/types/lib/core/brotliProbe.d.ts.map +1 -0
  158. package/types/lib/core/env.d.ts +22 -2
  159. package/types/lib/core/env.d.ts.map +1 -1
  160. package/types/lib/core/fs.d.ts.map +1 -1
  161. package/types/lib/core/httpClient.d.ts +24 -0
  162. package/types/lib/core/httpClient.d.ts.map +1 -1
  163. package/types/lib/core/lockPaths.d.ts +19 -0
  164. package/types/lib/core/lockPaths.d.ts.map +1 -0
  165. package/types/lib/core/processTree.d.ts +2 -0
  166. package/types/lib/core/processTree.d.ts.map +1 -1
  167. package/types/lib/core/projectConfig.d.ts.map +1 -1
  168. package/types/lib/core/projectTooling.d.ts +41 -0
  169. package/types/lib/core/projectTooling.d.ts.map +1 -0
  170. package/types/lib/core/propertySanitizer.d.ts +26 -0
  171. package/types/lib/core/propertySanitizer.d.ts.map +1 -1
  172. package/types/lib/core/toolRegistry.d.ts +36 -0
  173. package/types/lib/core/toolRegistry.d.ts.map +1 -0
  174. package/types/lib/ecosystems/cppEvidence.d.ts +40 -13
  175. package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
  176. package/types/lib/ecosystems/cppIncludeResolver.d.ts +2 -1
  177. package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -1
  178. package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
  179. package/types/lib/ecosystems/gemHostProbe.d.ts +28 -0
  180. package/types/lib/ecosystems/gemHostProbe.d.ts.map +1 -0
  181. package/types/lib/ecosystems/golem.d.ts +81 -1
  182. package/types/lib/ecosystems/golem.d.ts.map +1 -1
  183. package/types/lib/ecosystems/gradleutils.d.ts +57 -21
  184. package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
  185. package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -1
  186. package/types/lib/ecosystems/parsers-dotnet.d.ts +40 -4
  187. package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
  188. package/types/lib/ecosystems/parsers-go.d.ts +85 -13
  189. package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
  190. package/types/lib/ecosystems/parsers-js.d.ts +17 -20
  191. package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
  192. package/types/lib/ecosystems/parsers-jvm.d.ts +28 -2
  193. package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
  194. package/types/lib/ecosystems/parsers-misc.d.ts +37 -58
  195. package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
  196. package/types/lib/ecosystems/parsers-python.d.ts +14 -3
  197. package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
  198. package/types/lib/ecosystems/pythonutils.d.ts +19 -1
  199. package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
  200. package/types/lib/ecosystems/rubyutils.d.ts +144 -12
  201. package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
  202. package/types/lib/ecosystems/rusi.d.ts.map +1 -1
  203. package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -1
  204. package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
  205. package/types/lib/ecosystems/vendoredCode.d.ts +26 -0
  206. package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -1
  207. package/types/lib/ecosystems/venvProbe.d.ts +40 -0
  208. package/types/lib/ecosystems/venvProbe.d.ts.map +1 -0
  209. package/types/lib/evinser/evinser.d.ts +88 -8
  210. package/types/lib/evinser/evinser.d.ts.map +1 -1
  211. package/types/lib/evinser/swiftsem.d.ts +10 -0
  212. package/types/lib/evinser/swiftsem.d.ts.map +1 -1
  213. package/types/lib/inventory/agentSkillSpec.d.ts +13 -0
  214. package/types/lib/inventory/agentSkillSpec.d.ts.map +1 -0
  215. package/types/lib/inventory/apkInstalledDb.d.ts +42 -0
  216. package/types/lib/inventory/apkInstalledDb.d.ts.map +1 -0
  217. package/types/lib/inventory/atomUtils.d.ts +33 -0
  218. package/types/lib/inventory/atomUtils.d.ts.map +1 -1
  219. package/types/lib/inventory/brotliDecoder.d.ts +58 -0
  220. package/types/lib/inventory/brotliDecoder.d.ts.map +1 -0
  221. package/types/lib/inventory/cacheDir.d.ts +12 -4
  222. package/types/lib/inventory/cacheDir.d.ts.map +1 -1
  223. package/types/lib/inventory/cbomutils.d.ts +17 -0
  224. package/types/lib/inventory/cbomutils.d.ts.map +1 -1
  225. package/types/lib/inventory/certificates.d.ts +205 -0
  226. package/types/lib/inventory/certificates.d.ts.map +1 -0
  227. package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
  228. package/types/lib/inventory/deps.d.ts +2 -1
  229. package/types/lib/inventory/deps.d.ts.map +1 -1
  230. package/types/lib/inventory/display.d.ts +18 -0
  231. package/types/lib/inventory/display.d.ts.map +1 -1
  232. package/types/lib/inventory/dosai.d.ts +162 -7
  233. package/types/lib/inventory/dosai.d.ts.map +1 -1
  234. package/types/lib/inventory/dotnetRuntime.d.ts +44 -0
  235. package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -0
  236. package/types/lib/inventory/dynamic.d.ts +6 -1
  237. package/types/lib/inventory/dynamic.d.ts.map +1 -1
  238. package/types/lib/inventory/envcontext.d.ts +92 -8
  239. package/types/lib/inventory/envcontext.d.ts.map +1 -1
  240. package/types/lib/inventory/evidenceUtils.d.ts +29 -10
  241. package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
  242. package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
  243. package/types/lib/inventory/goBuildInfo.d.ts +10 -0
  244. package/types/lib/inventory/goBuildInfo.d.ts.map +1 -0
  245. package/types/lib/inventory/gtfobins.d.ts.map +1 -1
  246. package/types/lib/inventory/hbom.d.ts.map +1 -1
  247. package/types/lib/inventory/hbomAnalysis.d.ts +10 -0
  248. package/types/lib/inventory/hbomAnalysis.d.ts.map +1 -1
  249. package/types/lib/inventory/hostRuntimeProbe.d.ts +44 -0
  250. package/types/lib/inventory/hostRuntimeProbe.d.ts.map +1 -0
  251. package/types/lib/inventory/hostTopology.d.ts.map +1 -1
  252. package/types/lib/inventory/jvmToolEnv.d.ts +12 -0
  253. package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
  254. package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -1
  255. package/types/lib/inventory/mavenCentralMirror.d.ts +170 -0
  256. package/types/lib/inventory/mavenCentralMirror.d.ts.map +1 -0
  257. package/types/lib/inventory/nodeBuildInfo.d.ts +95 -0
  258. package/types/lib/inventory/nodeBuildInfo.d.ts.map +1 -0
  259. package/types/lib/inventory/nodeHostProbe.d.ts +15 -0
  260. package/types/lib/inventory/nodeHostProbe.d.ts.map +1 -0
  261. package/types/lib/inventory/osPackagePurl.d.ts +99 -0
  262. package/types/lib/inventory/osPackagePurl.d.ts.map +1 -0
  263. package/types/lib/inventory/osPackageResolver.d.ts +44 -2
  264. package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
  265. package/types/lib/inventory/osinfo.d.ts +31 -6
  266. package/types/lib/inventory/osinfo.d.ts.map +1 -1
  267. package/types/lib/inventory/osqueryTransform.d.ts +51 -0
  268. package/types/lib/inventory/osqueryTransform.d.ts.map +1 -1
  269. package/types/lib/inventory/phpBuildInfo.d.ts +142 -0
  270. package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -0
  271. package/types/lib/inventory/phpHostProbe.d.ts +35 -0
  272. package/types/lib/inventory/phpHostProbe.d.ts.map +1 -0
  273. package/types/lib/inventory/rootfsCerts.d.ts +27 -0
  274. package/types/lib/inventory/rootfsCerts.d.ts.map +1 -0
  275. package/types/lib/inventory/rubyBuildInfo.d.ts +271 -0
  276. package/types/lib/inventory/rubyBuildInfo.d.ts.map +1 -0
  277. package/types/lib/inventory/rubyHostProbe.d.ts +47 -0
  278. package/types/lib/inventory/rubyHostProbe.d.ts.map +1 -0
  279. package/types/lib/inventory/source.d.ts +38 -0
  280. package/types/lib/inventory/source.d.ts.map +1 -1
  281. package/types/lib/inventory/spdx.d.ts +15 -0
  282. package/types/lib/inventory/spdx.d.ts.map +1 -1
  283. package/types/lib/inventory/traceRunner.d.ts +4 -1
  284. package/types/lib/inventory/traceRunner.d.ts.map +1 -1
  285. package/types/lib/inventory/tracedCrypto.d.ts +22 -0
  286. package/types/lib/inventory/tracedCrypto.d.ts.map +1 -1
  287. package/types/lib/managers/binary.d.ts +10 -0
  288. package/types/lib/managers/binary.d.ts.map +1 -1
  289. package/types/lib/managers/docker.d.ts +24 -0
  290. package/types/lib/managers/docker.d.ts.map +1 -1
  291. package/types/lib/parsers/email.d.ts +19 -0
  292. package/types/lib/parsers/email.d.ts.map +1 -0
  293. package/types/lib/parsers/largeJson.d.ts +17 -3
  294. package/types/lib/parsers/largeJson.d.ts.map +1 -1
  295. package/types/lib/server/server.d.ts +8 -0
  296. package/types/lib/server/server.d.ts.map +1 -1
  297. package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
  298. package/types/lib/stages/postgen/introspection/reflect.d.ts.map +1 -1
  299. package/types/lib/stages/postgen/ruleEngine.d.ts +7 -4
  300. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
  301. package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
  302. package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
  303. package/types/lib/stages/pregen/pregen.d.ts +26 -9
  304. package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
  305. package/types/lib/validator/bomValidator.d.ts.map +1 -1
@@ -141,21 +141,22 @@
141
141
  }
142
142
 
143
143
  - id: CBC-001
144
- name: "Expired or Expiring Certificate"
145
- description: "Certificates that have expired or are close to their expiration date will cause service disruptions or trust validation failures."
144
+ name: "Expired Certificate"
145
+ description: "A certificate whose validity ended before the audit ran will fail trust validation and cause service disruptions."
146
146
  severity: high
147
147
  category: cbom-compliance
148
148
  dry-run-support: full
149
149
  condition: |
150
150
  components[
151
151
  cryptoProperties.assetType = 'certificate'
152
- and $hasProp($, 'cdx:cert:isExpired', 'true')
152
+ and $certEndMillis(cryptoProperties.certificateProperties.notValidAfter) != null
153
+ and $certEndMillis(cryptoProperties.certificateProperties.notValidAfter) < $toMillis($now())
153
154
  ]
154
155
  location: |
155
156
  {
156
157
  "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
157
158
  }
158
- message: "Certificate for Subject '{{ cryptoProperties.certificateProperties.subjectName }}' has expired or is invalid"
159
+ message: "Certificate for Subject '{{ cryptoProperties.certificateProperties.subjectName }}' expired on {{ cryptoProperties.certificateProperties.notValidAfter }}"
159
160
  mitigation: "Renew the certificate and update the deployment trust stores."
160
161
  evidence: |
161
162
  {
@@ -163,3 +164,233 @@
163
164
  "issuer": cryptoProperties.certificateProperties.issuerName,
164
165
  "notValidAfter": cryptoProperties.certificateProperties.notValidAfter
165
166
  }
167
+
168
+ - id: CBC-002
169
+ name: "Certificate expiring within 30 days"
170
+ description: "A certificate that is still valid but expires within 30 days will soon cause trust validation failures."
171
+ severity: medium
172
+ category: cbom-compliance
173
+ dry-run-support: full
174
+ condition: |
175
+ components[
176
+ cryptoProperties.assetType = 'certificate'
177
+ and $certEndMillis(cryptoProperties.certificateProperties.notValidAfter) != null
178
+ and $certEndMillis(cryptoProperties.certificateProperties.notValidAfter) >= $toMillis($now())
179
+ and $certEndMillis(cryptoProperties.certificateProperties.notValidAfter) < ($toMillis($now()) + 2592000000)
180
+ ]
181
+ location: |
182
+ {
183
+ "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
184
+ }
185
+ message: "Certificate for Subject '{{ cryptoProperties.certificateProperties.subjectName }}' expires on {{ cryptoProperties.certificateProperties.notValidAfter }}"
186
+ mitigation: "Plan the certificate renewal and update the deployment trust stores before it expires."
187
+ evidence: |
188
+ {
189
+ "subject": cryptoProperties.certificateProperties.subjectName,
190
+ "issuer": cryptoProperties.certificateProperties.issuerName,
191
+ "notValidAfter": cryptoProperties.certificateProperties.notValidAfter
192
+ }
193
+
194
+ # The eight SPKI SHA-256 hashes Go 1.27.3 and 1.26.10 hard-code into
195
+ # crypto/x509 (CVE-2026-111943).
196
+ # https://github.com/golang/go/commit/90617fb7ceb59cf08bee7826bb51b8c8fb8c11de
197
+ - id: CBC-003
198
+ name: "Certificate or key distrusted by Go (CVE-2026-111943)"
199
+ description: "Go 1.27.3 and 1.26.10 reject every chain containing one of eight intermediate CA keys, matched by the SHA-256 of the certificate's SubjectPublicKeyInfo. The hash matches re-issued and cross-signed copies of the same key as well."
200
+ severity: high
201
+ category: cbom-security
202
+ dry-run-support: full
203
+ standards:
204
+ nist-800-53:
205
+ - "SC-13 Cryptographic Protection"
206
+ condition: |
207
+ (
208
+ $deny := [
209
+ "ebed6475c2c2d80fcb199f3fe8dd6e6b3ce60b77eb15d4e42c3dec0c6f5b5105",
210
+ "49dd353dc2b919a3770645117d0e60c16115e7d1bc259eefe734b00ea434fe5f",
211
+ "e0254c7fcdc265e2f0f8a428dabb75ab4ae039b4872d62f5ee57f0877d5a8a41",
212
+ "5c0660a2b164910d8ff589c18e14552e9e0ec237dcefe2cb736d41a4811f81a0",
213
+ "43bffa19d6ef651451f6841e019931e96f6f2eaeff28ab4b6f1ce4576de2717b",
214
+ "63ecefee431d49523bc1136c4e72d0206a477086caf606cd5cf025686c109cf8",
215
+ "ec4ffa1ad0ac88081314b7aaffef6a91f97cd57291bb5ba686c5415f5eb4f6b6",
216
+ "92c063d67e8f14db71d288e11266ffdaf69cbf115f7bab14f3bc2f68d25e0e30"
217
+ ];
218
+ components[
219
+ (
220
+ cryptoProperties.assetType = 'certificate'
221
+ or cryptoProperties.assetType = 'related-crypto-material'
222
+ )
223
+ and $exists(properties[name = 'cdx:crypto:spkiSha256'].value[$lowercase($) in $deny])
224
+ ]
225
+ )
226
+ location: |
227
+ {
228
+ "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
229
+ }
230
+ message: "Certificate or key '{{ name }}' carries a public key Go 1.27.3/1.26.10 distrust (CVE-2026-111943)"
231
+ mitigation: "Replace the certificate chain and remove the key from every trust store, bundle and pin. https://github.com/golang/go/commit/90617fb7ceb59cf08bee7826bb51b8c8fb8c11de"
232
+ evidence: |
233
+ {
234
+ "spkiSha256": $prop($, 'cdx:crypto:spkiSha256'),
235
+ "subject": cryptoProperties.certificateProperties.subjectName,
236
+ "locations": $count(evidence.occurrences)
237
+ }
238
+
239
+ - id: CBC-004
240
+ name: "Certificate issued under a Go-distrusted key (CVE-2026-111943)"
241
+ description: "The certificate was issued by one of the eight intermediate CA keys Go 1.27.3 and 1.26.10 distrust, so Go clients rebuilt with those releases will refuse the chain even while the operating system still accepts it."
242
+ severity: high
243
+ category: cbom-security
244
+ dry-run-support: full
245
+ standards:
246
+ nist-800-53:
247
+ - "SC-13 Cryptographic Protection"
248
+ condition: |
249
+ (
250
+ $deny := [
251
+ "ebed6475c2c2d80fcb199f3fe8dd6e6b3ce60b77eb15d4e42c3dec0c6f5b5105",
252
+ "49dd353dc2b919a3770645117d0e60c16115e7d1bc259eefe734b00ea434fe5f",
253
+ "e0254c7fcdc265e2f0f8a428dabb75ab4ae039b4872d62f5ee57f0877d5a8a41",
254
+ "5c0660a2b164910d8ff589c18e14552e9e0ec237dcefe2cb736d41a4811f81a0",
255
+ "43bffa19d6ef651451f6841e019931e96f6f2eaeff28ab4b6f1ce4576de2717b",
256
+ "63ecefee431d49523bc1136c4e72d0206a477086caf606cd5cf025686c109cf8",
257
+ "ec4ffa1ad0ac88081314b7aaffef6a91f97cd57291bb5ba686c5415f5eb4f6b6",
258
+ "92c063d67e8f14db71d288e11266ffdaf69cbf115f7bab14f3bc2f68d25e0e30"
259
+ ];
260
+ $badSkis := components[
261
+ cryptoProperties.assetType = 'certificate'
262
+ and $exists(properties[name = 'cdx:crypto:spkiSha256'].value[$lowercase($) in $deny])
263
+ ].properties[name = 'cdx:crypto:subjectKeyId'].value[$ != null].$lowercase($);
264
+ components[
265
+ cryptoProperties.assetType = 'certificate'
266
+ and $not($exists(properties[name = 'cdx:crypto:spkiSha256'].value[$lowercase($) in $deny]))
267
+ and (
268
+ $count(properties[name = 'cdx:crypto:issuerSpkiSha256' or name = 'cdx:crypto:unverifiedIssuerSpkiSha256'].value[$lowercase($) in $deny]) > 0
269
+ or (
270
+ $prop($, 'cdx:crypto:authorityKeyId') != null
271
+ and $lowercase($nullSafeProp($, 'cdx:crypto:authorityKeyId')) in $badSkis
272
+ )
273
+ )
274
+ ]
275
+ )
276
+ location: |
277
+ {
278
+ "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
279
+ }
280
+ message: "Certificate '{{ name }}' was issued under a public key Go 1.27.3/1.26.10 distrust (CVE-2026-111943)"
281
+ mitigation: "Re-issue the certificate under a trusted CA and update the server chain. https://github.com/golang/go/commit/90617fb7ceb59cf08bee7826bb51b8c8fb8c11de"
282
+ evidence: |
283
+ {
284
+ "authorityKeyId": $prop($, 'cdx:crypto:authorityKeyId'),
285
+ "issuerSpkiSha256": properties[name = 'cdx:crypto:issuerSpkiSha256'].value,
286
+ "subject": cryptoProperties.certificateProperties.subjectName
287
+ }
288
+
289
+ # Post-quantum OIDs (ML-DSA RFC 9881, SLH-DSA RFC 9909, ML-KEM RFC 9935) and
290
+ # the classical-only cutoff. NIST IR 8547 (initial public draft) proposes
291
+ # classical algorithms be disallowed after 2035.
292
+ - id: CBC-005
293
+ name: "Classical-only CA certificate valid past the post-quantum transition"
294
+ description: "A CA certificate whose key and signature algorithms are both classical stays valid beyond 2035-01-01, past the date NIST IR 8547 (initial public draft) proposes to disallow classical algorithms."
295
+ severity: low
296
+ category: cbom-security
297
+ dry-run-support: full
298
+ condition: |
299
+ (
300
+ $pq := [
301
+ "2.16.840.1.101.3.4.3.17", "2.16.840.1.101.3.4.3.18", "2.16.840.1.101.3.4.3.19",
302
+ "2.16.840.1.101.3.4.3.20", "2.16.840.1.101.3.4.3.21", "2.16.840.1.101.3.4.3.22",
303
+ "2.16.840.1.101.3.4.3.23", "2.16.840.1.101.3.4.3.24", "2.16.840.1.101.3.4.3.25",
304
+ "2.16.840.1.101.3.4.3.26", "2.16.840.1.101.3.4.3.27", "2.16.840.1.101.3.4.3.28",
305
+ "2.16.840.1.101.3.4.3.29", "2.16.840.1.101.3.4.3.30", "2.16.840.1.101.3.4.3.31",
306
+ "2.16.840.1.101.3.4.4.1", "2.16.840.1.101.3.4.4.2", "2.16.840.1.101.3.4.4.3"
307
+ ];
308
+ $cutoff := '2035-01-01T00:00:00Z';
309
+ components[
310
+ cryptoProperties.assetType = 'certificate'
311
+ and $prop($, 'cdx:crypto:certRole') in ['root', 'intermediate']
312
+ and $prop($, 'cdx:crypto:publicKeyAlgorithmOid') != null
313
+ and $prop($, 'cdx:crypto:signatureAlgorithmOid') != null
314
+ and $not($prop($, 'cdx:crypto:publicKeyAlgorithmOid') in $pq)
315
+ and $not($prop($, 'cdx:crypto:signatureAlgorithmOid') in $pq)
316
+ and $certEndMillis(cryptoProperties.certificateProperties.notValidAfter) != null
317
+ and $certEndMillis(cryptoProperties.certificateProperties.notValidAfter) > $toMillis($cutoff)
318
+ ]
319
+ )
320
+ location: |
321
+ {
322
+ "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
323
+ }
324
+ message: "CA certificate '{{ name }}' uses only classical algorithms but is valid past the 2035-01-01 cutoff"
325
+ mitigation: "Plan a migration to post-quantum algorithms before the classical-only validity window ends."
326
+ evidence: |
327
+ {
328
+ "keyAlgorithmOid": $prop($, 'cdx:crypto:publicKeyAlgorithmOid'),
329
+ "signatureAlgorithmOid": $prop($, 'cdx:crypto:signatureAlgorithmOid'),
330
+ "notValidAfter": cryptoProperties.certificateProperties.notValidAfter
331
+ }
332
+
333
+ - id: CBC-006
334
+ name: "Post-quantum key certified with a classical signature"
335
+ description: "The certificate's public key is post-quantum but its signature algorithm is classical, so the authentication of that key is only as strong as the classical signature."
336
+ severity: medium
337
+ category: cbom-security
338
+ dry-run-support: full
339
+ condition: |
340
+ (
341
+ $pq := [
342
+ "2.16.840.1.101.3.4.3.17", "2.16.840.1.101.3.4.3.18", "2.16.840.1.101.3.4.3.19",
343
+ "2.16.840.1.101.3.4.3.20", "2.16.840.1.101.3.4.3.21", "2.16.840.1.101.3.4.3.22",
344
+ "2.16.840.1.101.3.4.3.23", "2.16.840.1.101.3.4.3.24", "2.16.840.1.101.3.4.3.25",
345
+ "2.16.840.1.101.3.4.3.26", "2.16.840.1.101.3.4.3.27", "2.16.840.1.101.3.4.3.28",
346
+ "2.16.840.1.101.3.4.3.29", "2.16.840.1.101.3.4.3.30", "2.16.840.1.101.3.4.3.31",
347
+ "2.16.840.1.101.3.4.4.1", "2.16.840.1.101.3.4.4.2", "2.16.840.1.101.3.4.4.3"
348
+ ];
349
+ components[
350
+ cryptoProperties.assetType = 'certificate'
351
+ and $prop($, 'cdx:crypto:publicKeyAlgorithmOid') in $pq
352
+ and $prop($, 'cdx:crypto:signatureAlgorithmOid') != null
353
+ and $not($prop($, 'cdx:crypto:signatureAlgorithmOid') in $pq)
354
+ ]
355
+ )
356
+ location: |
357
+ {
358
+ "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
359
+ }
360
+ message: "Certificate '{{ name }}' binds a post-quantum key with the classical signature '{{ $prop($, 'cdx:crypto:signatureAlgorithm') }}'"
361
+ mitigation: "Re-issue the certificate under a post-quantum or composite signature scheme once one is standardised for your chain."
362
+ evidence: |
363
+ {
364
+ "keyAlgorithmOid": $prop($, 'cdx:crypto:publicKeyAlgorithmOid'),
365
+ "signatureAlgorithmOid": $prop($, 'cdx:crypto:signatureAlgorithmOid')
366
+ }
367
+
368
+ - id: CBC-007
369
+ name: "Unrecognised certificate algorithm"
370
+ description: "The key or signature algorithm is named only by its dotted OID, which means a composite, pre-standard or otherwise unregistered algorithm the inventory cannot classify. PLAN assigns this rule info severity; the rule engine's lowest level is low."
371
+ severity: low
372
+ category: cbom-security
373
+ dry-run-support: full
374
+ condition: |
375
+ components[
376
+ (
377
+ cryptoProperties.assetType = 'certificate'
378
+ and $match($safeStr($prop($, 'cdx:crypto:signatureAlgorithm')), /^[0-9]+(\.[0-9]+)+$/)
379
+ )
380
+ or (
381
+ cryptoProperties.assetType = 'related-crypto-material'
382
+ and $match(name, /^[0-9]+(\.[0-9]+)+$/)
383
+ )
384
+ ]
385
+ location: |
386
+ {
387
+ "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
388
+ }
389
+ message: "Certificate '{{ name }}' uses an algorithm named only by its OID '{{ $firstNonEmpty($prop($, 'cdx:crypto:signatureAlgorithm'), name) }}'"
390
+ mitigation: "Identify the algorithm behind the OID and confirm it is an approved one for this use."
391
+ evidence: |
392
+ {
393
+ "signatureAlgorithm": $prop($, 'cdx:crypto:signatureAlgorithm'),
394
+ "signatureAlgorithmOid": $prop($, 'cdx:crypto:signatureAlgorithmOid'),
395
+ "name": name
396
+ }
@@ -0,0 +1,46 @@
1
+ # Go binary toolchain rules
2
+ # Category: go-security
3
+ # Evaluates the cdx:go:buildVersion property recorded for executable file
4
+ # components during container/rootfs scans.
5
+
6
+ - id: GO-TLS-001
7
+ name: "Go binary built with a toolchain that lacks the CVE-2026-111943 distrust list"
8
+ description: "Go links its standard library statically, so a binary keeps the trust behaviour of the toolchain it was built with. Releases before go1.26.10, and go1.27.0 through go1.27.2, lack the eight SPKI hashes Go uses to distrust the CVE-2026-111943 intermediate CA keys, and older release lines (1.25 and earlier) will never receive them. Release candidates of newer lines (go1.28rc1) already carry the fix."
9
+ severity: high
10
+ category: go-security
11
+ dry-run-support: full
12
+ condition: |
13
+ components[
14
+ type = 'file'
15
+ and $hasProp($, 'cdx:go:buildVersion')
16
+ and (
17
+ $prop($, 'cdx:go:buildVersion') = 'unknown-pre-1.18'
18
+ or (
19
+ $m := $match($prop($, 'cdx:go:buildVersion'), /^go(\d+)\.(\d+)(?:\.(\d+))?/);
20
+ $m != null
21
+ and $number($m.groups[0]) = 1
22
+ and (
23
+ $number($m.groups[1]) < 26
24
+ or (
25
+ $number($m.groups[1]) = 26
26
+ and ($m.groups[2] != null ? $number($m.groups[2]) : 0) < 10
27
+ )
28
+ or (
29
+ $number($m.groups[1]) = 27
30
+ and ($m.groups[2] != null ? $number($m.groups[2]) : 0) < 3
31
+ )
32
+ )
33
+ )
34
+ )
35
+ ]
36
+ location: |
37
+ {
38
+ "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
39
+ }
40
+ message: "Go binary '{{ name }}' was built with {{ $prop($, 'cdx:go:buildVersion') }}, which lacks the CVE-2026-111943 distrust list"
41
+ mitigation: "Rebuild the binary with go1.26.10, go1.27.3 or newer so its crypto/x509 rejects the distrusted intermediate CA keys."
42
+ evidence: |
43
+ {
44
+ "buildVersion": $prop($, 'cdx:go:buildVersion'),
45
+ "srcFile": $prop($, 'internal:SrcFile')
46
+ }
@@ -227,3 +227,83 @@
227
227
  "goModExcludeCount": $prop($, 'cdx:golem:goModExcludeCount'),
228
228
  "excludeModule": $prop($, 'cdx:golem:excludeModule')
229
229
  }
230
+
231
+ - id: GOLEM-SEC-008
232
+ name: "Go component configures a custom TLS root pool"
233
+ description: "Golem reported a tls.Config RootCAs or x509.VerifyOptions Roots override, so the module validates certificates against a pool it supplies instead of the system roots"
234
+ severity: low
235
+ category: golem-security
236
+ dry-run-support: full
237
+ condition: |
238
+ components[
239
+ 'GOLEM-CRYPTO-TLS-CUSTOM-ROOTS' in properties[name = 'cdx:golem:cryptoFinding'].value
240
+ ]
241
+ location: |
242
+ { "bomRef": $."bom-ref", "purl": purl }
243
+ message: "Go component '{{ name }}' sets a custom TLS root CA pool"
244
+ mitigation: "Review where the custom pool comes from and refresh it from a trusted source; a stale pool keeps trusting revoked or distrusted intermediates"
245
+ evidence: |
246
+ {
247
+ "finding": $prop($, 'cdx:golem:cryptoFinding'),
248
+ "severity": $prop($, 'cdx:golem:cryptoFindingSeverity')
249
+ }
250
+
251
+ - id: GOLEM-SEC-009
252
+ name: "Go component replaces certificate verification"
253
+ description: "Golem reported a VerifyPeerCertificate or VerifyConnection callback, so the module performs its own certificate validation instead of (part of) the standard chain verification"
254
+ severity: medium
255
+ category: golem-security
256
+ dry-run-support: full
257
+ condition: |
258
+ components[
259
+ 'GOLEM-CRYPTO-TLS-CUSTOM-VERIFY' in properties[name = 'cdx:golem:cryptoFinding'].value
260
+ ]
261
+ location: |
262
+ { "bomRef": $."bom-ref", "purl": purl }
263
+ message: "Go component '{{ name }}' installs a custom certificate verification callback"
264
+ mitigation: "Check that the callback still calls Certificate.Verify, or that its custom checks are at least as strict; hand-rolled verification can miss revoked or distrusted intermediates"
265
+ evidence: |
266
+ {
267
+ "finding": $prop($, 'cdx:golem:cryptoFinding'),
268
+ "severity": $prop($, 'cdx:golem:cryptoFindingSeverity')
269
+ }
270
+
271
+ - id: GOLEM-SEC-010
272
+ name: "Go component disables TLS verification while customising it"
273
+ description: "Golem reported an InsecureSkipVerify setting on a tls.Config that also customises verification, the pattern where Go's own distrust list no longer applies"
274
+ severity: high
275
+ category: golem-security
276
+ dry-run-support: full
277
+ condition: |
278
+ components[
279
+ 'GOLEM-CRYPTO-TLS-VERIFY-REPLACED' in properties[name = 'cdx:golem:cryptoFinding'].value
280
+ ]
281
+ location: |
282
+ { "bomRef": $."bom-ref", "purl": purl }
283
+ message: "Go component '{{ name }}' sets InsecureSkipVerify together with custom verification"
284
+ mitigation: "Remove InsecureSkipVerify and implement the required checks inside VerifyPeerCertificate on top of the standard chain verification"
285
+ evidence: |
286
+ {
287
+ "finding": $prop($, 'cdx:golem:cryptoFinding'),
288
+ "severity": $prop($, 'cdx:golem:cryptoFindingSeverity')
289
+ }
290
+
291
+ - id: GOLEM-SEC-011
292
+ name: "Go component embeds a certificate pool"
293
+ description: "Golem reported a package-level //go:embed variable fed to x509.CertPool.AppendCertsFromPEM, so a private trust anchor travels inside the binary"
294
+ severity: low
295
+ category: golem-security
296
+ dry-run-support: full
297
+ condition: |
298
+ components[
299
+ 'GOLEM-CRYPTO-X509-EMBEDDED-POOL' in properties[name = 'cdx:golem:cryptoFinding'].value
300
+ ]
301
+ location: |
302
+ { "bomRef": $."bom-ref", "purl": purl }
303
+ message: "Go component '{{ name }}' appends an embedded PEM bundle to an x509 pool"
304
+ mitigation: "Track the embedded bundle like any other trust store: refresh it when CAs change and confirm it contains none of the distrusted keys"
305
+ evidence: |
306
+ {
307
+ "finding": $prop($, 'cdx:golem:cryptoFinding'),
308
+ "severity": $prop($, 'cdx:golem:cryptoFindingSeverity')
309
+ }
@@ -16,26 +16,38 @@
16
16
  - "1.1 Establish and Maintain Detailed Enterprise Asset Inventory"
17
17
  condition: |
18
18
  metadata.component[
19
- $safeStr($prop($, 'cdx:hbom:platform')) = 'linux'
20
- and $count(
21
- $$.components[
22
- $prop($, 'cdx:hbom:hardwareClass') = 'board'
23
- and (
24
- $hasProp($, 'cdx:hbom:boardVendor')
25
- or $hasProp($, 'cdx:hbom:boardName')
26
- or $hasProp($, 'cdx:hbom:biosVendor')
27
- or $hasProp($, 'cdx:hbom:biosVersion')
28
- or $hasProp($, 'cdx:hbom:firmwareDate')
29
- )
30
- ]
31
- ) = 0
19
+ (
20
+ $safeStr($prop($, 'cdx:hbom:platform')) = 'linux'
21
+ and $count(
22
+ $$.components[
23
+ $prop($, 'cdx:hbom:hardwareClass') = 'board'
24
+ and (
25
+ $hasProp($, 'cdx:hbom:boardVendor')
26
+ or $hasProp($, 'cdx:hbom:boardName')
27
+ or $hasProp($, 'cdx:hbom:biosVendor')
28
+ or $hasProp($, 'cdx:hbom:biosVersion')
29
+ or $hasProp($, 'cdx:hbom:firmwareDate')
30
+ )
31
+ ]
32
+ ) = 0
33
+ )
34
+ or (
35
+ $safeStr($prop($, 'cdx:hbom:platform')) = 'windows'
36
+ and $not(
37
+ $hasProp($, 'cdx:hbom:boardVendor')
38
+ or $hasProp($, 'cdx:hbom:boardName')
39
+ or $hasProp($, 'cdx:hbom:biosVendor')
40
+ or $hasProp($, 'cdx:hbom:biosVersion')
41
+ or $hasProp($, 'cdx:hbom:firmwareDate')
42
+ )
43
+ )
32
44
  ]
33
45
  location: |
34
46
  {
35
47
  "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
36
48
  }
37
49
  message: "HBOM for '{{ name }}' lacks board or firmware provenance fields needed for governance review"
38
- mitigation: "Enable richer firmware/board collection on supported Linux hosts, validate SMBIOS access, and ensure the inventory captures board vendor, board name, BIOS vendor, BIOS version, and firmware date where available."
50
+ mitigation: "Enable richer firmware/board collection on supported Linux hosts, validate SMBIOS access, and ensure the inventory captures board vendor, board name, BIOS vendor, BIOS version, and firmware date where available. On Windows these come from the windows-cim-platform batch, which a network logon (SSH, WinRM) as a non-administrator cannot run: collect from a local session or an elevated one."
39
51
  evidence: |
40
52
  {
41
53
  "platform": $prop($, 'cdx:hbom:platform'),
@@ -142,7 +154,7 @@
142
154
  "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
143
155
  }
144
156
  message: "HBOM for '{{ name }}' includes storage volumes but no explicit encryption posture evidence"
145
- mitigation: "Enable volume-level enrichment on supported platforms or pair the HBOM with equivalent host controls evidence so encryption compliance can be verified."
157
+ mitigation: "Enable volume-level enrichment on supported platforms or pair the HBOM with equivalent host controls evidence so encryption compliance can be verified. On Windows, BitLocker status comes from the --privileged batch, so rerun from an elevated (Run as administrator) prompt with --privileged."
146
158
  evidence: |
147
159
  {
148
160
  "storageVolumeCount": $count($$.components[$prop($, 'cdx:hbom:hardwareClass') = 'storage-volume']),
@@ -219,8 +231,8 @@
219
231
  {
220
232
  "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
221
233
  }
222
- message: "HBOM for '{{ name }}' hit permission-denied enrichments that likely require a rerun with --privileged"
223
- mitigation: "Where policy allows, rerun HBOM collection with --privileged so cdx-hbom can use the documented non-interactive sudo path for permission-sensitive Linux enrichments."
234
+ message: "HBOM for '{{ name }}' hit permission-denied enrichments that likely require {{ $safeStr($prop($, 'cdx:hbom:platform')) = 'windows' ? 'a rerun from a local or elevated session' : 'a rerun with --privileged' }}"
235
+ mitigation: "Where policy allows, rerun HBOM collection with --privileged. On Linux, cdx-hbom then uses the documented non-interactive sudo path for permission-sensitive enrichments. On Windows it never elevates or prompts: run it from a local session (a non-administrator over SSH or WinRM is denied every WMI query) and, for the TPM, BitLocker and storage-reliability batch, from an elevated (Run as administrator) prompt."
224
236
  evidence: |
225
237
  {
226
238
  "collectorProfile": $prop(bom, 'cdx:hbom:collectorProfile'),
@@ -260,7 +272,7 @@
260
272
 
261
273
  - id: HBC-009
262
274
  name: "HBOM board and BIOS provenance was blocked by permissions"
263
- description: "When dmidecode-backed firmware and board enrichment is blocked, the HBOM may miss board-vendor, board-name, BIOS-version, and related governance evidence."
275
+ description: "When dmidecode-backed firmware and board enrichment is blocked on Linux, or Windows denies WMI to the whole session (a network logon), the HBOM may miss board-vendor, board-name, BIOS-version, and related governance evidence."
264
276
  severity: medium
265
277
  category: hbom-compliance
266
278
  dry-run-support: full
@@ -270,15 +282,21 @@
270
282
  - "SI-7 Software, Firmware, and Information Integrity"
271
283
  condition: |
272
284
  metadata.component[
273
- $safeStr($prop($, 'cdx:hbom:platform')) = 'linux'
274
- and $listContains($propList($$, 'cdx:hbom:analysis:permissionDeniedIds'), 'dmidecode-firmware-board')
285
+ (
286
+ $safeStr($prop($, 'cdx:hbom:platform')) = 'linux'
287
+ and $listContains($propList($$, 'cdx:hbom:analysis:permissionDeniedIds'), 'dmidecode-firmware-board')
288
+ )
289
+ or (
290
+ $safeStr($prop($, 'cdx:hbom:platform')) = 'windows'
291
+ and $listContains($propList($$, 'cdx:hbom:analysis:permissionDeniedIds'), 'windows-cim-platform:network-logon')
292
+ )
275
293
  ]
276
294
  location: |
277
295
  {
278
296
  "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
279
297
  }
280
- message: "HBOM for '{{ name }}' could not capture full board and BIOS provenance because dmidecode enrichment was blocked"
281
- mitigation: "Where policy allows, rerun with --privileged or equivalent access so the collector can gather firmware vendor, BIOS version, board vendor, and board name data."
298
+ message: "HBOM for '{{ name }}' could not capture full board and BIOS provenance because {{ $safeStr($prop($, 'cdx:hbom:platform')) = 'windows' ? 'WMI was denied to this network logon' : 'dmidecode enrichment was blocked' }}"
299
+ mitigation: "Where policy allows, rerun with --privileged or equivalent access so the collector can gather firmware vendor, BIOS version, board vendor, and board name data. On Windows, run HBOM from a local session or an elevated one instead of over SSH or WinRM as a non-administrator."
282
300
  evidence: |
283
301
  {
284
302
  "collectorProfile": $prop(bom, 'cdx:hbom:collectorProfile'),
@@ -32,7 +32,7 @@
32
32
 
33
33
  - id: HBP-002
34
34
  name: "Storage health is degraded or wear is near exhaustion"
35
- description: "Degraded SMART state or high wear percentage is a strong leading indicator of latency, failure, or replacement pressure."
35
+ description: "Degraded SMART state, a Warning or Unhealthy Windows storage health status, or high wear percentage is a strong leading indicator of latency, failure, or replacement pressure."
36
36
  severity: high
37
37
  category: hbom-performance
38
38
  dry-run-support: full
@@ -50,6 +50,10 @@
50
50
  and $lowercase($safeStr($prop($, 'cdx:hbom:smartStatus'))) != 'ok'
51
51
  and $lowercase($safeStr($prop($, 'cdx:hbom:smartStatus'))) != 'passed'
52
52
  )
53
+ or (
54
+ $lowercase($safeStr($prop($, 'cdx:hbom:healthStatus'))) = 'warning'
55
+ or $lowercase($safeStr($prop($, 'cdx:hbom:healthStatus'))) = 'unhealthy'
56
+ )
53
57
  or (
54
58
  $hasProp($, 'cdx:hbom:wearPercentageUsed')
55
59
  and $number($prop($, 'cdx:hbom:wearPercentageUsed')) >= 80
@@ -65,6 +69,8 @@
65
69
  evidence: |
66
70
  {
67
71
  "smartStatus": $prop($, 'cdx:hbom:smartStatus'),
72
+ "healthStatus": $prop($, 'cdx:hbom:healthStatus'),
73
+ "operationalStatus": $prop($, 'cdx:hbom:operationalStatus'),
68
74
  "wearPercentageUsed": $prop($, 'cdx:hbom:wearPercentageUsed'),
69
75
  "revision": $prop($, 'cdx:hbom:revision'),
70
76
  "deviceSerial": $prop($, 'cdx:hbom:deviceSerial')
@@ -90,7 +90,7 @@
90
90
  "bomRef": $firstNonEmpty($."bom-ref", bom.serialNumber)
91
91
  }
92
92
  message: "Merged host inventory for '{{ name }}' contains no strict HBOM-to-OBOM topology links"
93
- mitigation: "Review collector coverage, ensure runtime categories such as interface_addresses or kernel_modules are available, and prefer exact identifier-bearing probes over heuristic joins."
93
+ mitigation: "Review collector coverage, ensure runtime categories such as interface_addresses or kernel_modules (logical_drives on Windows) are available, and prefer exact identifier-bearing probes over heuristic joins."
94
94
  evidence: |
95
95
  {
96
96
  "hostViewMode": $prop($, 'cdx:hostview:mode'),
@@ -111,8 +111,9 @@
111
111
  "deviceId": name,
112
112
  "driveLetter": version,
113
113
  "protectionStatus": $prop($, 'protection_status'),
114
- "encryptionMethod": $prop($, 'encryption_method'),
115
- "percentageEncrypted": $prop($, 'percentage_encrypted')
114
+ "encryptionMethod": description,
115
+ "percentageEncrypted": $prop($, 'percentage_encrypted'),
116
+ "protectorTypes": $prop($, 'protector_types')
116
117
  }
117
118
 
118
119
  - id: OBOM-WIN-002
@@ -1774,3 +1775,31 @@
1774
1775
  "comment": description,
1775
1776
  "uid": $prop($, 'uid')
1776
1777
  }
1778
+
1779
+ - id: OBOM-LNX-023
1780
+ name: "Linux snap installed in devmode confinement"
1781
+ description: "A snap installed with --devmode runs without its sandbox being enforced: policy violations are only logged. Devmode is meant for snap development, not for software a host relies on."
1782
+ severity: medium
1783
+ category: obom-runtime
1784
+ dry-run-support: full
1785
+ condition: |
1786
+ components[
1787
+ $prop($, 'cdx:osquery:category') = 'snap_packages'
1788
+ and $lowercase($safeStr($prop($, 'cdx:snap:confinement'))) = 'devmode'
1789
+ ]
1790
+ location: |
1791
+ {
1792
+ "bomRef": $."bom-ref",
1793
+ "purl": purl
1794
+ }
1795
+ message: "Snap '{{ name }}' {{ version }} (revision {{ $prop($, 'cdx:snap:revision') }}) is installed in devmode confinement, so its sandbox is not enforced"
1796
+ mitigation: "Reinstall the snap from a stable channel with strict confinement, or remove it. If devmode is required for development, keep it off production and shared hosts."
1797
+ evidence: |
1798
+ {
1799
+ "snap": name,
1800
+ "version": version,
1801
+ "revision": $prop($, 'cdx:snap:revision'),
1802
+ "channel": $prop($, 'cdx:snap:channel'),
1803
+ "confinement": $prop($, 'cdx:snap:confinement'),
1804
+ "grade": $prop($, 'grade')
1805
+ }