@cdxgen/cdxgen 13.0.1 → 13.2.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 +30 -16
- package/bin/audit.js +6 -0
- package/bin/cdxgen.js +141 -7
- package/bin/evinse.js +3 -1
- package/data/component-tags.json +8 -1
- package/data/crypto-oid.json +88 -12
- package/data/frameworks-list.json +86 -1
- package/data/remediations.json +1167 -0
- package/data/rules/ai-bom.yaml +78 -0
- package/data/rules/asar-archives.yaml +1 -1
- package/data/rules/build-fidelity.yaml +782 -0
- package/data/rules/cargo-rust.yaml +132 -0
- package/data/rules/mcp-servers.yaml +122 -0
- package/data/rules/package-integrity.yaml +13 -13
- package/lib/audit/index.js +48 -4
- package/lib/audit/scoring.js +2 -8
- package/lib/audit/targets.js +6 -1
- package/lib/cli/bomAssembly.js +32 -1
- package/lib/cli/cliOptions.js +94 -7
- package/lib/cli/index.js +268 -49
- package/lib/cli/jsBom.js +91 -5
- package/lib/cli/jvmBom.js +1515 -1314
- package/lib/cli/managedBom.js +249 -28
- package/lib/cli/nativeBom.js +986 -10
- package/lib/core/activity.js +120 -2
- package/lib/core/buildLedger.js +799 -0
- package/lib/core/deferredExit.js +141 -0
- package/lib/core/env.js +108 -2
- package/lib/core/fs.js +60 -0
- package/lib/core/logger.js +12 -99
- package/lib/core/severity.js +16 -0
- package/lib/core/syncFileWriter.js +106 -0
- package/lib/core/userAgent.js +151 -0
- package/lib/ecosystems/cargoCache.js +364 -0
- package/lib/ecosystems/caxa.js +13 -5
- package/lib/ecosystems/cppEvidence.js +40 -2
- package/lib/ecosystems/ecosystems.js +250 -91
- package/lib/ecosystems/golem.js +11 -1
- package/lib/ecosystems/gradleutils.js +498 -17
- package/lib/ecosystems/kosi.js +1256 -0
- package/lib/ecosystems/parsers-crystal.js +179 -0
- package/lib/ecosystems/parsers-dotnet.js +69 -39
- package/lib/ecosystems/parsers-elm.js +816 -0
- package/lib/ecosystems/parsers-gleam.js +1 -1
- package/lib/ecosystems/parsers-js.js +26 -0
- package/lib/ecosystems/parsers-julia.js +268 -0
- package/lib/ecosystems/parsers-jvm.js +9 -0
- package/lib/ecosystems/parsers-lua.js +218 -0
- package/lib/ecosystems/parsers-misc.js +188 -2
- package/lib/ecosystems/parsers-nim.js +221 -0
- package/lib/ecosystems/parsers-opam.js +180 -0
- package/lib/ecosystems/parsers-perl.js +277 -0
- package/lib/ecosystems/parsers-python.js +172 -36
- package/lib/ecosystems/parsers-r.js +148 -0
- package/lib/ecosystems/parsers-rebar.js +411 -0
- package/lib/ecosystems/parsers-rust.js +944 -19
- package/lib/ecosystems/parsers-spack.js +204 -0
- package/lib/ecosystems/parsers-stack.js +264 -0
- package/lib/ecosystems/parsers-terraform.js +194 -0
- package/lib/ecosystems/pypiClassifiers.js +326 -0
- package/lib/ecosystems/pythonutils.js +49 -1
- package/lib/ecosystems/rubyutils.js +13 -0
- package/lib/ecosystems/rusi.js +126 -6
- package/lib/evinser/evinser.js +141 -13
- package/lib/helpers/agenticToolutils.js +925 -0
- package/lib/helpers/remote/dependency-track.js +81 -14
- package/lib/inventory/agentFormulationParser.js +57 -4
- package/lib/inventory/aiCollector.js +504 -10
- package/lib/inventory/aiInventory.js +12 -0
- package/lib/inventory/analyzer.js +488 -30
- package/lib/inventory/astWorker.js +6 -0
- package/lib/inventory/auditCategories.js +17 -0
- package/lib/inventory/cbomutils.js +30 -0
- package/lib/inventory/cdxrs.js +7 -2
- package/lib/inventory/communityAiConfigParser.js +215 -2
- package/lib/inventory/depsUtils.js +72 -0
- package/lib/inventory/dosai.js +508 -22
- package/lib/inventory/envcontext.js +215 -24
- package/lib/inventory/evidenceUtils.js +13 -0
- package/lib/inventory/fetchBatch.js +131 -2
- package/lib/inventory/fetchRate.js +74 -11
- package/lib/inventory/forgeEnricher.js +3 -2
- package/lib/inventory/jvmToolEnv.js +594 -0
- package/lib/inventory/mcpConfigParser.js +166 -2
- package/lib/inventory/mcpDiscovery.js +11 -0
- package/lib/inventory/mcpServerManifest.js +389 -0
- package/lib/inventory/mcpbBundle.js +419 -0
- package/lib/inventory/osinfo.js +1 -0
- package/lib/inventory/plugins.js +3 -0
- package/lib/inventory/protobom.js +54 -88
- package/lib/inventory/protobomLoader.js +4 -0
- package/lib/inventory/rustFormulationParser.js +1 -1
- package/lib/inventory/source.js +10 -4
- package/lib/inventory/stylePackageRefs.js +41 -0
- package/lib/inventory/svelteUtils.js +524 -0
- package/lib/inventory/toolRequirements.js +903 -0
- package/lib/managers/binary.js +24 -0
- package/lib/managers/docker.js +26 -5
- package/lib/parsers/huggingfaceUtils.js +15 -7
- package/lib/parsers/onnx.js +294 -0
- package/lib/parsers/safetensors.js +114 -0
- package/lib/server/server.js +1 -1
- package/lib/stages/postgen/annotationBuilder.js +97 -0
- package/lib/stages/postgen/auditBom.js +76 -79
- package/lib/stages/postgen/introspection/annotate.js +320 -0
- package/lib/stages/postgen/introspection/commandFacts.js +293 -0
- package/lib/stages/postgen/introspection/emit.js +192 -0
- package/lib/stages/postgen/introspection/formulationEvidence.js +427 -0
- package/lib/stages/postgen/introspection/markers.js +250 -0
- package/lib/stages/postgen/introspection/reflect.js +1214 -0
- package/lib/stages/postgen/introspection/report.js +1208 -0
- package/lib/stages/postgen/introspection/score.js +1067 -0
- package/lib/stages/postgen/introspection/shapeCommand.js +304 -0
- package/lib/stages/postgen/parentEdge.js +156 -0
- package/lib/stages/postgen/postgen.js +284 -3
- package/lib/stages/postgen/ruleEngine.js +17 -0
- package/lib/stages/pregen/envAudit.js +42 -2
- package/lib/stages/pregen/pregen.js +1171 -6
- package/lib/third-party/arborist/snapshots/calc-dep-flags.test.cjs +462 -0
- package/lib/validator/bomValidator.js +11 -2
- package/package.json +26 -26
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/audit/scoring.d.ts +2 -8
- package/types/lib/audit/scoring.d.ts.map +1 -1
- package/types/lib/audit/targets.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +2 -1
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts +10 -2
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts +23 -0
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts +33 -0
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts +88 -8
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/activity.d.ts.map +1 -1
- package/types/lib/core/buildLedger.d.ts +272 -0
- package/types/lib/core/buildLedger.d.ts.map +1 -0
- package/types/lib/core/deferredExit.d.ts +84 -0
- package/types/lib/core/deferredExit.d.ts.map +1 -0
- package/types/lib/core/env.d.ts +43 -1
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts +21 -0
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/logger.d.ts +2 -11
- package/types/lib/core/logger.d.ts.map +1 -1
- package/types/lib/core/severity.d.ts +11 -0
- package/types/lib/core/severity.d.ts.map +1 -0
- package/types/lib/core/syncFileWriter.d.ts +33 -0
- package/types/lib/core/syncFileWriter.d.ts.map +1 -0
- package/types/lib/core/userAgent.d.ts +56 -0
- package/types/lib/core/userAgent.d.ts.map +1 -0
- package/types/lib/ecosystems/cargoCache.d.ts +75 -0
- package/types/lib/ecosystems/cargoCache.d.ts.map +1 -0
- package/types/lib/ecosystems/caxa.d.ts.map +1 -1
- package/types/lib/ecosystems/cppEvidence.d.ts +1 -1
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts +15 -1
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +53 -0
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/kosi.d.ts +73 -0
- package/types/lib/ecosystems/kosi.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-crystal.d.ts +27 -0
- package/types/lib/ecosystems/parsers-crystal.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-dotnet.d.ts +19 -0
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-elm.d.ts +79 -0
- package/types/lib/ecosystems/parsers-elm.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-julia.d.ts +57 -0
- package/types/lib/ecosystems/parsers-julia.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-lua.d.ts +50 -0
- package/types/lib/ecosystems/parsers-lua.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-misc.d.ts +23 -0
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-nim.d.ts +43 -0
- package/types/lib/ecosystems/parsers-nim.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-opam.d.ts +31 -0
- package/types/lib/ecosystems/parsers-opam.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-perl.d.ts +36 -0
- package/types/lib/ecosystems/parsers-perl.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-r.d.ts +35 -0
- package/types/lib/ecosystems/parsers-r.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-rebar.d.ts +42 -0
- package/types/lib/ecosystems/parsers-rebar.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-rust.d.ts +199 -0
- package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-spack.d.ts +33 -0
- package/types/lib/ecosystems/parsers-spack.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-stack.d.ts +35 -0
- package/types/lib/ecosystems/parsers-stack.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-terraform.d.ts +34 -0
- package/types/lib/ecosystems/parsers-terraform.d.ts.map +1 -0
- package/types/lib/ecosystems/pypiClassifiers.d.ts +80 -0
- package/types/lib/ecosystems/pypiClassifiers.d.ts.map +1 -0
- package/types/lib/ecosystems/pythonutils.d.ts +21 -1
- package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/evinser/evinser.d.ts +34 -1
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/helpers/agenticToolutils.d.ts +87 -0
- package/types/lib/helpers/agenticToolutils.d.ts.map +1 -0
- package/types/lib/helpers/remote/dependency-track.d.ts +45 -4
- package/types/lib/helpers/remote/dependency-track.d.ts.map +1 -1
- package/types/lib/inventory/agentFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/aiInventory.d.ts.map +1 -1
- package/types/lib/inventory/analyzer.d.ts.map +1 -1
- package/types/lib/inventory/auditCategories.d.ts +12 -0
- package/types/lib/inventory/auditCategories.d.ts.map +1 -1
- package/types/lib/inventory/cbomutils.d.ts.map +1 -1
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/depsUtils.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +43 -0
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/fetchBatch.d.ts +43 -0
- package/types/lib/inventory/fetchBatch.d.ts.map +1 -1
- package/types/lib/inventory/fetchRate.d.ts +9 -6
- package/types/lib/inventory/fetchRate.d.ts.map +1 -1
- package/types/lib/inventory/forgeEnricher.d.ts.map +1 -1
- package/types/lib/inventory/jvmToolEnv.d.ts +190 -0
- package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -0
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/mcpDiscovery.d.ts.map +1 -1
- package/types/lib/inventory/mcpServerManifest.d.ts +19 -0
- package/types/lib/inventory/mcpServerManifest.d.ts.map +1 -0
- package/types/lib/inventory/mcpbBundle.d.ts +19 -0
- package/types/lib/inventory/mcpbBundle.d.ts.map +1 -0
- package/types/lib/inventory/osinfo.d.ts.map +1 -1
- package/types/lib/inventory/plugins.d.ts.map +1 -1
- package/types/lib/inventory/protobom.d.ts +18 -13
- package/types/lib/inventory/protobom.d.ts.map +1 -1
- package/types/lib/inventory/protobomLoader.d.ts.map +1 -1
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/stylePackageRefs.d.ts +17 -0
- package/types/lib/inventory/stylePackageRefs.d.ts.map +1 -0
- package/types/lib/inventory/svelteUtils.d.ts +124 -0
- package/types/lib/inventory/svelteUtils.d.ts.map +1 -0
- package/types/lib/inventory/toolRequirements.d.ts +216 -0
- package/types/lib/inventory/toolRequirements.d.ts.map +1 -0
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/parsers/huggingfaceUtils.d.ts +8 -1
- package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
- package/types/lib/parsers/onnx.d.ts +28 -0
- package/types/lib/parsers/onnx.d.ts.map +1 -0
- package/types/lib/parsers/safetensors.d.ts +22 -0
- package/types/lib/parsers/safetensors.d.ts.map +1 -0
- package/types/lib/stages/postgen/annotationBuilder.d.ts +53 -0
- package/types/lib/stages/postgen/annotationBuilder.d.ts.map +1 -0
- package/types/lib/stages/postgen/auditBom.d.ts.map +1 -1
- package/types/lib/stages/postgen/introspection/annotate.d.ts +81 -0
- package/types/lib/stages/postgen/introspection/annotate.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/commandFacts.d.ts +32 -0
- package/types/lib/stages/postgen/introspection/commandFacts.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/emit.d.ts +71 -0
- package/types/lib/stages/postgen/introspection/emit.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/formulationEvidence.d.ts +154 -0
- package/types/lib/stages/postgen/introspection/formulationEvidence.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/markers.d.ts +58 -0
- package/types/lib/stages/postgen/introspection/markers.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/reflect.d.ts +77 -0
- package/types/lib/stages/postgen/introspection/reflect.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/report.d.ts +85 -0
- package/types/lib/stages/postgen/introspection/report.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/score.d.ts +149 -0
- package/types/lib/stages/postgen/introspection/score.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/shapeCommand.d.ts +79 -0
- package/types/lib/stages/postgen/introspection/shapeCommand.d.ts.map +1 -0
- package/types/lib/stages/postgen/parentEdge.d.ts +35 -0
- package/types/lib/stages/postgen/parentEdge.d.ts.map +1 -0
- package/types/lib/stages/postgen/postgen.d.ts +35 -2
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +131 -0
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
package/lib/cli/managedBom.js
CHANGED
|
@@ -6,6 +6,8 @@ import process from "node:process";
|
|
|
6
6
|
import { build } from "@cdxgen/cdx-purl";
|
|
7
7
|
|
|
8
8
|
import { DEBUG_MODE, readEnvironmentVariable } from "../core/activity.js";
|
|
9
|
+
import { recordDegradation } from "../core/buildLedger.js";
|
|
10
|
+
import { deferFailOnError } from "../core/deferredExit.js";
|
|
9
11
|
import {
|
|
10
12
|
DOTNET_CMD,
|
|
11
13
|
hasAnyProjectType,
|
|
@@ -48,6 +50,7 @@ import {
|
|
|
48
50
|
parseGitHubWorkflowData,
|
|
49
51
|
parseHelmYamlData,
|
|
50
52
|
} from "../ecosystems/parsers-misc.js";
|
|
53
|
+
import { parseCpanSnapshot } from "../ecosystems/parsers-perl.js";
|
|
51
54
|
import {
|
|
52
55
|
generatePixiLockFile,
|
|
53
56
|
parseMojoProject,
|
|
@@ -59,6 +62,8 @@ import {
|
|
|
59
62
|
parseReqFile,
|
|
60
63
|
parseSetupPyFile,
|
|
61
64
|
} from "../ecosystems/parsers-python.js";
|
|
65
|
+
import { parseRenvLock } from "../ecosystems/parsers-r.js";
|
|
66
|
+
import { parseTerraformLockFile } from "../ecosystems/parsers-terraform.js";
|
|
62
67
|
import { collectEmbeddedSboms } from "../ecosystems/pep770.js";
|
|
63
68
|
import { isPyLockFile } from "../ecosystems/pylockutils.js";
|
|
64
69
|
import {
|
|
@@ -94,6 +99,7 @@ import {
|
|
|
94
99
|
trimComponents,
|
|
95
100
|
} from "../inventory/depsUtils.js";
|
|
96
101
|
import {
|
|
102
|
+
collectDosaiServiceComponents,
|
|
97
103
|
collectDosaiServicesFromMethods,
|
|
98
104
|
createDosaiMethodsSlice,
|
|
99
105
|
isDosaiDotnetLanguage,
|
|
@@ -102,6 +108,7 @@ import {
|
|
|
102
108
|
} from "../inventory/dosai.js";
|
|
103
109
|
import { addEvidenceForDotnet } from "../inventory/evidenceUtils.js";
|
|
104
110
|
import { nugetPurl, pypiBomRef } from "../inventory/purl.js";
|
|
111
|
+
import { classifyProbeResult } from "../inventory/toolRequirements.js";
|
|
105
112
|
import { getPluginToolComponents } from "../managers/binary.js";
|
|
106
113
|
import { getTreeWithPlugin } from "../managers/piptree.js";
|
|
107
114
|
import {
|
|
@@ -408,7 +415,11 @@ export async function createPythonBom(path, options) {
|
|
|
408
415
|
}
|
|
409
416
|
let retMap = await parsePyLockData(lockData, f);
|
|
410
417
|
if (retMap?.workspaceWarningShown) {
|
|
411
|
-
options
|
|
418
|
+
deferFailOnError(options, {
|
|
419
|
+
ecosystem: "python",
|
|
420
|
+
tool: "python",
|
|
421
|
+
detail: "the python lock file could not be parsed",
|
|
422
|
+
});
|
|
412
423
|
}
|
|
413
424
|
if (retMap?.pyLockProperties?.length) {
|
|
414
425
|
parentComponent.properties = parentComponent.properties || [];
|
|
@@ -458,15 +469,6 @@ export async function createPythonBom(path, options) {
|
|
|
458
469
|
retMap.dependenciesList,
|
|
459
470
|
parentComponent,
|
|
460
471
|
);
|
|
461
|
-
if (retMap.rootList) {
|
|
462
|
-
const parentDependsOn = new Set();
|
|
463
|
-
for (const p of retMap.rootList)
|
|
464
|
-
parentDependsOn.add(pypiBomRef(p.name, p.version));
|
|
465
|
-
dependencies.splice(0, 0, {
|
|
466
|
-
ref: parentComponent["bom-ref"],
|
|
467
|
-
dependsOn: [...parentDependsOn].sort(),
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
472
|
} else {
|
|
471
473
|
let exportedReqs = "";
|
|
472
474
|
if (f.endsWith("poetry.lock")) {
|
|
@@ -493,6 +495,11 @@ export async function createPythonBom(path, options) {
|
|
|
493
495
|
exportedReqs = expCmd.stdout.toString();
|
|
494
496
|
}
|
|
495
497
|
if (exportedReqs) {
|
|
498
|
+
// The export contains the resolved closure, not just the first
|
|
499
|
+
// level, so it contributes components only. The root edge comes
|
|
500
|
+
// from parsePyLockData (seeded from the manifest); for locks
|
|
501
|
+
// without a neighbouring pyproject.toml the generic postgen
|
|
502
|
+
// parent-edge repair keeps the tree reachable.
|
|
496
503
|
const tmpReqFile = join(
|
|
497
504
|
tempDir,
|
|
498
505
|
`exported-${basename(basePath)}-reqs.txt`,
|
|
@@ -501,13 +508,6 @@ export async function createPythonBom(path, options) {
|
|
|
501
508
|
const dlist = await parseReqFile(tmpReqFile, false);
|
|
502
509
|
if (dlist?.length) {
|
|
503
510
|
pkgList = pkgList.concat(dlist);
|
|
504
|
-
const parentDependsOn = new Set();
|
|
505
|
-
for (const p of dlist)
|
|
506
|
-
parentDependsOn.add(pypiBomRef(p.name, p.version));
|
|
507
|
-
dependencies.splice(0, 0, {
|
|
508
|
-
ref: parentComponent["bom-ref"],
|
|
509
|
-
dependsOn: [...parentDependsOn].sort(),
|
|
510
|
-
});
|
|
511
511
|
}
|
|
512
512
|
}
|
|
513
513
|
}
|
|
@@ -577,14 +577,30 @@ export async function createPythonBom(path, options) {
|
|
|
577
577
|
safeSpawnSync("pipenv", ["install"], { cwd: path, shell: isWin });
|
|
578
578
|
const piplockFile = join(path, "Pipfile.lock");
|
|
579
579
|
if (safeExistsSync(piplockFile)) {
|
|
580
|
-
|
|
581
|
-
|
|
580
|
+
let dlist;
|
|
581
|
+
try {
|
|
582
|
+
const lockData = JSON.parse(readFileSync(piplockFile));
|
|
583
|
+
dlist = await parsePiplockData(lockData);
|
|
584
|
+
} catch (err) {
|
|
585
|
+
recordDegradation("python.lockfile-unparseable.pipenv", {
|
|
586
|
+
ecosystem: "python",
|
|
587
|
+
impact: "transitive-deps",
|
|
588
|
+
path: piplockFile,
|
|
589
|
+
detail:
|
|
590
|
+
"The Pipfile.lock could not be parsed, so no locked versions were captured from it.",
|
|
591
|
+
});
|
|
592
|
+
console.log(`Error while parsing the lock file ${piplockFile}.`, err);
|
|
593
|
+
}
|
|
582
594
|
if (dlist?.length) {
|
|
583
595
|
pkgList = pkgList.concat(dlist);
|
|
584
596
|
}
|
|
585
597
|
} else {
|
|
586
598
|
console.error("Pipfile.lock not found at", path);
|
|
587
|
-
options
|
|
599
|
+
deferFailOnError(options, {
|
|
600
|
+
ecosystem: "python",
|
|
601
|
+
tool: "pipenv",
|
|
602
|
+
detail: "Pipfile.lock was not found",
|
|
603
|
+
});
|
|
588
604
|
}
|
|
589
605
|
} else if (reqDirFiles?.length) {
|
|
590
606
|
for (const j in reqDirFiles) {
|
|
@@ -1087,13 +1103,33 @@ export function createPHPBom(path, options) {
|
|
|
1087
1103
|
shell: isWin,
|
|
1088
1104
|
});
|
|
1089
1105
|
if (versionResult.status !== 0 || versionResult.error) {
|
|
1106
|
+
// A composer the runtime or a policy denied is not an unavailable
|
|
1107
|
+
// composer; the version probes report that as degraded evidence.
|
|
1108
|
+
if (classifyProbeResult(versionResult) === "missing") {
|
|
1109
|
+
recordDegradation("php.composer.missing", {
|
|
1110
|
+
ecosystem: "php",
|
|
1111
|
+
tool: "composer",
|
|
1112
|
+
impact: "components",
|
|
1113
|
+
command: "composer --version",
|
|
1114
|
+
exitCode:
|
|
1115
|
+
typeof versionResult.status === "number"
|
|
1116
|
+
? versionResult.status
|
|
1117
|
+
: undefined,
|
|
1118
|
+
detail:
|
|
1119
|
+
"The composer executable could not be run, so the composer.lock generation could not be attempted.",
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1090
1122
|
console.error(
|
|
1091
1123
|
"No composer version found. Check if composer is installed and available in PATH.",
|
|
1092
1124
|
);
|
|
1093
1125
|
if (DEBUG_MODE) {
|
|
1094
1126
|
console.log(versionResult.error, versionResult.stderr);
|
|
1095
1127
|
}
|
|
1096
|
-
options
|
|
1128
|
+
deferFailOnError(options, {
|
|
1129
|
+
ecosystem: "php",
|
|
1130
|
+
tool: "composer",
|
|
1131
|
+
detail: "the composer version command failed",
|
|
1132
|
+
});
|
|
1097
1133
|
}
|
|
1098
1134
|
let composerVersion;
|
|
1099
1135
|
if (DEBUG_MODE) {
|
|
@@ -1129,7 +1165,11 @@ export function createPHPBom(path, options) {
|
|
|
1129
1165
|
console.log(result.stderr);
|
|
1130
1166
|
}
|
|
1131
1167
|
console.log(result.error);
|
|
1132
|
-
options
|
|
1168
|
+
deferFailOnError(options, {
|
|
1169
|
+
ecosystem: "php",
|
|
1170
|
+
tool: "composer",
|
|
1171
|
+
detail: "the composer install command failed",
|
|
1172
|
+
});
|
|
1133
1173
|
}
|
|
1134
1174
|
}
|
|
1135
1175
|
}
|
|
@@ -1206,6 +1246,15 @@ export function createPHPBom(path, options) {
|
|
|
1206
1246
|
parentComponent,
|
|
1207
1247
|
});
|
|
1208
1248
|
}
|
|
1249
|
+
if (composerJsonMode && !composerLockMode) {
|
|
1250
|
+
recordDegradation("php.no-lockfile", {
|
|
1251
|
+
ecosystem: "php",
|
|
1252
|
+
tool: "composer",
|
|
1253
|
+
impact: "components",
|
|
1254
|
+
detail:
|
|
1255
|
+
"No composer.lock was found or generated, and the lock file is the source the Composer parser reads.",
|
|
1256
|
+
});
|
|
1257
|
+
}
|
|
1209
1258
|
return {};
|
|
1210
1259
|
}
|
|
1211
1260
|
|
|
@@ -1319,7 +1368,11 @@ export async function createRubyBom(path, options) {
|
|
|
1319
1368
|
"Bundle install has failed. Check if bundle is installed and available in PATH.",
|
|
1320
1369
|
);
|
|
1321
1370
|
console.log(result.error, result.stderr);
|
|
1322
|
-
options
|
|
1371
|
+
deferFailOnError(options, {
|
|
1372
|
+
ecosystem: "ruby",
|
|
1373
|
+
tool: "bundler",
|
|
1374
|
+
detail: "the bundler command failed",
|
|
1375
|
+
});
|
|
1323
1376
|
}
|
|
1324
1377
|
}
|
|
1325
1378
|
}
|
|
@@ -1361,7 +1414,11 @@ export async function createRubyBom(path, options) {
|
|
|
1361
1414
|
console.log(
|
|
1362
1415
|
"SBOM generation using only gemspec files is imprecise and results in an inaccurate dependency tree.",
|
|
1363
1416
|
);
|
|
1364
|
-
options
|
|
1417
|
+
deferFailOnError(options, {
|
|
1418
|
+
ecosystem: "ruby",
|
|
1419
|
+
tool: "bundler",
|
|
1420
|
+
detail: "only gemspec files were available to parse",
|
|
1421
|
+
});
|
|
1365
1422
|
}
|
|
1366
1423
|
for (const f of gemspecFiles) {
|
|
1367
1424
|
const gemspecData = readFileSync(f, { encoding: "utf-8" });
|
|
@@ -1634,7 +1691,11 @@ export async function createCsharpBom(path, options) {
|
|
|
1634
1691
|
"TIP: msbuild is not available for Linux. Try using a Windows build agent to generate an SBOM for this project.",
|
|
1635
1692
|
);
|
|
1636
1693
|
}
|
|
1637
|
-
options
|
|
1694
|
+
deferFailOnError(options, {
|
|
1695
|
+
ecosystem: "csharp",
|
|
1696
|
+
tool: "dotnet",
|
|
1697
|
+
detail: "the dotnet command failed",
|
|
1698
|
+
});
|
|
1638
1699
|
}
|
|
1639
1700
|
if (result?.stderr?.includes("To install missing framework")) {
|
|
1640
1701
|
console.log(
|
|
@@ -1683,7 +1744,11 @@ export async function createCsharpBom(path, options) {
|
|
|
1683
1744
|
console.log(result.stdout);
|
|
1684
1745
|
}
|
|
1685
1746
|
console.log("---------");
|
|
1686
|
-
options
|
|
1747
|
+
deferFailOnError(options, {
|
|
1748
|
+
ecosystem: "csharp",
|
|
1749
|
+
tool: "dotnet",
|
|
1750
|
+
detail: "the dotnet restore did not produce a usable assets file",
|
|
1751
|
+
});
|
|
1687
1752
|
}
|
|
1688
1753
|
}
|
|
1689
1754
|
// Collect the assets, lock, and nupkg files generated from restore
|
|
@@ -1786,7 +1851,11 @@ export async function createCsharpBom(path, options) {
|
|
|
1786
1851
|
console.log(
|
|
1787
1852
|
"Alternatively, try using the custom `ghcr.io/cdxgen/cdxgen-dotnet:v13` container image, which bundles a range of dotnet SDKs.",
|
|
1788
1853
|
);
|
|
1789
|
-
options
|
|
1854
|
+
deferFailOnError(options, {
|
|
1855
|
+
ecosystem: "csharp",
|
|
1856
|
+
tool: "dotnet",
|
|
1857
|
+
detail: "no dotnet dependency evidence could be collected",
|
|
1858
|
+
});
|
|
1790
1859
|
}
|
|
1791
1860
|
}
|
|
1792
1861
|
// packages.lock.json parsing for any project without a project.assets.json
|
|
@@ -1960,7 +2029,10 @@ export async function createCsharpBom(path, options) {
|
|
|
1960
2029
|
}
|
|
1961
2030
|
pkgList = addEvidenceForDotnet(pkgList, slicesFile);
|
|
1962
2031
|
const methodsSlice = readDosaiJsonFile(slicesFile);
|
|
1963
|
-
|
|
2032
|
+
// Provider-backed Services[] first so bom-refs, trust zones, and data
|
|
2033
|
+
// classifications survive; ApiEndpoints derivation fills in the rest.
|
|
2034
|
+
const servicesMap = collectDosaiServiceComponents(methodsSlice, {});
|
|
2035
|
+
collectDosaiServicesFromMethods(methodsSlice, servicesMap);
|
|
1964
2036
|
services = normalizeDosaiServiceMap(servicesMap);
|
|
1965
2037
|
}
|
|
1966
2038
|
}
|
|
@@ -2081,3 +2153,152 @@ export async function createCryptoCertsBom(path, options) {
|
|
|
2081
2153
|
},
|
|
2082
2154
|
};
|
|
2083
2155
|
}
|
|
2156
|
+
|
|
2157
|
+
/**
|
|
2158
|
+
* Function to create bom string for R projects using renv.
|
|
2159
|
+
*
|
|
2160
|
+
* The `renv.lock` file carries the resolved package set for the project
|
|
2161
|
+
* library, including the R version it was produced under.
|
|
2162
|
+
*
|
|
2163
|
+
* @param {string} path to the project
|
|
2164
|
+
* @param {Object} options Parse options from the cli
|
|
2165
|
+
* @returns {Object} BOM object
|
|
2166
|
+
*/
|
|
2167
|
+
export function createRBom(path, options) {
|
|
2168
|
+
let pkgList = [];
|
|
2169
|
+
let dependencies = [];
|
|
2170
|
+
let rootInputs = [];
|
|
2171
|
+
let rVersion;
|
|
2172
|
+
const renvLockFiles = getAllFiles(
|
|
2173
|
+
path,
|
|
2174
|
+
`${options.multiProject ? "**/" : ""}renv.lock`,
|
|
2175
|
+
options,
|
|
2176
|
+
);
|
|
2177
|
+
for (const renvLockFile of renvLockFiles) {
|
|
2178
|
+
if (DEBUG_MODE) {
|
|
2179
|
+
console.log(`Parsing ${renvLockFile}`);
|
|
2180
|
+
}
|
|
2181
|
+
const result = parseRenvLock(renvLockFile);
|
|
2182
|
+
if (result.pkgList?.length) {
|
|
2183
|
+
pkgList = pkgList.concat(result.pkgList);
|
|
2184
|
+
}
|
|
2185
|
+
if (result.dependencies?.length) {
|
|
2186
|
+
dependencies = dependencies.concat(result.dependencies);
|
|
2187
|
+
}
|
|
2188
|
+
if (result.rootInputs?.length) {
|
|
2189
|
+
rootInputs = rootInputs.concat(result.rootInputs);
|
|
2190
|
+
}
|
|
2191
|
+
if (!rVersion) {
|
|
2192
|
+
rVersion = result.rVersion;
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
if (!pkgList.length) {
|
|
2196
|
+
return {};
|
|
2197
|
+
}
|
|
2198
|
+
// renv locks the library, not the project: they carry no project name, so
|
|
2199
|
+
// the directory is the name the project is already known by. The R version
|
|
2200
|
+
// the library was resolved under is a property of that project.
|
|
2201
|
+
const projectName = basename(resolve(path));
|
|
2202
|
+
const parentComponent = {
|
|
2203
|
+
type: "application",
|
|
2204
|
+
name: projectName,
|
|
2205
|
+
"bom-ref": `application:${projectName}:latest`,
|
|
2206
|
+
description: `R project: ${projectName}`,
|
|
2207
|
+
properties: [
|
|
2208
|
+
{ name: "internal:SrcFile", value: renvLockFiles.join(", ") },
|
|
2209
|
+
...(rVersion ? [{ name: "cdx:renv:rVersion", value: rVersion }] : []),
|
|
2210
|
+
],
|
|
2211
|
+
};
|
|
2212
|
+
if (rootInputs.length) {
|
|
2213
|
+
dependencies.push({
|
|
2214
|
+
ref: parentComponent["bom-ref"],
|
|
2215
|
+
dependsOn: [...new Set(rootInputs)].sort(),
|
|
2216
|
+
});
|
|
2217
|
+
}
|
|
2218
|
+
return buildBomNSData(options, pkgList, "cran", {
|
|
2219
|
+
src: path,
|
|
2220
|
+
filename: renvLockFiles.join(", "),
|
|
2221
|
+
dependencies,
|
|
2222
|
+
parentComponent,
|
|
2223
|
+
});
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
/**
|
|
2227
|
+
* Function to create bom string for Perl projects using Carton.
|
|
2228
|
+
*
|
|
2229
|
+
* The `cpanfile.snapshot` carries the resolved install set; the declared
|
|
2230
|
+
* `cpanfile` is consulted to distinguish direct dependencies.
|
|
2231
|
+
*
|
|
2232
|
+
* @param {string} path to the project
|
|
2233
|
+
* @param {Object} options Parse options from the cli
|
|
2234
|
+
* @returns {Object} BOM object
|
|
2235
|
+
*/
|
|
2236
|
+
export function createPerlBom(path, options) {
|
|
2237
|
+
let pkgList = [];
|
|
2238
|
+
let dependencies = [];
|
|
2239
|
+
const snapshotFiles = getAllFiles(
|
|
2240
|
+
path,
|
|
2241
|
+
`${options.multiProject ? "**/" : ""}cpanfile.snapshot`,
|
|
2242
|
+
options,
|
|
2243
|
+
);
|
|
2244
|
+
for (const snapshotFile of snapshotFiles) {
|
|
2245
|
+
if (DEBUG_MODE) {
|
|
2246
|
+
console.log(`Parsing ${snapshotFile}`);
|
|
2247
|
+
}
|
|
2248
|
+
const baseDir = dirname(snapshotFile);
|
|
2249
|
+
const cpanfile = join(baseDir, "cpanfile");
|
|
2250
|
+
const result = parseCpanSnapshot(
|
|
2251
|
+
snapshotFile,
|
|
2252
|
+
safeExistsSync(cpanfile) ? cpanfile : undefined,
|
|
2253
|
+
);
|
|
2254
|
+
if (result.pkgList?.length) {
|
|
2255
|
+
pkgList = pkgList.concat(result.pkgList);
|
|
2256
|
+
}
|
|
2257
|
+
if (result.dependencies?.length) {
|
|
2258
|
+
dependencies = dependencies.concat(result.dependencies);
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
if (pkgList.length) {
|
|
2262
|
+
return buildBomNSData(options, pkgList, "cpan", {
|
|
2263
|
+
src: path,
|
|
2264
|
+
filename: snapshotFiles.join(", "),
|
|
2265
|
+
dependencies,
|
|
2266
|
+
});
|
|
2267
|
+
}
|
|
2268
|
+
return {};
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
/**
|
|
2272
|
+
* Function to create bom string for Terraform and OpenTofu projects.
|
|
2273
|
+
*
|
|
2274
|
+
* The `.terraform.lock.hcl` file pins the providers the configuration
|
|
2275
|
+
* resolves to, with content hashes suitable for the CycloneDX hashes array.
|
|
2276
|
+
*
|
|
2277
|
+
* @param {string} path to the project
|
|
2278
|
+
* @param {Object} options Parse options from the cli
|
|
2279
|
+
* @returns {Object} BOM object
|
|
2280
|
+
*/
|
|
2281
|
+
export function createTerraformBom(path, options) {
|
|
2282
|
+
let pkgList = [];
|
|
2283
|
+
const lockFiles = getAllFiles(
|
|
2284
|
+
path,
|
|
2285
|
+
`${options.multiProject ? "**/" : ""}.terraform.lock.hcl`,
|
|
2286
|
+
options,
|
|
2287
|
+
);
|
|
2288
|
+
for (const lockFile of lockFiles) {
|
|
2289
|
+
if (DEBUG_MODE) {
|
|
2290
|
+
console.log(`Parsing ${lockFile}`);
|
|
2291
|
+
}
|
|
2292
|
+
const result = parseTerraformLockFile(lockFile);
|
|
2293
|
+
if (result.pkgList?.length) {
|
|
2294
|
+
pkgList = pkgList.concat(result.pkgList);
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
if (pkgList.length) {
|
|
2298
|
+
return buildBomNSData(options, pkgList, "terraform", {
|
|
2299
|
+
src: path,
|
|
2300
|
+
filename: lockFiles.join(", "),
|
|
2301
|
+
});
|
|
2302
|
+
}
|
|
2303
|
+
return {};
|
|
2304
|
+
}
|