@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
package/lib/cli/index.js CHANGED
@@ -50,7 +50,9 @@ import {
50
50
  buildDependencyTrackBomRequest,
51
51
  getDependencyTrackBomApiUrl,
52
52
  } from "../helpers/remote/dependency-track.js";
53
+ import { collectObomIdeInventory } from "../helpers/vsixutils.js";
53
54
  import { optionIncludesAiInventoryProjectType } from "../inventory/aiInventory.js";
55
+ import { readApkInstalledDb } from "../inventory/apkInstalledDb.js";
54
56
  import { isCycloneDxComponentTypeEnabled } from "../inventory/bomUtils.js";
55
57
  import {
56
58
  mergeDependencies,
@@ -58,7 +60,10 @@ import {
58
60
  trimComponents,
59
61
  } from "../inventory/depsUtils.js";
60
62
  import { buildDynamicComponents } from "../inventory/dynamic.js";
61
- import { convertOSQueryResults } from "../inventory/evidenceUtils.js";
63
+ import {
64
+ convertApkPackages,
65
+ convertOSQueryResults,
66
+ } from "../inventory/evidenceUtils.js";
62
67
  import {
63
68
  createHbomDocument,
64
69
  ensureHbomRuntimeSupport,
@@ -66,15 +71,28 @@ import {
66
71
  hasHbomProjectType,
67
72
  } from "../inventory/hbom.js";
68
73
  import { mergeHostInventoryBoms } from "../inventory/hostTopology.js";
74
+ import { probeHostNode } from "../inventory/nodeHostProbe.js";
75
+ import { markOsInstalledLanguagePackages } from "../inventory/osPackageResolver.js";
69
76
  import { orderParentCandidates } from "../inventory/parentSelection.js";
77
+ import { probeHostPhp } from "../inventory/phpHostProbe.js";
70
78
  // Imported directly rather than through the utils.js barrel: purl validity is
71
79
  // checked in a hot path and the barrel is already the root of several import
72
80
  // cycles.
73
81
  import { applyPurl, ociPurl } from "../inventory/purl.js";
82
+ import {
83
+ deriveOsPackagedRubyRuntimes,
84
+ linkDefaultGemsToRuntimes,
85
+ } from "../inventory/rubyBuildInfo.js";
86
+ import { probeHostRuby } from "../inventory/rubyHostProbe.js";
74
87
  import { table } from "../inventory/table.js";
75
88
 
76
89
  export { summarizeAiInventory } from "../inventory/aiInventory.js";
77
90
 
91
+ import { probeHostRubyGems } from "../ecosystems/gemHostProbe.js";
92
+ import {
93
+ mergeHostPythonEnvironmentPackages,
94
+ probeHostPythonEnvironments,
95
+ } from "../ecosystems/venvProbe.js";
78
96
  import {
79
97
  enrichOSComponentsWithTrustData,
80
98
  executeOsQuery,
@@ -86,6 +104,7 @@ import {
86
104
  exportArchive,
87
105
  exportImage,
88
106
  getPkgPathList,
107
+ isFollowableManifestImage,
89
108
  isImageReference,
90
109
  parseImageName,
91
110
  } from "../managers/docker.js";
@@ -234,6 +253,28 @@ switch (_platform()) {
234
253
  break;
235
254
  }
236
255
 
256
+ /**
257
+ * Home directories whose editor extension folders an OBOM reads: every user's
258
+ * home from osquery when cdxgen runs as root, and otherwise the current
259
+ * user's, which is the only one it can read.
260
+ *
261
+ * @returns {string[]} Home directories
262
+ */
263
+ function obomUserHomes() {
264
+ const ownHome = homedir();
265
+ if (typeof process.getuid !== "function" || process.getuid() !== 0) {
266
+ return [ownHome];
267
+ }
268
+ const homes = new Set([ownHome]);
269
+ for (const row of executeOsQuery("SELECT directory FROM users;") || []) {
270
+ const dir = row?.directory;
271
+ if (typeof dir === "string" && dir.startsWith("/") && safeExistsSync(dir)) {
272
+ homes.add(dir);
273
+ }
274
+ }
275
+ return [...homes];
276
+ }
277
+
237
278
  /**
238
279
  * Function to create obom string for the current OS using osquery
239
280
  *
@@ -241,7 +282,7 @@ switch (_platform()) {
241
282
  * @param {Object} options Parse options from the cli
242
283
  * @returns {Promise<Object>} Promise resolving to BOM object
243
284
  */
244
- export function createOSBom(_path, options) {
285
+ export async function createOSBom(_path, options) {
245
286
  console.warn(
246
287
  "About to generate OBOM for the current OS installation. This will take several minutes ...",
247
288
  );
@@ -272,6 +313,84 @@ export function createOSBom(_path, options) {
272
313
  );
273
314
  }
274
315
  } // for
316
+ // osquery has no apk table, so the packages of an Alpine, Wolfi or Chainguard
317
+ // host come from the apk installed database, after the osquery categories and
318
+ // as a category of their own. They are all components: the OS itself is the
319
+ // first row of the first osquery category, as before.
320
+ if (_platform() === "linux") {
321
+ const apkInventory = readApkInstalledDb();
322
+ if (apkInventory.state === "unreadable") {
323
+ recordDegradation("os.apk-installed-db.unreadable", {
324
+ ecosystem: "generic",
325
+ tool: "apk",
326
+ impact: "components",
327
+ path: apkInventory.path,
328
+ detail:
329
+ "The apk installed database exists but could not be read in full, so the packages it lists are missing from the OBOM.",
330
+ });
331
+ }
332
+ if (apkInventory.packages.length) {
333
+ pkgList = pkgList.concat(
334
+ convertApkPackages(apkInventory.packages).sort((a, b) =>
335
+ a.name.localeCompare(b.name),
336
+ ),
337
+ );
338
+ }
339
+ }
340
+ // The package tables cannot see a PHP that no package manager installed. Its
341
+ // edges stay out: an OBOM has no dependency graph, and a partial one makes
342
+ // post-processing infer the OS root's dependencies from these files alone.
343
+ const hostPhp = probeHostPhp({ executeOsQuery, packageComponents: pkgList });
344
+ if (hostPhp.components.length) {
345
+ pkgList = pkgList.concat(hostPhp.components);
346
+ }
347
+ // Nor a Node.js from a release tarball or a version manager, or the Brotli
348
+ // decoder compiled into it.
349
+ const hostNode = probeHostNode({
350
+ executeOsQuery,
351
+ packageComponents: pkgList,
352
+ });
353
+ if (hostNode.components.length) {
354
+ pkgList = pkgList.concat(hostNode.components);
355
+ }
356
+ // Nor a Ruby from ruby-build, a version manager or a toolcache tarball.
357
+ const hostRuby = probeHostRuby({
358
+ executeOsQuery,
359
+ packageComponents: pkgList,
360
+ });
361
+ if (hostRuby.components.length) {
362
+ pkgList = pkgList.concat(hostRuby.components);
363
+ }
364
+ // A Ruby a package manager installed is also named by its upstream version.
365
+ pkgList = pkgList.concat(deriveOsPackagedRubyRuntimes(pkgList));
366
+ // osquery has no table for RubyGems; the gems of the host's gem homes are
367
+ // read from their specifications.
368
+ const hostGems = await probeHostRubyGems({
369
+ executeOsQuery,
370
+ packageComponents: pkgList,
371
+ });
372
+ if (hostGems.length) {
373
+ const knownRefs = new Set(pkgList.map((component) => component["bom-ref"]));
374
+ pkgList = pkgList.concat(
375
+ hostGems.filter((gem) => !knownRefs.has(gem["bom-ref"])),
376
+ );
377
+ }
378
+ // osquery reads the interpreter's own site-packages; packages installed into
379
+ // a virtual environment or a pyenv interpreter are read from their METADATA.
380
+ pkgList = mergeHostPythonEnvironmentPackages(
381
+ pkgList,
382
+ probeHostPythonEnvironments(),
383
+ );
384
+ // osquery reads the extension registry of a fixed list of editors; the
385
+ // editors themselves, and the extensions of the others, come from the
386
+ // extension folders. A root scan reads every user's home, as osquery does.
387
+ try {
388
+ pkgList = pkgList.concat(
389
+ collectObomIdeInventory(pkgList, { homes: obomUserHomes() }),
390
+ );
391
+ } catch (err) {
392
+ thoughtLog(`Unable to read the editor extension folders: ${err.message}`);
393
+ }
275
394
  const hostTrustInventory = enrichOSComponentsWithTrustData(pkgList);
276
395
  if (hostTrustInventory?.components?.length) {
277
396
  pkgList = hostTrustInventory.components;
@@ -515,11 +634,14 @@ export async function createContainerSpecLikeBom(path, options) {
515
634
  if (imageBomData?.bomJson?.components) {
516
635
  components = components.concat(imageBomData.bomJson.components);
517
636
  }
637
+ doneimages.push(img.image);
638
+ if (!isFollowableManifestImage(img.image, imageObj)) {
639
+ continue;
640
+ }
518
641
  const bomData = await createBom(img.image, {
519
642
  specVersion: options.specVersion,
520
643
  projectType: ["oci"],
521
644
  });
522
- doneimages.push(img.image);
523
645
  if (bomData) {
524
646
  if (bomData.components?.length) {
525
647
  // Inject properties
@@ -734,8 +856,10 @@ export async function createMultiXBom(pathList, options) {
734
856
  let dependencies = [];
735
857
  let bomData;
736
858
  let formulationList = [];
859
+ let metadataProperties = [];
737
860
  let parentComponent = determineParentComponent(options) || {};
738
861
  let parentSubComponents = [];
862
+ let osFileOwners;
739
863
  const setProjectTypeActivityContext = (projectType, sourcePath) => {
740
864
  setActivityContext({
741
865
  projectType,
@@ -756,6 +880,8 @@ export async function createMultiXBom(pathList, options) {
756
880
  const {
757
881
  osPackages,
758
882
  osPackageFiles,
883
+ nativeExtensionFiles,
884
+ ownerByPath,
759
885
  dependenciesList,
760
886
  allTypes,
761
887
  bundledSdks,
@@ -770,6 +896,7 @@ export async function createMultiXBom(pathList, options) {
770
896
  options.exportData?.inspectData?.Config,
771
897
  options,
772
898
  );
899
+ osFileOwners = ownerByPath;
773
900
  osPhase.succeed(
774
901
  summarizeCounts([
775
902
  [osPackages.length, "OS package", "OS packages"],
@@ -818,6 +945,7 @@ export async function createMultiXBom(pathList, options) {
818
945
  components = components.concat(osPackageFiles || []);
819
946
  components = components.concat(executables);
820
947
  components = components.concat(sharedLibs);
948
+ components = components.concat(nativeExtensionFiles || []);
821
949
  if (dependenciesList?.length) {
822
950
  dependencies = mergeDependencies(dependencies, dependenciesList);
823
951
  }
@@ -867,6 +995,7 @@ export async function createMultiXBom(pathList, options) {
867
995
  dependencies: [],
868
996
  options: { ...sharedOptions },
869
997
  parentSubComponents: [],
998
+ metadataProperties: [],
870
999
  };
871
1000
  }
872
1001
  };
@@ -879,6 +1008,7 @@ export async function createMultiXBom(pathList, options) {
879
1008
  let components = [];
880
1009
  let dependencies = [];
881
1010
  let parentSubComponents = [];
1011
+ let metadataProperties = [];
882
1012
  // Each builder detects the project of its own ecosystem. A builder that sets
883
1013
  // options.parentComponent to force its project into its own BOM must not
884
1014
  // make that project the next builder's too, or the next ecosystem's project
@@ -1163,6 +1293,12 @@ export async function createMultiXBom(pathList, options) {
1163
1293
  }
1164
1294
  setProjectTypeActivityContext("php", path);
1165
1295
  bomData = await withOwnParent(() => createPHPBom(path, options));
1296
+ // A lock with no packages can still hold the project's platform data.
1297
+ if (bomData?.metadataProperties?.length) {
1298
+ metadataProperties = metadataProperties.concat(
1299
+ bomData.metadataProperties,
1300
+ );
1301
+ }
1166
1302
  if (bomData?.bomJson?.components?.length) {
1167
1303
  thoughtLog(
1168
1304
  `I found ${bomData.bomJson.components.length} php packages.`,
@@ -1236,7 +1372,12 @@ export async function createMultiXBom(pathList, options) {
1236
1372
  }
1237
1373
  setProjectTypeActivityContext("csharp", path);
1238
1374
  bomData = await withOwnParent(() => createCsharpBom(path, options));
1239
- if (bomData?.bomJson?.components?.length) {
1375
+ // Every project the scan read has a dependency entry of its own, so a
1376
+ // project that uses no packages is kept along with its parent.
1377
+ if (
1378
+ bomData?.bomJson?.components?.length ||
1379
+ bomData?.bomJson?.dependencies?.length
1380
+ ) {
1240
1381
  thoughtLog(
1241
1382
  `There are ${bomData.bomJson.components.length} csharp packages.`,
1242
1383
  );
@@ -1753,9 +1894,18 @@ export async function createMultiXBom(pathList, options) {
1753
1894
  );
1754
1895
  }
1755
1896
  components = components.concat(bomData.bomJson.components);
1897
+ if (bomData.dependencies?.length) {
1898
+ dependencies = mergeDependencies(dependencies, bomData.dependencies);
1899
+ }
1756
1900
  }
1757
1901
  }
1758
- return { components, dependencies, options, parentSubComponents };
1902
+ return {
1903
+ components,
1904
+ dependencies,
1905
+ options,
1906
+ parentSubComponents,
1907
+ metadataProperties,
1908
+ };
1759
1909
  };
1760
1910
  const pathResults = [];
1761
1911
  // A container scan walks hundreds of paths, so the phase carries a bar and
@@ -1818,6 +1968,9 @@ export async function createMultiXBom(pathList, options) {
1818
1968
  parentSubComponents = parentSubComponents.concat(
1819
1969
  pathResult.parentSubComponents,
1820
1970
  );
1971
+ metadataProperties = metadataProperties.concat(
1972
+ pathResult.metadataProperties,
1973
+ );
1821
1974
  if (pathResult.options.services?.length) {
1822
1975
  sharedOptions.services = mergeServices(
1823
1976
  sharedOptions.services || [],
@@ -1907,7 +2060,28 @@ export async function createMultiXBom(pathList, options) {
1907
2060
  components,
1908
2061
  parentComponent,
1909
2062
  dependencies,
1910
- );
2063
+ metadataProperties,
2064
+ );
2065
+ // Language packages an OS package installed are judged by that package.
2066
+ // Duplicates have merged by now, so a component found both where the distro
2067
+ // put it and where pip did is seen whole and left unmarked.
2068
+ markOsInstalledLanguagePackages(
2069
+ multiResult.bomJson?.components,
2070
+ osFileOwners,
2071
+ options.allLayersExplodedDir,
2072
+ );
2073
+ // The default gems of an unpackaged Ruby, such as resolv in a Docker
2074
+ // Official image, ship with that Ruby and are updated by its releases.
2075
+ const defaultGemEdges = linkDefaultGemsToRuntimes(
2076
+ multiResult.bomJson?.components,
2077
+ options.allLayersExplodedDir,
2078
+ );
2079
+ if (defaultGemEdges.length && multiResult.bomJson) {
2080
+ multiResult.bomJson.dependencies = mergeDependencies(
2081
+ multiResult.bomJson.dependencies || [],
2082
+ defaultGemEdges,
2083
+ );
2084
+ }
1911
2085
  if (formulationList.length) {
1912
2086
  multiResult.formulationList = formulationList;
1913
2087
  }
@@ -1978,6 +2152,7 @@ export async function createDynamicBom(path, options) {
1978
2152
  const {
1979
2153
  components: pkgList,
1980
2154
  services: traceServices,
2155
+ dependencies: traceDependencies,
1981
2156
  dryRunSummary,
1982
2157
  } = await buildDynamicComponents(commandStr, workingDir, traceOptions);
1983
2158
 
@@ -1986,6 +2161,7 @@ export async function createDynamicBom(path, options) {
1986
2161
  projectType: "dynamic",
1987
2162
  filename: commandStr,
1988
2163
  services: traceServices,
2164
+ dependencies: traceDependencies || [],
1989
2165
  });
1990
2166
  // A dry run denies every side effect, so the attempted-operation counts are
1991
2167
  // the result. Only counts are recorded, never the paths or targets.