@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.
- package/README.md +9 -9
- package/bin/cdxgen-secure.js +15 -0
- package/bin/cdxgen.js +29 -5
- package/bin/evinse.js +8 -0
- package/bin/hbom.js +15 -7
- package/bin/repl.js +29 -0
- package/bin/validate.js +6 -0
- package/data/cbomosdb-queries.json +13 -1
- package/data/component-tags.json +8 -0
- package/data/license-aliases.json +24 -2
- package/data/queries-darwin.json +25 -1
- package/data/queries-win.json +19 -1
- package/data/queries.json +41 -0
- package/data/remediations.json +407 -1
- package/data/rules/ai-bom.yaml +1 -1
- package/data/rules/brotli-decoder.yaml +107 -0
- package/data/rules/cbom-security.yaml +235 -4
- 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/vscode-extensions.yaml +75 -0
- package/data/spdx-license-list.json +121 -7
- package/data/spdx-licenses.json +69 -0
- package/data/spdx.schema.json +845 -2
- package/lib/audit/index.js +14 -0
- package/lib/cli/bomAssembly.js +120 -6
- package/lib/cli/cliOptions.js +110 -3
- package/lib/cli/index.js +182 -6
- package/lib/cli/jsBom.js +153 -64
- package/lib/cli/jvmBom.js +363 -66
- package/lib/cli/managedBom.js +853 -87
- package/lib/cli/nativeBom.js +267 -33
- package/lib/core/boundedFile.js +344 -0
- package/lib/core/brotliProbe.js +182 -0
- package/lib/core/env.js +38 -8
- package/lib/core/fs.js +40 -19
- package/lib/core/httpClient.js +172 -46
- package/lib/core/lockPaths.js +38 -0
- package/lib/core/paths.js +24 -1
- package/lib/core/processTree.js +5 -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/toolRegistry.js +170 -0
- package/lib/ecosystems/cppEvidence.js +263 -106
- package/lib/ecosystems/cppIncludeResolver.js +16 -5
- package/lib/ecosystems/ecosystems.js +25 -10
- package/lib/ecosystems/gemHostProbe.js +301 -0
- package/lib/ecosystems/golem.js +550 -6
- package/lib/ecosystems/gradleutils.js +858 -244
- package/lib/ecosystems/parsers-bazel.js +107 -6
- package/lib/ecosystems/parsers-dotnet.js +117 -18
- package/lib/ecosystems/parsers-go.js +1090 -367
- package/lib/ecosystems/parsers-js.js +505 -22
- package/lib/ecosystems/parsers-jvm.js +259 -17
- package/lib/ecosystems/parsers-misc.js +438 -64
- package/lib/ecosystems/parsers-python.js +100 -12
- package/lib/ecosystems/pythonutils.js +128 -2
- package/lib/ecosystems/rubyutils.js +544 -34
- package/lib/ecosystems/rusi.js +10 -0
- package/lib/ecosystems/scalacliutils.js +4 -1
- package/lib/ecosystems/scalasem.js +798 -151
- package/lib/ecosystems/vendoredCode.js +237 -3
- package/lib/ecosystems/venvProbe.js +360 -0
- package/lib/evinser/evinser.js +472 -61
- package/lib/evinser/swiftsem.js +68 -5
- package/lib/helpers/agenticToolutils.js +413 -93
- package/lib/helpers/vsixutils.js +1574 -315
- package/lib/inventory/agentSkillSpec.js +17 -0
- package/lib/inventory/apkInstalledDb.js +243 -0
- package/lib/inventory/atomUtils.js +110 -0
- package/lib/inventory/auditCategories.js +3 -3
- package/lib/inventory/brotliDecoder.js +142 -0
- package/lib/inventory/buildToolRateLimit.js +1 -1
- package/lib/inventory/cacheDir.js +52 -9
- package/lib/inventory/cbomutils.js +56 -7
- package/lib/inventory/certificates.js +2371 -0
- package/lib/inventory/communityAiConfigParser.js +4 -9
- package/lib/inventory/deps.js +41 -4
- package/lib/inventory/display.js +200 -3
- package/lib/inventory/dosai.js +639 -63
- package/lib/inventory/dotnetRuntime.js +217 -0
- package/lib/inventory/dynamic.js +45 -3
- package/lib/inventory/envcontext.js +475 -18
- package/lib/inventory/evidenceUtils.js +447 -23
- package/lib/inventory/fetchBatch.js +1 -1
- package/lib/inventory/formulationParsers.js +32 -3
- package/lib/inventory/goBuildInfo.js +140 -0
- package/lib/inventory/gtfobins.js +13 -0
- package/lib/inventory/hbom.js +67 -7
- package/lib/inventory/hbomAnalysis.js +16 -0
- package/lib/inventory/hostRuntimeProbe.js +686 -0
- package/lib/inventory/hostTopology.js +21 -0
- package/lib/inventory/jvmLocalRepos.js +9 -2
- package/lib/inventory/jvmToolEnv.js +29 -0
- package/lib/inventory/licenseEnhancer.js +12 -0
- package/lib/inventory/mavenCentralMirror.js +534 -0
- package/lib/inventory/nodeBuildInfo.js +218 -0
- package/lib/inventory/nodeHostProbe.js +202 -0
- package/lib/inventory/osPackagePurl.js +244 -0
- package/lib/inventory/osPackageResolver.js +271 -87
- package/lib/inventory/osinfo.js +79 -31
- package/lib/inventory/osqueryTransform.js +114 -5
- package/lib/inventory/phpBuildInfo.js +438 -0
- package/lib/inventory/phpHostProbe.js +185 -0
- package/lib/inventory/rootfsCerts.js +426 -0
- package/lib/inventory/rubyBuildInfo.js +972 -0
- package/lib/inventory/rubyHostProbe.js +218 -0
- package/lib/inventory/scalaCoords.js +4 -3
- package/lib/inventory/scalaDedupe.js +440 -0
- package/lib/inventory/source.js +256 -5
- package/lib/inventory/spdx.js +144 -0
- package/lib/inventory/traceRunner.js +5 -1
- package/lib/inventory/tracedCrypto.js +129 -0
- package/lib/managers/binary.js +866 -186
- package/lib/managers/docker.js +245 -12
- package/lib/parsers/email.js +277 -0
- package/lib/parsers/largeJson.js +62 -13
- package/lib/parsers/vscodeExtensionId.js +183 -0
- package/lib/server/server.js +198 -2
- package/lib/stages/postgen/annotator.js +17 -1
- package/lib/stages/postgen/introspection/reflect.js +4 -1
- package/lib/stages/postgen/postgen.js +5 -5
- package/lib/stages/postgen/ruleEngine.js +71 -6
- package/lib/stages/postgen/specVersionCompat.js +30 -0
- package/lib/stages/pregen/envAudit.js +1 -0
- package/lib/stages/pregen/pregen.js +231 -62
- package/lib/validator/bomValidator.js +32 -6
- package/lib/validator/generated/runtime.mjs +13 -0
- package/lib/validator/generated/validate-1.6.mjs +27 -8
- package/lib/validator/generated/validate-1.7.mjs +32 -13
- package/lib/validator/generated/validate-2.0.mjs +31 -12
- package/lib/validator/index.js +1 -1
- package/package.json +19 -18
- 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 +22 -3
- 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 +1 -17
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +20 -0
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/boundedFile.d.ts +70 -0
- package/types/lib/core/boundedFile.d.ts.map +1 -0
- package/types/lib/core/brotliProbe.d.ts +37 -0
- package/types/lib/core/brotliProbe.d.ts.map +1 -0
- package/types/lib/core/env.d.ts +22 -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 +24 -0
- package/types/lib/core/httpClient.d.ts.map +1 -1
- package/types/lib/core/lockPaths.d.ts +19 -0
- package/types/lib/core/lockPaths.d.ts.map +1 -0
- package/types/lib/core/processTree.d.ts +2 -0
- package/types/lib/core/processTree.d.ts.map +1 -1
- 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/toolRegistry.d.ts +36 -0
- package/types/lib/core/toolRegistry.d.ts.map +1 -0
- package/types/lib/ecosystems/cppEvidence.d.ts +40 -13
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts +2 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/gemHostProbe.d.ts +28 -0
- package/types/lib/ecosystems/gemHostProbe.d.ts.map +1 -0
- 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 +57 -21
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-dotnet.d.ts +40 -4
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-go.d.ts +85 -13
- package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +17 -20
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-jvm.d.ts +28 -2
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +37 -58
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +14 -3
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +19 -1
- package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts +144 -12
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -1
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
- package/types/lib/ecosystems/vendoredCode.d.ts +26 -0
- package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -1
- package/types/lib/ecosystems/venvProbe.d.ts +40 -0
- package/types/lib/ecosystems/venvProbe.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +88 -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/inventory/agentSkillSpec.d.ts +13 -0
- package/types/lib/inventory/agentSkillSpec.d.ts.map +1 -0
- 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 +33 -0
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/brotliDecoder.d.ts +58 -0
- package/types/lib/inventory/brotliDecoder.d.ts.map +1 -0
- package/types/lib/inventory/cacheDir.d.ts +12 -4
- package/types/lib/inventory/cacheDir.d.ts.map +1 -1
- package/types/lib/inventory/cbomutils.d.ts +17 -0
- package/types/lib/inventory/cbomutils.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/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/deps.d.ts +2 -1
- 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 +162 -7
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dotnetRuntime.d.ts +44 -0
- package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -0
- package/types/lib/inventory/dynamic.d.ts +6 -1
- package/types/lib/inventory/dynamic.d.ts.map +1 -1
- package/types/lib/inventory/envcontext.d.ts +92 -8
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts +29 -10
- package/types/lib/inventory/evidenceUtils.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/gtfobins.d.ts.map +1 -1
- 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/hostRuntimeProbe.d.ts +44 -0
- package/types/lib/inventory/hostRuntimeProbe.d.ts.map +1 -0
- package/types/lib/inventory/hostTopology.d.ts.map +1 -1
- package/types/lib/inventory/jvmToolEnv.d.ts +12 -0
- package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
- package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -1
- package/types/lib/inventory/mavenCentralMirror.d.ts +170 -0
- package/types/lib/inventory/mavenCentralMirror.d.ts.map +1 -0
- package/types/lib/inventory/nodeBuildInfo.d.ts +95 -0
- package/types/lib/inventory/nodeBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/nodeHostProbe.d.ts +15 -0
- package/types/lib/inventory/nodeHostProbe.d.ts.map +1 -0
- 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 +44 -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/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/rubyBuildInfo.d.ts +271 -0
- package/types/lib/inventory/rubyBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/rubyHostProbe.d.ts +47 -0
- package/types/lib/inventory/rubyHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +38 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/spdx.d.ts +15 -0
- package/types/lib/inventory/spdx.d.ts.map +1 -1
- package/types/lib/inventory/traceRunner.d.ts +4 -1
- package/types/lib/inventory/traceRunner.d.ts.map +1 -1
- package/types/lib/inventory/tracedCrypto.d.ts +22 -0
- package/types/lib/inventory/tracedCrypto.d.ts.map +1 -1
- 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 +24 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- 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 +17 -3
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- 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/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/envAudit.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +26 -9
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
package/lib/audit/index.js
CHANGED
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
resolveGitUrlFromPurl,
|
|
48
48
|
resolvePurlSourceDirectory,
|
|
49
49
|
sanitizeRemoteUrlForLogs,
|
|
50
|
+
validateAndRejectGitSource,
|
|
50
51
|
} from "../inventory/source.js";
|
|
51
52
|
import { executeOsQuery } from "../managers/binary.js";
|
|
52
53
|
import { getBomWithOras } from "../managers/oci.js";
|
|
@@ -1307,6 +1308,17 @@ export function buildTargetContextFindings(target) {
|
|
|
1307
1308
|
* @returns {void}
|
|
1308
1309
|
*/
|
|
1309
1310
|
function cloneRepositoryToDir(repoUrl, cloneDir, gitRef) {
|
|
1311
|
+
// The repository URL comes from registry metadata, so it gets the same
|
|
1312
|
+
// protocol and host checks as a URL sent to the server.
|
|
1313
|
+
const validationError = validateAndRejectGitSource(repoUrl);
|
|
1314
|
+
if (validationError) {
|
|
1315
|
+
const error = new Error(
|
|
1316
|
+
`${validationError.error}: ${validationError.details}`,
|
|
1317
|
+
);
|
|
1318
|
+
error.errorType = "clone";
|
|
1319
|
+
error.retryable = false;
|
|
1320
|
+
throw error;
|
|
1321
|
+
}
|
|
1310
1322
|
const gitArgs = [
|
|
1311
1323
|
"-c",
|
|
1312
1324
|
"alias.clone=",
|
|
@@ -1316,6 +1328,8 @@ function cloneRepositoryToDir(repoUrl, cloneDir, gitRef) {
|
|
|
1316
1328
|
"safe.bareRepository=explicit",
|
|
1317
1329
|
"-c",
|
|
1318
1330
|
"core.hooksPath=/dev/null",
|
|
1331
|
+
"-c",
|
|
1332
|
+
"core.symlinks=false",
|
|
1319
1333
|
"clone",
|
|
1320
1334
|
"--template=",
|
|
1321
1335
|
"--depth",
|
package/lib/cli/bomAssembly.js
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
CDXGEN_VERSION,
|
|
26
26
|
frameworksList,
|
|
27
27
|
} from "../core/state.js";
|
|
28
|
+
import { getExecutedTools } from "../core/toolRegistry.js";
|
|
28
29
|
import {
|
|
29
30
|
isPkgTypeOnlyImport,
|
|
30
31
|
setNpmCleanedVersionProperty,
|
|
@@ -45,6 +46,7 @@ import {
|
|
|
45
46
|
setCycloneDxFormat,
|
|
46
47
|
toCycloneDxSpecVersionString,
|
|
47
48
|
} from "../inventory/bomUtils.js";
|
|
49
|
+
import { mergeDuplicateCryptoComponents } from "../inventory/certificates.js";
|
|
48
50
|
import { mergeServices, trimComponents } from "../inventory/depsUtils.js";
|
|
49
51
|
import {
|
|
50
52
|
attachIdentityTools,
|
|
@@ -59,7 +61,7 @@ import {
|
|
|
59
61
|
} from "../inventory/purl.js";
|
|
60
62
|
import { repairPurl } from "../inventory/sbomDocument.js";
|
|
61
63
|
import { getLicenses } from "../inventory/spdx.js";
|
|
62
|
-
import { getBinaryBom } from "../managers/binary.js";
|
|
64
|
+
import { getBinaryBom, getPluginToolComponents } from "../managers/binary.js";
|
|
63
65
|
import { isValidIriReference } from "../parsers/iri.js";
|
|
64
66
|
|
|
65
67
|
/**
|
|
@@ -292,10 +294,85 @@ function anchorDetectedParent(
|
|
|
292
294
|
return anchored;
|
|
293
295
|
}
|
|
294
296
|
|
|
297
|
+
/**
|
|
298
|
+
* Builds the tool components for the external helpers and build tools this
|
|
299
|
+
* run executed, from the run-scoped registry (issue #598). Bundled plugin
|
|
300
|
+
* helpers are enriched with the manifest component of the plugin package that
|
|
301
|
+
* ships them, so the plugin package's version and identity travel with the
|
|
302
|
+
* helper. Empty when the run spawned nothing external, which keeps such BOMs
|
|
303
|
+
* byte-identical to the previous behaviour.
|
|
304
|
+
*
|
|
305
|
+
* @returns {object[]} Sorted CycloneDX tool components
|
|
306
|
+
*/
|
|
307
|
+
export const buildExternalToolComponents = () => {
|
|
308
|
+
const recordedTools = getExecutedTools();
|
|
309
|
+
if (!recordedTools.length) {
|
|
310
|
+
return [];
|
|
311
|
+
}
|
|
312
|
+
const recordedNames = recordedTools.map((tool) => tool.name);
|
|
313
|
+
const pluginComponents = getPluginToolComponents(recordedNames);
|
|
314
|
+
const pluginByName = new Map(
|
|
315
|
+
pluginComponents.map((component) => [component.name, component]),
|
|
316
|
+
);
|
|
317
|
+
const components = [];
|
|
318
|
+
for (const tool of recordedTools) {
|
|
319
|
+
const pluginComponent = pluginByName.get(tool.name);
|
|
320
|
+
if (pluginComponent?.["bom-ref"]) {
|
|
321
|
+
components.push(pluginComponent);
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
const component = {
|
|
325
|
+
type: "application",
|
|
326
|
+
name: tool.name,
|
|
327
|
+
};
|
|
328
|
+
if (tool.version) {
|
|
329
|
+
component.version = tool.version;
|
|
330
|
+
}
|
|
331
|
+
components.push(component);
|
|
332
|
+
}
|
|
333
|
+
return components;
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Drops the executed tools that are already present: a tool whose bom-ref or
|
|
338
|
+
* name matches an explicitly passed context tool, or whose bom-ref an earlier
|
|
339
|
+
* executed tool already carries (several bundled helpers can share one plugin
|
|
340
|
+
* package component). The context tools themselves are never touched.
|
|
341
|
+
*
|
|
342
|
+
* @param {object[]} contextTools Tool components passed in by the caller
|
|
343
|
+
* @param {object[]} executedTools Tool components from the run's registry
|
|
344
|
+
* @returns {object[]} The executed tools to append
|
|
345
|
+
*/
|
|
346
|
+
const newExecutedTools = (contextTools, executedTools) => {
|
|
347
|
+
const seenRefs = new Set();
|
|
348
|
+
const seenNames = new Set();
|
|
349
|
+
for (const component of contextTools) {
|
|
350
|
+
if (component?.["bom-ref"]) {
|
|
351
|
+
seenRefs.add(component["bom-ref"]);
|
|
352
|
+
}
|
|
353
|
+
if (component?.name) {
|
|
354
|
+
seenNames.add(component.name);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
const unique = [];
|
|
358
|
+
for (const component of executedTools) {
|
|
359
|
+
const ref = component["bom-ref"];
|
|
360
|
+
if ((ref && seenRefs.has(ref)) || seenNames.has(component.name)) {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
if (ref) {
|
|
364
|
+
seenRefs.add(ref);
|
|
365
|
+
}
|
|
366
|
+
unique.push(component);
|
|
367
|
+
}
|
|
368
|
+
return unique;
|
|
369
|
+
};
|
|
370
|
+
|
|
295
371
|
/**
|
|
296
372
|
* Assembles the `metadata.tools` block, including the cdxgen tool entry and,
|
|
297
373
|
* for spec versions prior to 1.5, the legacy tools array. For spec version
|
|
298
|
-
* 1.6+ the author field is converted to the authors array.
|
|
374
|
+
* 1.6+ the author field is converted to the authors array. The tools this run
|
|
375
|
+
* executed follow the context tools, sorted by name, and cdxgen comes last.
|
|
299
376
|
*
|
|
300
377
|
* @param {object} options CLI options
|
|
301
378
|
* @param {object} [context={}] Additional context carrying existing components
|
|
@@ -303,6 +380,7 @@ function anchorDetectedParent(
|
|
|
303
380
|
* tools array (1.4) or a components array with tool components (1.5+)
|
|
304
381
|
*/
|
|
305
382
|
export const addToolsSection = (options, context = {}) => {
|
|
383
|
+
const externalTools = buildExternalToolComponents();
|
|
306
384
|
if (options.specVersion === 1.4) {
|
|
307
385
|
return [
|
|
308
386
|
{
|
|
@@ -310,6 +388,11 @@ export const addToolsSection = (options, context = {}) => {
|
|
|
310
388
|
name: "cdxgen",
|
|
311
389
|
version: CDXGEN_VERSION,
|
|
312
390
|
},
|
|
391
|
+
...newExecutedTools([], externalTools).map((tool) =>
|
|
392
|
+
tool.version
|
|
393
|
+
? { name: tool.name, version: tool.version }
|
|
394
|
+
: { name: tool.name },
|
|
395
|
+
),
|
|
313
396
|
];
|
|
314
397
|
}
|
|
315
398
|
let components = [];
|
|
@@ -330,6 +413,7 @@ export const addToolsSection = (options, context = {}) => {
|
|
|
330
413
|
} else if (tools && Object.keys(tools).length && tools.components) {
|
|
331
414
|
components = components.concat(tools.components);
|
|
332
415
|
}
|
|
416
|
+
components = components.concat(newExecutedTools(components, externalTools));
|
|
333
417
|
const cdxToolComponent = {
|
|
334
418
|
group: CDXGEN_TOOL_GROUP,
|
|
335
419
|
name: CDXGEN_TOOL_NAME,
|
|
@@ -457,6 +541,11 @@ export const addLifecyclesSection = (options) => {
|
|
|
457
541
|
/**
|
|
458
542
|
* Function to create metadata block
|
|
459
543
|
*
|
|
544
|
+
* @param {Object} [parentComponent] Component the BOM describes
|
|
545
|
+
* @param {Object} [options] CLI options
|
|
546
|
+
* @param {Object} [context] Generator context. `context.metadataProperties`
|
|
547
|
+
* holds facts of a manifest that has no component to carry them, such as the
|
|
548
|
+
* platform data of a composer.lock whose composer.json names no project.
|
|
460
549
|
*/
|
|
461
550
|
export function addMetadata(parentComponent = {}, options = {}, context = {}) {
|
|
462
551
|
// DO NOT fork this project to just change the vendor or author's name
|
|
@@ -518,7 +607,13 @@ export function addMetadata(parentComponent = {}, options = {}, context = {}) {
|
|
|
518
607
|
// We cannot use purl or bom-ref here since they would not match
|
|
519
608
|
// purl - could have application on one side and a different type
|
|
520
609
|
// bom-ref could have qualifiers on one side
|
|
521
|
-
|
|
610
|
+
// A purl subpath marks a separate project that declares the
|
|
611
|
+
// parent's coordinates, such as a second Maven project or a Gradle
|
|
612
|
+
// subproject with the same group, name and version.
|
|
613
|
+
const separateProject =
|
|
614
|
+
comp.purl?.includes("#") &&
|
|
615
|
+
comp.purl.split("#")[1] !== parentComponent.purl?.split("#")[1];
|
|
616
|
+
if (fullName !== parentFullName || separateProject) {
|
|
522
617
|
if (!comp["bom-ref"]) {
|
|
523
618
|
comp["bom-ref"] = `pkg:${comp.type}/${decodeURIComponent(
|
|
524
619
|
fullName,
|
|
@@ -752,7 +847,7 @@ export function addMetadata(parentComponent = {}, options = {}, context = {}) {
|
|
|
752
847
|
});
|
|
753
848
|
let appLanguage;
|
|
754
849
|
// TODO: Move these lists to a config file.
|
|
755
|
-
for (const lang
|
|
850
|
+
for (const lang of [
|
|
756
851
|
"java",
|
|
757
852
|
"node",
|
|
758
853
|
"dotnet",
|
|
@@ -828,6 +923,9 @@ export function addMetadata(parentComponent = {}, options = {}, context = {}) {
|
|
|
828
923
|
// AI provenance/oversight detection (`-t ai-provenance`) is injected into the
|
|
829
924
|
// BOM document root (bomJson.properties) after post-processing, not into
|
|
830
925
|
// metadata.properties. See ensureAiProvenanceProperties/ensureAiOversightProperties.
|
|
926
|
+
if (context?.metadataProperties?.length) {
|
|
927
|
+
mproperties.push(...context.metadataProperties);
|
|
928
|
+
}
|
|
831
929
|
if (mproperties.length) {
|
|
832
930
|
metadata.properties = mproperties;
|
|
833
931
|
}
|
|
@@ -1602,6 +1700,10 @@ export const buildBomNSData = (options, pkgInfo, ptype, context) => {
|
|
|
1602
1700
|
if (context?.formulationList?.length) {
|
|
1603
1701
|
bomNSData.formulationList = context.formulationList;
|
|
1604
1702
|
}
|
|
1703
|
+
// createMultiXBom rebuilds the metadata block, so these are handed on.
|
|
1704
|
+
if (context?.metadataProperties?.length) {
|
|
1705
|
+
bomNSData.metadataProperties = context.metadataProperties;
|
|
1706
|
+
}
|
|
1605
1707
|
// Carry language-specific provenance citations (e.g. PEP 770 embedded
|
|
1606
1708
|
// SBOMs) so postProcess can attach them in the single root-level citations
|
|
1607
1709
|
// section it builds.
|
|
@@ -1933,16 +2035,28 @@ export function emitAiInventorySummary(aiInventory, discoveryPath) {
|
|
|
1933
2035
|
* @param {Array} components Components
|
|
1934
2036
|
* @param {Object} parentComponent Parent component
|
|
1935
2037
|
* @param {Array} dependencies Dependencies
|
|
2038
|
+
* @param {Array} [metadataProperties] Properties for the metadata block, from
|
|
2039
|
+
* generators whose manifest has no component to carry them
|
|
1936
2040
|
*
|
|
1937
2041
|
* @returns {Object} Object including BOM Json
|
|
1938
2042
|
*/
|
|
1939
|
-
export function dedupeBom(
|
|
2043
|
+
export function dedupeBom(
|
|
2044
|
+
options,
|
|
2045
|
+
components,
|
|
2046
|
+
parentComponent,
|
|
2047
|
+
dependencies,
|
|
2048
|
+
metadataProperties = [],
|
|
2049
|
+
) {
|
|
1940
2050
|
if (!components) {
|
|
1941
2051
|
return {};
|
|
1942
2052
|
}
|
|
1943
2053
|
if (!dependencies) {
|
|
1944
2054
|
dependencies = [];
|
|
1945
2055
|
}
|
|
2056
|
+
// Certificate components from different producers (trustinspector rootfs,
|
|
2057
|
+
// the source-directory scan, observed chains) share a bom-ref; merge their
|
|
2058
|
+
// occurrences and properties before the generic trim.
|
|
2059
|
+
components = mergeDuplicateCryptoComponents(components);
|
|
1946
2060
|
components = trimComponents(components);
|
|
1947
2061
|
// Let's apply some common tweaks
|
|
1948
2062
|
// Convert evidence.identity section to an object for 1.5
|
|
@@ -1971,7 +2085,7 @@ export function dedupeBom(options, components, parentComponent, dependencies) {
|
|
|
1971
2085
|
),
|
|
1972
2086
|
serialNumber: serialNum,
|
|
1973
2087
|
version: 1,
|
|
1974
|
-
metadata: addMetadata(parentComponent, options, {}),
|
|
2088
|
+
metadata: addMetadata(parentComponent, options, { metadataProperties }),
|
|
1975
2089
|
components,
|
|
1976
2090
|
services: options.services || [],
|
|
1977
2091
|
dependencies,
|
package/lib/cli/cliOptions.js
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
METADATA_PROPERTY_CONFIG_KEYS,
|
|
20
20
|
parseMetadataProperties,
|
|
21
21
|
} from "../core/metadataProperties.js";
|
|
22
|
+
import { toCamel } from "../core/paths.js";
|
|
22
23
|
import {
|
|
23
24
|
DEFAULT_CDX_SPEC_VERSION,
|
|
24
25
|
normalizeCycloneDxComponentTypeFilter,
|
|
@@ -124,6 +125,106 @@ export function isUserProvided(value, yaDefault) {
|
|
|
124
125
|
return value !== undefined && value !== yaDefault;
|
|
125
126
|
}
|
|
126
127
|
|
|
128
|
+
/**
|
|
129
|
+
* The value the operator gave an option on the command line or through its
|
|
130
|
+
* CDXGEN_* environment variable. yargs also fills options in from defaults
|
|
131
|
+
* and from a config file, which cannot be told apart in its output.
|
|
132
|
+
*
|
|
133
|
+
* @param {string} option kebab-case option name
|
|
134
|
+
* @param {object} [context]
|
|
135
|
+
* @param {string[]} [context.argv] Raw command-line arguments
|
|
136
|
+
* @param {object} [context.env] Environment variables
|
|
137
|
+
* @param {boolean} [context.boolean] Read the option as a boolean flag
|
|
138
|
+
* @returns {string|boolean|undefined} The operator's value, or undefined
|
|
139
|
+
*/
|
|
140
|
+
export function operatorOptionChoice(
|
|
141
|
+
option,
|
|
142
|
+
{ argv = process.argv.slice(2), env = process.env, boolean = false } = {},
|
|
143
|
+
) {
|
|
144
|
+
const spellings = [...new Set([option, toCamel(option)])];
|
|
145
|
+
const toBoolean = (value) =>
|
|
146
|
+
["true", "1"].includes(`${value}`.trim().toLowerCase());
|
|
147
|
+
let choice;
|
|
148
|
+
for (let i = 0; i < argv.length; i++) {
|
|
149
|
+
const arg = `${argv[i]}`;
|
|
150
|
+
if (arg === "--") {
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
for (const name of spellings) {
|
|
154
|
+
if (boolean && arg === `--no-${name}`) {
|
|
155
|
+
choice = false;
|
|
156
|
+
} else if (arg === `--${name}`) {
|
|
157
|
+
const next = argv[i + 1] === undefined ? "" : `${argv[i + 1]}`;
|
|
158
|
+
if (!boolean) {
|
|
159
|
+
choice = next;
|
|
160
|
+
i++;
|
|
161
|
+
} else if (["true", "false"].includes(next.toLowerCase())) {
|
|
162
|
+
choice = toBoolean(next);
|
|
163
|
+
i++;
|
|
164
|
+
} else {
|
|
165
|
+
choice = true;
|
|
166
|
+
}
|
|
167
|
+
} else if (arg.startsWith(`--${name}=`)) {
|
|
168
|
+
const value = arg.slice(name.length + 3);
|
|
169
|
+
choice = boolean ? toBoolean(value) : value;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (choice !== undefined) {
|
|
174
|
+
return choice;
|
|
175
|
+
}
|
|
176
|
+
const envValue =
|
|
177
|
+
env[`CDXGEN_${option.toUpperCase().replaceAll("-", "_")}`] ?? "";
|
|
178
|
+
if (`${envValue}`.trim() === "") {
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
return boolean ? toBoolean(envValue) : `${envValue}`;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Make the operator's choice about running the scanned project's own code
|
|
186
|
+
* final. A config file is read from the working directory, which is usually
|
|
187
|
+
* the scanned project, so it carries that project's trust. Neither the config
|
|
188
|
+
* file nor a profile or lifecycle may turn installs on when the operator
|
|
189
|
+
* disabled them, and secure mode keeps installs off unless the operator
|
|
190
|
+
* passes --install-deps. Introspection keeps the project's build tools
|
|
191
|
+
* running with installs off, which is likewise the operator's decision, so
|
|
192
|
+
* introspection asked for only by the config file does not do that.
|
|
193
|
+
*
|
|
194
|
+
* **Mutates `options` in place.**
|
|
195
|
+
*
|
|
196
|
+
* @param {object} options The options object, after applyAdvancedOptions
|
|
197
|
+
* @param {object} [context]
|
|
198
|
+
* @param {object} [context.projectConfig] Sanitized config file contents
|
|
199
|
+
* @param {boolean} [context.isSecureMode] Whether cdxgen runs in secure mode
|
|
200
|
+
* @param {string[]} [context.argv] Raw command-line arguments
|
|
201
|
+
* @param {object} [context.env] Environment variables
|
|
202
|
+
* @returns {void}
|
|
203
|
+
*/
|
|
204
|
+
export function applyOperatorToolingChoice(options, context = {}) {
|
|
205
|
+
const { projectConfig, argv, env } = context;
|
|
206
|
+
const secureMode = context.isSecureMode ?? isSecureMode;
|
|
207
|
+
const installChoice = operatorOptionChoice("install-deps", {
|
|
208
|
+
argv,
|
|
209
|
+
env,
|
|
210
|
+
boolean: true,
|
|
211
|
+
});
|
|
212
|
+
if (installChoice === false || (secureMode && installChoice !== true)) {
|
|
213
|
+
options.installDeps = false;
|
|
214
|
+
}
|
|
215
|
+
const configAsksIntrospect =
|
|
216
|
+
["true", "1"].includes(`${projectConfig?.introspect}`.toLowerCase()) ||
|
|
217
|
+
projectConfig?.profile === "introspect";
|
|
218
|
+
if (
|
|
219
|
+
options.introspect === true &&
|
|
220
|
+
configAsksIntrospect &&
|
|
221
|
+
operatorOptionChoice("introspect", { argv, env, boolean: true }) !== true &&
|
|
222
|
+
operatorOptionChoice("profile", { argv, env }) !== "introspect"
|
|
223
|
+
) {
|
|
224
|
+
options.introspectFromConfigFile = true;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
127
228
|
/**
|
|
128
229
|
* Combine the custom metadata properties of every source (discussion 4391):
|
|
129
230
|
* the `--metadata-property` flag, the CDXGEN_METADATA_PROPERTY and
|
|
@@ -588,7 +689,9 @@ export function applyAdvancedOptions(options, context = {}) {
|
|
|
588
689
|
options.deep = true;
|
|
589
690
|
options.evidence = false;
|
|
590
691
|
options.includeCrypto = false;
|
|
591
|
-
|
|
692
|
+
// A profile may skip installs but never turn them back on once they
|
|
693
|
+
// were disabled, which would run the scanned project's code.
|
|
694
|
+
options.installDeps = !secureMode && options.installDeps !== false;
|
|
592
695
|
break;
|
|
593
696
|
case "deep-learning":
|
|
594
697
|
case "ml-deep":
|
|
@@ -596,7 +699,7 @@ export function applyAdvancedOptions(options, context = {}) {
|
|
|
596
699
|
options.deep = true;
|
|
597
700
|
options.evidence = true;
|
|
598
701
|
options.includeCrypto = true;
|
|
599
|
-
options.installDeps = !secureMode;
|
|
702
|
+
options.installDeps = !secureMode && options.installDeps !== false;
|
|
600
703
|
options.bomAudit = true;
|
|
601
704
|
break;
|
|
602
705
|
default:
|
|
@@ -619,7 +722,11 @@ export function applyAdvancedOptions(options, context = {}) {
|
|
|
619
722
|
"PREVIEW: post-build lifecycle SBOM generation is supported only for limited project types.",
|
|
620
723
|
});
|
|
621
724
|
}
|
|
622
|
-
|
|
725
|
+
// The project is already built, so installs are on only where they
|
|
726
|
+
// would have been anyway: a disabled install stays disabled.
|
|
727
|
+
if (options.installDeps !== false) {
|
|
728
|
+
options.installDeps = true;
|
|
729
|
+
}
|
|
623
730
|
break;
|
|
624
731
|
default:
|
|
625
732
|
break;
|