@cdxgen/cdxgen 13.3.0 → 13.5.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.
- package/README.md +12 -9
- package/bin/cdxgen-secure.js +15 -0
- package/bin/cdxgen.js +115 -31
- package/bin/evinse.js +23 -1
- package/bin/hbom.js +15 -7
- package/bin/repl.js +115 -0
- package/bin/sign.js +45 -15
- package/bin/tracebom.js +5 -1
- package/bin/validate.js +84 -18
- package/bin/verify.js +155 -86
- package/data/cbomosdb-queries.json +13 -1
- package/data/component-tags.json +8 -0
- package/data/helpers/init.gradle +46 -21
- package/data/queries-darwin.json +25 -1
- package/data/queries-win.json +19 -1
- package/data/queries.json +41 -0
- package/data/remediations.json +344 -1
- package/data/rules/cbom-security.yaml +235 -4
- package/data/rules/dependency-sources.yaml +67 -0
- package/data/rules/go-binaries.yaml +46 -0
- package/data/rules/golem-go.yaml +80 -0
- package/data/rules/hbom-compliance.yaml +40 -22
- package/data/rules/hbom-performance.yaml +7 -1
- package/data/rules/host-topology.yaml +1 -1
- package/data/rules/obom-runtime.yaml +31 -2
- package/data/rules/php-runtime.yaml +143 -0
- package/data/rules/scala-evidence.yaml +115 -0
- package/lib/audit/index.js +52 -6
- package/lib/cli/bomAssembly.js +28 -3
- package/lib/cli/cliOptions.js +110 -3
- package/lib/cli/index.js +186 -58
- package/lib/cli/jsBom.js +50 -29
- package/lib/cli/jvmBom.js +779 -146
- package/lib/cli/managedBom.js +1021 -261
- package/lib/cli/nativeBom.js +364 -58
- package/lib/core/activity.js +12 -0
- package/lib/core/env.js +47 -17
- package/lib/core/fs.js +31 -21
- package/lib/core/httpClient.js +233 -69
- package/lib/core/pluginRun.js +184 -0
- package/lib/core/processTree.js +100 -0
- package/lib/core/projectConfig.js +1 -0
- package/lib/core/projectTooling.js +97 -0
- package/lib/core/propertySanitizer.js +72 -0
- package/lib/core/runState.js +39 -0
- package/lib/core/toml.js +72 -0
- package/lib/ecosystems/asarutils.js +4 -2
- package/lib/ecosystems/bunutils.js +5 -7
- package/lib/ecosystems/cargoCache.js +231 -8
- package/lib/ecosystems/cmakeResolver.js +10 -21
- package/lib/ecosystems/cppBuildContext.js +631 -0
- package/lib/ecosystems/cppEvidence.js +337 -22
- package/lib/ecosystems/cppIncludeResolver.js +294 -0
- package/lib/ecosystems/denoutils.js +93 -66
- package/lib/ecosystems/ecosystems.js +1967 -788
- package/lib/ecosystems/golem.js +578 -18
- package/lib/ecosystems/gradleutils.js +340 -46
- package/lib/ecosystems/jsEvidence.js +85 -24
- package/lib/ecosystems/kosi.js +21 -4
- package/lib/ecosystems/npmutils.js +64 -0
- package/lib/ecosystems/parsers-dotnet.js +668 -153
- package/lib/ecosystems/parsers-elm.js +46 -28
- package/lib/ecosystems/parsers-gleam.js +3 -4
- package/lib/ecosystems/parsers-go.js +1283 -297
- package/lib/ecosystems/parsers-js.js +92 -26
- package/lib/ecosystems/parsers-julia.js +2 -3
- package/lib/ecosystems/parsers-jvm.js +463 -29
- package/lib/ecosystems/parsers-misc.js +405 -93
- package/lib/ecosystems/parsers-python.js +152 -20
- package/lib/ecosystems/parsers-rust.js +4 -4
- package/lib/ecosystems/parsers-terraform.js +1573 -19
- package/lib/ecosystems/pythonutils.js +102 -6
- package/lib/ecosystems/remote/huggingface.js +3 -0
- package/lib/ecosystems/rubyutils.js +73 -20
- package/lib/ecosystems/rusi.js +32 -9
- package/lib/ecosystems/sbtutils.js +243 -187
- package/lib/ecosystems/scalacliutils.js +343 -0
- package/lib/ecosystems/scalasem.js +2620 -0
- package/lib/ecosystems/terraformRegistry.js +288 -0
- package/lib/ecosystems/utils.js +2 -0
- package/lib/ecosystems/vendoredCode.js +156 -0
- package/lib/evinser/evinser.js +695 -78
- package/lib/evinser/swiftsem.js +68 -5
- package/lib/helpers/agenticToolutils.js +2 -2
- package/lib/helpers/bomSigner.js +576 -128
- package/lib/inventory/agentSkillSpec.js +17 -0
- package/lib/inventory/aiCollector.js +4 -1
- package/lib/inventory/analyzer.js +110 -127
- package/lib/inventory/apkInstalledDb.js +243 -0
- package/lib/inventory/atomUtils.js +204 -48
- package/lib/inventory/auditCategories.js +10 -3
- package/lib/inventory/buildToolRateLimit.js +144 -0
- package/lib/inventory/cacheCommands.js +2 -1
- package/lib/inventory/cacheDir.js +52 -9
- package/lib/inventory/certificates.js +2371 -0
- package/lib/inventory/cmakeBuildDirs.js +254 -0
- package/lib/inventory/communityAiConfigParser.js +4 -9
- package/lib/inventory/deps.js +507 -128
- package/lib/inventory/display.js +200 -3
- package/lib/inventory/dosai.js +747 -101
- package/lib/inventory/dosaiParsers.js +310 -15
- package/lib/inventory/dynamic.js +96 -8
- package/lib/inventory/envcontext.js +168 -5
- package/lib/inventory/evidenceUtils.js +590 -132
- package/lib/inventory/fetchBatch.js +574 -38
- package/lib/inventory/fetchDiskCache.js +597 -0
- package/lib/inventory/forgeEnricher.js +14 -5
- package/lib/inventory/formulationParsers.js +3 -2
- package/lib/inventory/goBuildInfo.js +140 -0
- package/lib/inventory/hbom.js +67 -7
- package/lib/inventory/hbomAnalysis.js +16 -0
- package/lib/inventory/hostTopology.js +21 -0
- package/lib/inventory/jvmLocalRepos.js +917 -0
- package/lib/inventory/mcpConfigParser.js +2 -3
- package/lib/inventory/osPackagePurl.js +244 -0
- package/lib/inventory/osPackageResolver.js +89 -87
- package/lib/inventory/osinfo.js +79 -31
- package/lib/inventory/osqueryTransform.js +114 -5
- package/lib/inventory/parentSelection.js +146 -0
- package/lib/inventory/phpBuildInfo.js +487 -0
- package/lib/inventory/phpHostProbe.js +641 -0
- package/lib/inventory/rootfsCerts.js +426 -0
- package/lib/inventory/rustFormulationParser.js +3 -4
- package/lib/inventory/scalaCoords.js +153 -0
- package/lib/inventory/source.js +215 -11
- package/lib/inventory/spdx.js +245 -0
- package/lib/inventory/traceRunner.js +93 -8
- package/lib/inventory/tracedCrypto.js +423 -0
- package/lib/managers/binary.js +529 -183
- package/lib/managers/docker.js +199 -44
- package/lib/managers/oci.js +24 -2
- package/lib/parsers/cmakeCache.js +69 -0
- package/lib/parsers/cmakeLists.js +16 -2
- package/lib/parsers/cmakePresets.js +400 -0
- package/lib/parsers/compileCommands.js +557 -0
- package/lib/parsers/email.js +277 -0
- package/lib/parsers/largeJson.js +34 -2
- package/lib/parsers/strictJson.js +322 -0
- package/lib/parsers/terraformConfig.js +1073 -0
- package/lib/parsers/terraformSource.js +652 -0
- package/lib/server/server.js +209 -1
- package/lib/stages/postgen/annotator.js +17 -1
- package/lib/stages/postgen/introspection/markers.js +1 -1
- package/lib/stages/postgen/introspection/reflect.js +4 -1
- package/lib/stages/postgen/postgen.js +20 -6
- package/lib/stages/postgen/ruleEngine.js +58 -1
- package/lib/stages/postgen/specVersionCompat.js +62 -0
- package/lib/stages/pregen/pregen.js +117 -5
- package/lib/validator/bomValidator.js +26 -5
- package/lib/validator/generated/runtime.mjs +13 -0
- package/lib/validator/generated/validate-1.6.mjs +26 -7
- package/lib/validator/generated/validate-1.7.mjs +31 -12
- package/lib/validator/generated/validate-2.0.mjs +30 -11
- package/lib/validator/index.js +25 -10
- package/lib/validator/reporters/json.js +1 -0
- package/package.json +23 -23
- package/types/bin/cdxgen-secure.d.ts +3 -0
- package/types/bin/cdxgen-secure.d.ts.map +1 -0
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +9 -2
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +43 -0
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +44 -1
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts +7 -4
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts +3 -1
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/activity.d.ts.map +1 -1
- package/types/lib/core/env.d.ts +27 -2
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/httpClient.d.ts +13 -8
- package/types/lib/core/httpClient.d.ts.map +1 -1
- package/types/lib/core/pluginRun.d.ts +97 -0
- package/types/lib/core/pluginRun.d.ts.map +1 -0
- package/types/lib/core/processTree.d.ts +36 -0
- package/types/lib/core/processTree.d.ts.map +1 -0
- package/types/lib/core/projectConfig.d.ts.map +1 -1
- package/types/lib/core/projectTooling.d.ts +41 -0
- package/types/lib/core/projectTooling.d.ts.map +1 -0
- package/types/lib/core/propertySanitizer.d.ts +26 -0
- package/types/lib/core/propertySanitizer.d.ts.map +1 -1
- package/types/lib/core/runState.d.ts +29 -0
- package/types/lib/core/runState.d.ts.map +1 -0
- package/types/lib/core/toml.d.ts +20 -0
- package/types/lib/core/toml.d.ts.map +1 -0
- package/types/lib/ecosystems/asarutils.d.ts.map +1 -1
- package/types/lib/ecosystems/bunutils.d.ts.map +1 -1
- package/types/lib/ecosystems/cargoCache.d.ts +12 -0
- package/types/lib/ecosystems/cargoCache.d.ts.map +1 -1
- package/types/lib/ecosystems/cmakeResolver.d.ts +5 -3
- package/types/lib/ecosystems/cmakeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/cppBuildContext.d.ts +55 -0
- package/types/lib/ecosystems/cppBuildContext.d.ts.map +1 -0
- package/types/lib/ecosystems/cppEvidence.d.ts +19 -3
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts +92 -0
- package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -0
- package/types/lib/ecosystems/denoutils.d.ts +9 -3
- package/types/lib/ecosystems/denoutils.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts +62 -13
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/golem.d.ts +81 -1
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +59 -7
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/kosi.d.ts.map +1 -1
- package/types/lib/ecosystems/npmutils.d.ts +15 -0
- package/types/lib/ecosystems/npmutils.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-dotnet.d.ts +155 -5
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-elm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-gleam.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-go.d.ts +119 -5
- package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +6 -1
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-julia.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-jvm.d.ts +74 -3
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +21 -59
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +57 -6
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-terraform.d.ts +38 -21
- package/types/lib/ecosystems/parsers-terraform.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +26 -1
- package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
- package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts +21 -1
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/ecosystems/sbtutils.d.ts +88 -2
- package/types/lib/ecosystems/sbtutils.d.ts.map +1 -1
- package/types/lib/ecosystems/scalacliutils.d.ts +56 -0
- package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -0
- package/types/lib/ecosystems/scalasem.d.ts +311 -0
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -0
- package/types/lib/ecosystems/terraformRegistry.d.ts +9 -0
- package/types/lib/ecosystems/terraformRegistry.d.ts.map +1 -0
- package/types/lib/ecosystems/utils.d.ts +2 -2
- package/types/lib/ecosystems/utils.d.ts.map +1 -1
- package/types/lib/ecosystems/vendoredCode.d.ts +32 -0
- package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +100 -8
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/swiftsem.d.ts +10 -0
- package/types/lib/evinser/swiftsem.d.ts.map +1 -1
- package/types/lib/helpers/bomSigner.d.ts +80 -4
- package/types/lib/helpers/bomSigner.d.ts.map +1 -1
- package/types/lib/inventory/agentSkillSpec.d.ts +13 -0
- package/types/lib/inventory/agentSkillSpec.d.ts.map +1 -0
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/analyzer.d.ts.map +1 -1
- package/types/lib/inventory/apkInstalledDb.d.ts +42 -0
- package/types/lib/inventory/apkInstalledDb.d.ts.map +1 -0
- package/types/lib/inventory/atomUtils.d.ts +96 -10
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/auditCategories.d.ts +3 -0
- package/types/lib/inventory/auditCategories.d.ts.map +1 -1
- package/types/lib/inventory/buildToolRateLimit.d.ts +38 -0
- package/types/lib/inventory/buildToolRateLimit.d.ts.map +1 -0
- package/types/lib/inventory/cacheCommands.d.ts +2 -1
- package/types/lib/inventory/cacheCommands.d.ts.map +1 -1
- package/types/lib/inventory/cacheDir.d.ts +12 -4
- package/types/lib/inventory/cacheDir.d.ts.map +1 -1
- package/types/lib/inventory/certificates.d.ts +205 -0
- package/types/lib/inventory/certificates.d.ts.map +1 -0
- package/types/lib/inventory/cmakeBuildDirs.d.ts +58 -0
- package/types/lib/inventory/cmakeBuildDirs.d.ts.map +1 -0
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/deps.d.ts +61 -2
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/display.d.ts +18 -0
- package/types/lib/inventory/display.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +202 -14
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dosaiParsers.d.ts +53 -7
- package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
- package/types/lib/inventory/dynamic.d.ts +16 -1
- package/types/lib/inventory/dynamic.d.ts.map +1 -1
- package/types/lib/inventory/envcontext.d.ts +40 -2
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts +48 -14
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/fetchBatch.d.ts +83 -14
- package/types/lib/inventory/fetchBatch.d.ts.map +1 -1
- package/types/lib/inventory/fetchDiskCache.d.ts +169 -0
- package/types/lib/inventory/fetchDiskCache.d.ts.map +1 -0
- package/types/lib/inventory/forgeEnricher.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/goBuildInfo.d.ts +10 -0
- package/types/lib/inventory/goBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/hbom.d.ts.map +1 -1
- package/types/lib/inventory/hbomAnalysis.d.ts +10 -0
- package/types/lib/inventory/hbomAnalysis.d.ts.map +1 -1
- package/types/lib/inventory/hostTopology.d.ts.map +1 -1
- package/types/lib/inventory/jvmLocalRepos.d.ts +178 -0
- package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -0
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/osPackagePurl.d.ts +99 -0
- package/types/lib/inventory/osPackagePurl.d.ts.map +1 -0
- package/types/lib/inventory/osPackageResolver.d.ts +6 -2
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
- package/types/lib/inventory/osinfo.d.ts +31 -6
- package/types/lib/inventory/osinfo.d.ts.map +1 -1
- package/types/lib/inventory/osqueryTransform.d.ts +51 -0
- package/types/lib/inventory/osqueryTransform.d.ts.map +1 -1
- package/types/lib/inventory/parentSelection.d.ts +34 -0
- package/types/lib/inventory/parentSelection.d.ts.map +1 -0
- package/types/lib/inventory/phpBuildInfo.d.ts +142 -0
- package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/phpHostProbe.d.ts +35 -0
- package/types/lib/inventory/phpHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/rootfsCerts.d.ts +27 -0
- package/types/lib/inventory/rootfsCerts.d.ts.map +1 -0
- package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/scalaCoords.d.ts +80 -0
- package/types/lib/inventory/scalaCoords.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +28 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/spdx.d.ts +24 -0
- package/types/lib/inventory/spdx.d.ts.map +1 -1
- package/types/lib/inventory/traceRunner.d.ts +16 -1
- package/types/lib/inventory/traceRunner.d.ts.map +1 -1
- package/types/lib/inventory/tracedCrypto.d.ts +64 -0
- package/types/lib/inventory/tracedCrypto.d.ts.map +1 -0
- package/types/lib/managers/binary.d.ts +10 -0
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +12 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/managers/oci.d.ts +3 -1
- package/types/lib/managers/oci.d.ts.map +1 -1
- package/types/lib/parsers/cmakeCache.d.ts +16 -0
- package/types/lib/parsers/cmakeCache.d.ts.map +1 -1
- package/types/lib/parsers/cmakeLists.d.ts +2 -1
- package/types/lib/parsers/cmakeLists.d.ts.map +1 -1
- package/types/lib/parsers/cmakePresets.d.ts +78 -0
- package/types/lib/parsers/cmakePresets.d.ts.map +1 -0
- package/types/lib/parsers/compileCommands.d.ts +115 -0
- package/types/lib/parsers/compileCommands.d.ts.map +1 -0
- package/types/lib/parsers/email.d.ts +19 -0
- package/types/lib/parsers/email.d.ts.map +1 -0
- package/types/lib/parsers/largeJson.d.ts +13 -0
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- package/types/lib/parsers/strictJson.d.ts +46 -0
- package/types/lib/parsers/strictJson.d.ts.map +1 -0
- package/types/lib/parsers/terraformConfig.d.ts +70 -0
- package/types/lib/parsers/terraformConfig.d.ts.map +1 -0
- package/types/lib/parsers/terraformSource.d.ts +66 -0
- package/types/lib/parsers/terraformSource.d.ts.map +1 -0
- package/types/lib/server/server.d.ts +8 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
- package/types/lib/stages/postgen/introspection/reflect.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts +7 -4
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +14 -1
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/index.d.ts +8 -0
- package/types/lib/validator/index.d.ts.map +1 -1
- package/types/lib/validator/reporters/json.d.ts.map +1 -1
- package/lib/third-party/arborist/snapshots/calc-dep-flags.test.cjs +0 -462
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// Bounded Go buildinfo reader for executable file components: recovers the
|
|
2
|
+
// toolchain version a binary was built with, so a BOM can answer "which Go
|
|
3
|
+
// programs predate the CVE-2026-111943 distrust list". Only the header and
|
|
4
|
+
// the inline version string are read; pointer-based (pre-1.18) layouts are
|
|
5
|
+
// reported as such and never followed.
|
|
6
|
+
//
|
|
7
|
+
// Layout: go/src/debug/buildinfo/buildinfo.go at tag go1.27.2. The 14-byte
|
|
8
|
+
// magic `\xff Go buildinf:` is 16-byte aligned; the next two bytes are the
|
|
9
|
+
// pointer size and flags. When flags&2 is set the version string follows as a
|
|
10
|
+
// uvarint length plus bytes. The magic can appear anywhere in the file's
|
|
11
|
+
// initial segment, so the search scans aligned offsets up to a cap.
|
|
12
|
+
|
|
13
|
+
import { closeSync, fstatSync, openSync, readSync } from "node:fs";
|
|
14
|
+
|
|
15
|
+
const BUILD_INFO_MAGIC = Buffer.from([
|
|
16
|
+
0xff, 0x20, 0x47, 0x6f, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x66,
|
|
17
|
+
0x3a,
|
|
18
|
+
]);
|
|
19
|
+
// The buildinfo section follows text and rodata, often late in the file
|
|
20
|
+
// (37 MB into a 40 MB gh binary), so the cap must cover large binaries.
|
|
21
|
+
const MAX_SEARCH_BYTES = 512 * 1024 * 1024;
|
|
22
|
+
const READ_CHUNK_BYTES = 64 * 1024;
|
|
23
|
+
const MAX_VERSION_BYTES = 128;
|
|
24
|
+
export const PRE_1_18_VERSION = "unknown-pre-1.18";
|
|
25
|
+
|
|
26
|
+
function readUvarint(buffer, offset) {
|
|
27
|
+
let value = 0;
|
|
28
|
+
let shift = 0;
|
|
29
|
+
for (let i = 0; i < 10 && offset + i < buffer.length; i++) {
|
|
30
|
+
const byte = buffer[offset + i];
|
|
31
|
+
value += (byte & 0x7f) * 2 ** shift;
|
|
32
|
+
if (!(byte & 0x80)) {
|
|
33
|
+
return { value, next: offset + i + 1 };
|
|
34
|
+
}
|
|
35
|
+
shift += 7;
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function parseHeaderAt(buffer, offset, limit) {
|
|
41
|
+
if (offset + 32 > limit) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
for (let i = 0; i < BUILD_INFO_MAGIC.length; i++) {
|
|
45
|
+
if (buffer[offset + i] !== BUILD_INFO_MAGIC[i]) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const pointerSize = buffer[offset + 14];
|
|
50
|
+
const flags = buffer[offset + 15];
|
|
51
|
+
if (pointerSize !== 4 && pointerSize !== 8) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
if (!(flags & 0x02)) {
|
|
55
|
+
// Version lives behind pointers (pre-1.18 layout): not followed.
|
|
56
|
+
return PRE_1_18_VERSION;
|
|
57
|
+
}
|
|
58
|
+
// The inline strings start 16 bytes past the magic header (magic 14 +
|
|
59
|
+
// pointerSize 1 + flags 1, then a reserved 16-byte slot), as a uvarint
|
|
60
|
+
// length followed by the bytes.
|
|
61
|
+
const varint = readUvarint(buffer, offset + 32);
|
|
62
|
+
if (
|
|
63
|
+
!varint ||
|
|
64
|
+
varint.value === 0 ||
|
|
65
|
+
varint.value > MAX_VERSION_BYTES ||
|
|
66
|
+
varint.next + varint.value > limit
|
|
67
|
+
) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
const version = buffer.toString(
|
|
71
|
+
"latin1",
|
|
72
|
+
varint.next,
|
|
73
|
+
varint.next + varint.value,
|
|
74
|
+
);
|
|
75
|
+
if (!/^go[0-9]/.test(version)) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
return version;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Read the Go toolchain version from an executable's buildinfo header.
|
|
83
|
+
*
|
|
84
|
+
* @param {string} filePath absolute path to a possible Go binary
|
|
85
|
+
* @returns {string|undefined} `go1.x.y`, `unknown-pre-1.18` for old layouts,
|
|
86
|
+
* or undefined when the file carries no Go buildinfo
|
|
87
|
+
*/
|
|
88
|
+
export function readGoBuildVersion(filePath) {
|
|
89
|
+
if (typeof filePath !== "string" || !filePath) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
let fd;
|
|
93
|
+
try {
|
|
94
|
+
fd = openSync(filePath, "r");
|
|
95
|
+
const size = fstatSync(fd).size;
|
|
96
|
+
if (size < 32) {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
const searchLimit = Math.min(size, MAX_SEARCH_BYTES);
|
|
100
|
+
// Each chunk examines the aligned offsets that start inside its 64 KiB
|
|
101
|
+
// window, reading a fixed overlap past it so a header near the window
|
|
102
|
+
// end is parsed whole; the next chunk starts at the next window.
|
|
103
|
+
const OVERLAP_BYTES = 256;
|
|
104
|
+
const chunk = Buffer.alloc(READ_CHUNK_BYTES + OVERLAP_BYTES);
|
|
105
|
+
for (
|
|
106
|
+
let position = 0;
|
|
107
|
+
position < searchLimit;
|
|
108
|
+
position += READ_CHUNK_BYTES
|
|
109
|
+
) {
|
|
110
|
+
const want = Math.min(READ_CHUNK_BYTES + OVERLAP_BYTES, size - position);
|
|
111
|
+
const read = readSync(fd, chunk, 0, want, position);
|
|
112
|
+
if (read < 32) {
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
// position is a multiple of 16, so chunk offsets stay on the file's
|
|
116
|
+
// 16-byte grid.
|
|
117
|
+
for (
|
|
118
|
+
let offset = 0;
|
|
119
|
+
offset < READ_CHUNK_BYTES && offset + 32 <= read;
|
|
120
|
+
offset += 16
|
|
121
|
+
) {
|
|
122
|
+
const version = parseHeaderAt(chunk, offset, read);
|
|
123
|
+
if (version) {
|
|
124
|
+
return version;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return undefined;
|
|
129
|
+
} catch {
|
|
130
|
+
return undefined;
|
|
131
|
+
} finally {
|
|
132
|
+
if (fd !== undefined) {
|
|
133
|
+
try {
|
|
134
|
+
closeSync(fd);
|
|
135
|
+
} catch {
|
|
136
|
+
// already closed
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
package/lib/inventory/hbom.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { basename, win32 } from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
2
4
|
|
|
3
5
|
import {
|
|
4
6
|
isDryRun,
|
|
@@ -40,6 +42,18 @@ function getConfiguredHbomPathAllowlist() {
|
|
|
40
42
|
);
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
// A Windows plan can be inspected from any host (`getCommandPlan`), where
|
|
46
|
+
// node:path would not split a path on its backslashes.
|
|
47
|
+
function isWindowsStyleCommand(command) {
|
|
48
|
+
return command.includes("\\") || /^[A-Za-z]:/u.test(command);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getHbomCommandName(command) {
|
|
52
|
+
return isWindowsStyleCommand(command)
|
|
53
|
+
? win32.basename(command)
|
|
54
|
+
: basename(command);
|
|
55
|
+
}
|
|
56
|
+
|
|
43
57
|
function isAllowedHbomCommand(command, allowlistValue = undefined) {
|
|
44
58
|
const normalizedCommand = `${command ?? ""}`.trim();
|
|
45
59
|
if (!normalizedCommand) {
|
|
@@ -51,7 +65,10 @@ function isAllowedHbomCommand(command, allowlistValue = undefined) {
|
|
|
51
65
|
if (!allowlistEntries.length) {
|
|
52
66
|
return true;
|
|
53
67
|
}
|
|
54
|
-
|
|
68
|
+
// Exact and case-sensitive on purpose: cdx-hbom applies the same allowlist
|
|
69
|
+
// again when it spawns, so a looser preflight would pass here and then run
|
|
70
|
+
// nothing, which silently degrades the BOM.
|
|
71
|
+
const commandName = getHbomCommandName(normalizedCommand);
|
|
55
72
|
return allowlistEntries.some(
|
|
56
73
|
(entry) => entry === normalizedCommand || entry === commandName,
|
|
57
74
|
);
|
|
@@ -61,9 +78,27 @@ function formatHbomCommandTarget(command, args = []) {
|
|
|
61
78
|
return `${command}${args.length ? ` ${args.join(" ")}` : ""}`;
|
|
62
79
|
}
|
|
63
80
|
|
|
81
|
+
// Windows plan entries carry a multi-kilobyte PowerShell script as their last
|
|
82
|
+
// argument. Like the cdx-hbom trace and evidence, the preflight names it by
|
|
83
|
+
// digest so a blocked run does not print every script.
|
|
84
|
+
function summarizeHbomPlanArgs(planEntry) {
|
|
85
|
+
const args = [...(planEntry.args || [])];
|
|
86
|
+
if (planEntry.parser !== "windows-envelope" || !args.length) {
|
|
87
|
+
return args;
|
|
88
|
+
}
|
|
89
|
+
const digest = createHash("sha256")
|
|
90
|
+
.update(String(args.at(-1)))
|
|
91
|
+
.digest("hex")
|
|
92
|
+
.slice(0, 12);
|
|
93
|
+
return ["-Command", planEntry.id, "script", `sha256:${digest}`];
|
|
94
|
+
}
|
|
95
|
+
|
|
64
96
|
function buildHbomPlanActivities(planEntry, normalizedOptions) {
|
|
65
97
|
const baseArgs = [...(planEntry.args || [])];
|
|
66
|
-
const baseTarget = formatHbomCommandTarget(
|
|
98
|
+
const baseTarget = formatHbomCommandTarget(
|
|
99
|
+
planEntry.command,
|
|
100
|
+
summarizeHbomPlanArgs(planEntry),
|
|
101
|
+
);
|
|
67
102
|
const activities = [
|
|
68
103
|
{
|
|
69
104
|
args: baseArgs,
|
|
@@ -115,7 +150,7 @@ function collectDisallowedHbomCommands(
|
|
|
115
150
|
}
|
|
116
151
|
const existingEntry = disallowedCommands.get(requestedCommand) ?? {
|
|
117
152
|
command: requestedCommand,
|
|
118
|
-
commandName:
|
|
153
|
+
commandName: getHbomCommandName(requestedCommand),
|
|
119
154
|
ids: new Set(),
|
|
120
155
|
targets: new Set(),
|
|
121
156
|
};
|
|
@@ -214,6 +249,28 @@ function createHbomAllowlistPreflightError(
|
|
|
214
249
|
return new Error(messageLines.join("\n"));
|
|
215
250
|
}
|
|
216
251
|
|
|
252
|
+
/**
|
|
253
|
+
* Whether cdx-hbom spawns no command for these collector options.
|
|
254
|
+
*
|
|
255
|
+
* Only the Linux collector reads `includeCommandEnrichment: false` as "run no
|
|
256
|
+
* commands", and even there the privileged dmidecode step still runs. The
|
|
257
|
+
* Darwin collector ignores the option, and the Windows collector always runs
|
|
258
|
+
* its `windows-cim-platform` batch, so those plans are checked in full.
|
|
259
|
+
*
|
|
260
|
+
* @param {object} normalizedOptions Collector options from normalizeHbomOptions
|
|
261
|
+
* @returns {boolean} `true` when the allowlist has nothing to check
|
|
262
|
+
*/
|
|
263
|
+
function collectorSpawnsNoCommands(normalizedOptions) {
|
|
264
|
+
const targetPlatform = `${normalizedOptions.platform ?? process.platform}`
|
|
265
|
+
.trim()
|
|
266
|
+
.toLowerCase();
|
|
267
|
+
return (
|
|
268
|
+
normalizedOptions.includeCommandEnrichment === false &&
|
|
269
|
+
normalizedOptions.includePrivilegedEnrichment !== true &&
|
|
270
|
+
targetPlatform === "linux"
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
217
274
|
async function enforceSecureModeHbomAllowlists(hbomModule, normalizedOptions) {
|
|
218
275
|
if (isDryRun || normalizedOptions?.isDryRun || !isSecureMode) {
|
|
219
276
|
return;
|
|
@@ -249,7 +306,7 @@ async function enforceSecureModeHbomAllowlists(hbomModule, normalizedOptions) {
|
|
|
249
306
|
: [];
|
|
250
307
|
} else if (
|
|
251
308
|
hasCommandAllowlist &&
|
|
252
|
-
normalizedOptions
|
|
309
|
+
!collectorSpawnsNoCommands(normalizedOptions)
|
|
253
310
|
) {
|
|
254
311
|
traceActivities = hbomModule
|
|
255
312
|
.getCommandPlan(normalizedOptions)
|
|
@@ -259,7 +316,7 @@ async function enforceSecureModeHbomAllowlists(hbomModule, normalizedOptions) {
|
|
|
259
316
|
}
|
|
260
317
|
|
|
261
318
|
const disallowedCommands =
|
|
262
|
-
hasCommandAllowlist && normalizedOptions
|
|
319
|
+
hasCommandAllowlist && !collectorSpawnsNoCommands(normalizedOptions)
|
|
263
320
|
? collectDisallowedHbomCommands(traceActivities, commandAllowlistValue)
|
|
264
321
|
: [];
|
|
265
322
|
const disallowedPaths = hasPathAllowlist
|
|
@@ -398,8 +455,11 @@ export function normalizeHbomOptions(options = {}) {
|
|
|
398
455
|
timeoutValue === undefined || timeoutValue === null || timeoutValue === ""
|
|
399
456
|
? undefined
|
|
400
457
|
: Number.parseInt(`${timeoutValue}`, 10);
|
|
458
|
+
// yargs negates `--no-command-enrichment` into `commandEnrichment: false`
|
|
459
|
+
// and never sets `noCommandEnrichment`, so the CLIs rely on this spelling.
|
|
401
460
|
const includeCommandEnrichment =
|
|
402
|
-
options.includeCommandEnrichment ??
|
|
461
|
+
options.includeCommandEnrichment ??
|
|
462
|
+
(options.commandEnrichment !== false && !options.noCommandEnrichment);
|
|
403
463
|
const allowPartial = options.allowPartial ?? !options.strict;
|
|
404
464
|
|
|
405
465
|
return {
|
|
@@ -174,6 +174,22 @@ export function isHbomLikeBom(bomJson) {
|
|
|
174
174
|
);
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Explain how the permission-denied enrichments of an HBOM can be recovered.
|
|
179
|
+
*
|
|
180
|
+
* Windows never uses sudo: the elevated-only batch needs an already-elevated
|
|
181
|
+
* session, and a network logon is denied every WMI query.
|
|
182
|
+
*
|
|
183
|
+
* @param {string|undefined} platform `cdx:hbom:platform` of the HBOM
|
|
184
|
+
* @returns {string} Guidance for the platform; the Linux wording for any other platform
|
|
185
|
+
*/
|
|
186
|
+
export function getHbomPrivilegeGuidance(platform) {
|
|
187
|
+
if (`${platform ?? ""}`.toLowerCase() === "windows") {
|
|
188
|
+
return "Some Windows enrichments were denied. Run HBOM from a local session (a non-administrator over SSH or WinRM is denied every WMI query) and, for the TPM, BitLocker, storage-reliability and Secure Boot data, from an elevated (Run as administrator) prompt with --privileged. HBOM never prompts for elevation.";
|
|
189
|
+
}
|
|
190
|
+
return "Some Linux enrichments can likely succeed only with --privileged and a target environment that allows non-interactive sudo.";
|
|
191
|
+
}
|
|
192
|
+
|
|
177
193
|
/**
|
|
178
194
|
* Return a component's `cdx:hbom:hardwareClass` property value.
|
|
179
195
|
*
|
|
@@ -276,6 +276,7 @@ function isFilesystemIdentity(value) {
|
|
|
276
276
|
function createRuntimeIndexes(runtimeComponents) {
|
|
277
277
|
const interfaceAddressesByName = new Map();
|
|
278
278
|
const kernelModulesByName = new Map();
|
|
279
|
+
const logicalDrivesByDeviceId = new Map();
|
|
279
280
|
const mountPathsByDevice = new Map();
|
|
280
281
|
const mountPathsByPath = new Map();
|
|
281
282
|
const runtimeByStorageIdentity = new Map();
|
|
@@ -306,6 +307,13 @@ function createRuntimeIndexes(runtimeComponents) {
|
|
|
306
307
|
component["bom-ref"],
|
|
307
308
|
);
|
|
308
309
|
}
|
|
310
|
+
if (runtimeCategory === "logical_drives") {
|
|
311
|
+
appendMapEntry(
|
|
312
|
+
logicalDrivesByDeviceId,
|
|
313
|
+
toNormalizedIdentity(getPropertyValue(component, "device_id")),
|
|
314
|
+
component["bom-ref"],
|
|
315
|
+
);
|
|
316
|
+
}
|
|
309
317
|
if (runtimeCategory === "mount_hardening") {
|
|
310
318
|
appendMapEntry(
|
|
311
319
|
mountPathsByDevice,
|
|
@@ -339,6 +347,7 @@ function createRuntimeIndexes(runtimeComponents) {
|
|
|
339
347
|
return {
|
|
340
348
|
interfaceAddressesByName,
|
|
341
349
|
kernelModulesByName,
|
|
350
|
+
logicalDrivesByDeviceId,
|
|
342
351
|
mountPathsByDevice,
|
|
343
352
|
mountPathsByPath,
|
|
344
353
|
runtimeByStorageIdentity,
|
|
@@ -532,6 +541,14 @@ function createDependencyEdgeList(
|
|
|
532
541
|
"mount_hardening",
|
|
533
542
|
Array.from(indexes.mountPathsByPath.get(mountPath) || []),
|
|
534
543
|
);
|
|
544
|
+
// The Windows osquery pack has no mount_hardening; a volume's drive
|
|
545
|
+
// letter (C:) is the device_id of its logical drive.
|
|
546
|
+
addCategoryRefs(
|
|
547
|
+
linkedRefs,
|
|
548
|
+
linkedCategoryRefs,
|
|
549
|
+
"logical_drives",
|
|
550
|
+
Array.from(indexes.logicalDrivesByDeviceId.get(mountPath) || []),
|
|
551
|
+
);
|
|
535
552
|
}
|
|
536
553
|
const explicitFilesystemIdentity = isFilesystemIdentity(component.version)
|
|
537
554
|
? toNormalizedIdentity(component.version)
|
|
@@ -788,6 +805,10 @@ export function mergeHostInventoryBoms(hbomJson, obomData) {
|
|
|
788
805
|
if (obomData.parentComponent?.name && obomData.parentComponent?.type) {
|
|
789
806
|
runtimeComponents.unshift(obomData.parentComponent);
|
|
790
807
|
}
|
|
808
|
+
// trimComponents keys a component without a purl or bom-ref on name and
|
|
809
|
+
// version, which would fold hardware that shares a name (every Windows
|
|
810
|
+
// volume without a drive letter is named "Volume") into one component.
|
|
811
|
+
ensureBomRefs(hbomJson);
|
|
791
812
|
const mergedBomJson = {
|
|
792
813
|
...hbomJson,
|
|
793
814
|
components: trimComponents([
|