@cyclonedx/cdxgen 10.2.6 → 10.3.1

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 CHANGED
@@ -2,13 +2,18 @@
2
2
 
3
3
  ![cdxgen logo](cdxgen.png)
4
4
 
5
- cdxgen is a CLI tool, library, [REPL](./ADVANCED.md), and server to create a valid and compliant [CycloneDX][cyclonedx-homepage] Software Bill of Materials (SBOM) containing an aggregate of all project dependencies for C/C++, Node.js, PHP, Python, Ruby, Rust, Java, .Net, Dart, Haskell, Elixir, and Go projects in JSON format. CycloneDX 1.5 is a lightweight SBOM specification that is easily created, human and machine-readable, and simple to parse.
5
+ [![JSR](https://jsr.io/badges/@cyclonedx/cdxgen)](https://jsr.io/@cyclonedx/cdxgen)
6
6
 
7
- When used with plugins, cdxgen could generate an OBOM for Linux docker images and even VMs running Linux or Windows operating systems. cdxgen also includes an evinse tool to generate component evidence and SaaSBOM for some languages.
7
+ cdxgen is a CLI tool, library, [REPL](./ADVANCED.md), and server to create a valid and compliant [CycloneDX][cyclonedx-homepage] Bill of Materials (BOM) containing an aggregate of all project dependencies for C/C++, Node.js, PHP, Python, Ruby, Rust, Java, .Net, Dart, Haskell, Elixir, and Go projects in JSON format. CycloneDX is a full-stack BOM specification that is easily created, human and machine-readable, and simple to parse. The tool supports CycloneDX specification versions from 1.4 - 1.6.
8
+
9
+ When used with plugins:
10
+
11
+ - cdxgen could generate an OBOM for Linux docker images and even VMs running Linux or Windows operating systems
12
+ - cdxgen also includes an evinse tool to generate component evidence, CBOM and SaaSBOM for some languages
8
13
 
9
14
  ## Why cdxgen?
10
15
 
11
- Most SBOM tools are like simple barcode scanners. For easy applications, they can parse a few package manifests and create a list of components only based on these files without any deep inspection. Further, a typical application might have several repos, components, and libraries with complex build requirements. Traditional techniques to generate an SBOM per language or package manifest either do not work in enterprise environments or don't provide the confidence required for both compliance and automated analysis. So we built cdxgen - the universal polyglot SBOM generator that is user-friendly, precise and comprehensive!
16
+ Most SBOM tools are like simple barcode scanners. For easy applications, they can parse a few package manifests and create a list of components only based on these files without any deep inspection. Further, a typical application might have several repos, components, and libraries with complex build requirements. Traditional techniques to generate an SBOM per language or package manifest either do not work in enterprise environments or don't provide the confidence required for both compliance and automated analysis. So we built cdxgen - the universal polyglot SBOM generator that is user-friendly, precise, and comprehensive!
12
17
 
13
18
  <img src="./docs/why-cdxgen.jpg" alt="why cdxgen" width="256">
14
19
 
@@ -85,9 +90,6 @@ For go, `go mod why` command is used to identify required packages. For php, com
85
90
 
86
91
  ```shell
87
92
  npm install -g @cyclonedx/cdxgen
88
-
89
- # For CycloneDX 1.4 compatibility use version 8.6.0 or pass the argument `--spec-version 1.4`
90
- npm install -g @cyclonedx/cdxgen@8.6.0
91
93
  ```
92
94
 
93
95
  If you are a [Homebrew](https://brew.sh/) user, you can also install [cdxgen](https://formulae.brew.sh/formula/cdxgen) via:
@@ -228,9 +230,13 @@ To recursively generate a single BOM for all languages pass `-r` argument.
228
230
  cdxgen -r -o bom.json
229
231
  ```
230
232
 
231
- To generate SBOM for an older specification version, such as 1.4, pass the version number using the `--spec-version` argument.
233
+ The default specification used by cdxgen is 1.5. To generate BOM for a different specification version, such as 1.6 or 1.4, pass the version number using the `--spec-version` argument.
232
234
 
233
235
  ```shell
236
+ # 1.6 is unsupported by most tools
237
+ cdxgen -r -o bom.json --spec-version 1.6
238
+
239
+ # 1.4 is supported by most tools
234
240
  cdxgen -r -o bom.json --spec-version 1.4
235
241
  ```
236
242
 
@@ -361,6 +367,7 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
361
367
  - Go (go.mod)
362
368
  - PHP (composer.lock)
363
369
  - Ruby (Gemfile.lock)
370
+ - Rust (Cargo.lock)
364
371
 
365
372
  ## Environment variables
366
373
 
@@ -411,7 +418,7 @@ cdxgen could be extended with external binary plugins to support more SBOM use c
411
418
  sudo npm install -g @cyclonedx/cdxgen-plugins-bin
412
419
  ```
413
420
 
414
- ### Docker / OCI container support
421
+ ## Docker / OCI container support
415
422
 
416
423
  `docker` type is automatically detected based on the presence of values such as `sha256` or `docker.io` prefix etc in the path.
417
424
 
@@ -446,7 +453,7 @@ systemctl --user start podman.socket
446
453
  podman system service -t 0 &
447
454
  ```
448
455
 
449
- ### Generate OBOM for a live system
456
+ ## Generate OBOM for a live system
450
457
 
451
458
  You can use the `obom` command to generate an OBOM for a live system or a VM for compliance and vulnerability management purposes. Windows and Linux operating systems are supported in this mode.
452
459
 
@@ -458,6 +465,15 @@ obom
458
465
 
459
466
  This feature is powered by osquery, which is [installed](https://github.com/cyclonedx/cdxgen-plugins-bin/blob/main/build.sh#L8) along with the binary plugins. cdxgen would opportunistically try to detect as many components, apps, and extensions as possible using the [default queries](queries.json). The process would take several minutes and result in an SBOM file with thousands of components of various types, such as operating-system, device-drivers, files, and data.
460
467
 
468
+ ## Generate Cryptography Bill of Materials (CBOM)
469
+
470
+ Use the `cbom` alias to generate a CBOM. This is currently supported only for Java projects.
471
+
472
+ ```shell
473
+ cbom -t java
474
+ # cdxgen -t java --include-crypto -o bom.json .
475
+ ```
476
+
461
477
  ## Generating SaaSBOM and component evidences
462
478
 
463
479
  See [evinse mode](./ADVANCED.md) in the advanced documentation.
package/bin/cdxgen.js CHANGED
@@ -294,11 +294,18 @@ if (!args.projectName) {
294
294
  }
295
295
  }
296
296
 
297
- // Support for obom aliases
297
+ // Support for obom/cbom aliases
298
298
  if (process.argv[1].includes("obom") && !args.type) {
299
299
  args.type = "os";
300
300
  }
301
301
 
302
+ if (process.argv[1].includes("cbom") && !args.type) {
303
+ options.includeCrypto = true;
304
+ options.includeFormulation = true;
305
+ options.evidence = true;
306
+ options.specVersion = 1.6;
307
+ }
308
+
302
309
  /**
303
310
  * Method to apply advanced options such as profile and lifecycles
304
311
  *
@@ -593,7 +600,7 @@ const checkPermissions = (filePath) => {
593
600
  }
594
601
  }
595
602
  // Evidence generation
596
- if (options.evidence) {
603
+ if (options.evidence || options.includeCrypto) {
597
604
  const evinserModule = await import("../evinser.js");
598
605
  const evinseOptions = {
599
606
  _: args._,
@@ -607,7 +614,8 @@ const checkPermissions = (filePath) => {
607
614
  usagesSlicesFile: options.usagesSlicesFile,
608
615
  dataFlowSlicesFile: options.dataFlowSlicesFile,
609
616
  reachablesSlicesFile: options.reachablesSlicesFile,
610
- includeCrypto: options.includeCrypto
617
+ includeCrypto: options.includeCrypto,
618
+ specVersion: options.specVersion
611
619
  };
612
620
  const dbObjMap = await evinserModule.prepareDB(evinseOptions);
613
621
  if (dbObjMap) {
package/binary.js CHANGED
@@ -6,7 +6,8 @@ import {
6
6
  mkdirSync,
7
7
  mkdtempSync,
8
8
  readFileSync,
9
- rmSync
9
+ rmSync,
10
+ lstatSync
10
11
  } from "node:fs";
11
12
  import { basename, dirname, join, resolve } from "node:path";
12
13
  import { spawnSync } from "node:child_process";
@@ -399,10 +400,7 @@ export function getOSPackages(src) {
399
400
  osReleaseFile = join(src, "usr", "lib", "os-release");
400
401
  }
401
402
  if (osReleaseFile) {
402
- const osReleaseInfo = readFileSync(
403
- join(src, "usr", "lib", "os-release"),
404
- "utf-8"
405
- );
403
+ const osReleaseInfo = readFileSync(osReleaseFile, "utf-8");
406
404
  if (osReleaseInfo) {
407
405
  osReleaseInfo.split("\n").forEach((l) => {
408
406
  if (!l.startsWith("#") && l.includes("=")) {
@@ -425,6 +423,15 @@ export function getOSPackages(src) {
425
423
  case "pop":
426
424
  purl_type = "deb";
427
425
  break;
426
+ case "alpine":
427
+ purl_type = "apk";
428
+ if (osReleaseData.VERSION_ID) {
429
+ const versionParts = osReleaseData["VERSION_ID"].split(".");
430
+ if (versionParts.length >= 2) {
431
+ distro_codename = `alpine-${versionParts[0]}.${versionParts[1]}`;
432
+ }
433
+ }
434
+ break;
428
435
  default:
429
436
  if (distro_id_like.includes("debian")) {
430
437
  purl_type = "deb";
@@ -524,7 +531,7 @@ export function getOSPackages(src) {
524
531
  } else if (group === "alpine") {
525
532
  const dtmpA = purlObj.qualifiers.distro.split(".");
526
533
  if (dtmpA && dtmpA.length > 2) {
527
- distro_codename = group + "-" + dtmpA[0] + "." + dtmpA[1];
534
+ distro_codename = dtmpA[0] + "." + dtmpA[1];
528
535
  }
529
536
  } else if (group === "photon") {
530
537
  const dtmpA = purlObj.qualifiers.distro.split("-");
@@ -791,10 +798,11 @@ export function getBinaryBom(src, binaryBomFile, deepMode) {
791
798
  if (DEBUG_MODE) {
792
799
  console.log("Executing", BLINT_BIN, args.join(" "));
793
800
  }
801
+ const cwd = lstatSync(src).isDirectory() ? src : dirname(src);
794
802
  const result = spawnSync(BLINT_BIN, args, {
795
803
  encoding: "utf-8",
796
804
  timeout: TIMEOUT_MS,
797
- cwd: src
805
+ cwd
798
806
  });
799
807
  if (result.status !== 0 || result.error) {
800
808
  if (result.stderr) {
package/cbomutils.js CHANGED
@@ -5,6 +5,9 @@ import { join } from "node:path";
5
5
  const cbomosDbQueries = JSON.parse(
6
6
  readFileSync(join(dirNameStr, "data", "cbomosdb-queries.json"), "utf-8")
7
7
  );
8
+ const cbomCryptoOids = JSON.parse(
9
+ readFileSync(join(dirNameStr, "data", "crypto-oid.json"), "utf-8")
10
+ );
8
11
 
9
12
  /**
10
13
  * Method to collect crypto and ssl libraries from the OS.
@@ -12,7 +15,7 @@ const cbomosDbQueries = JSON.parse(
12
15
  * @param {Object} options
13
16
  * @returns osPkgsList Array of OS crypto packages
14
17
  */
15
- export const collectOSCryptoLibs = (options) => {
18
+ export function collectOSCryptoLibs(options) {
16
19
  let osPkgsList = [];
17
20
  for (const queryCategory of Object.keys(cbomosDbQueries)) {
18
21
  const queryObj = cbomosDbQueries[queryCategory];
@@ -36,4 +39,29 @@ export const collectOSCryptoLibs = (options) => {
36
39
  }
37
40
  }
38
41
  return osPkgsList;
39
- };
42
+ }
43
+
44
+ function cleanStr(str) {
45
+ return str.toLowerCase().replace(/[^0-9a-z ]/gi, "");
46
+ }
47
+
48
+ /**
49
+ * Find crypto algorithm in the given code snippet
50
+ *
51
+ * @param {String} Code snippet
52
+ * @returns {Array} Arary of crypto algorithm objects with oid and description
53
+ */
54
+ export function findCryptoAlgos(code) {
55
+ const cleanCode = cleanStr(code);
56
+ const cryptoAlgos = [];
57
+ for (const algoName of Object.keys(cbomCryptoOids)) {
58
+ if (cleanCode.includes(cleanStr(algoName))) {
59
+ cryptoAlgos.push({
60
+ ...cbomCryptoOids[algoName],
61
+ name: algoName,
62
+ ref: `crypto/algorithm/${algoName}@${cbomCryptoOids[algoName].oid}`
63
+ });
64
+ }
65
+ }
66
+ return cryptoAlgos;
67
+ }
package/data/README.md CHANGED
@@ -2,22 +2,23 @@
2
2
 
3
3
  Contents of data directory and their purpose.
4
4
 
5
- | Filename | Purpose |
6
- | --------------------- | ------------------------------------------------------------------------- |
7
- | bom-1.4.schema.json | CycloneDX 1.4 jsonschema for validation |
8
- | bom-1.5.schema.json | CycloneDX 1.5 jsonschema for validation |
9
- | cosdb-queries.json | osquery useful for identifying OS packages for C |
10
- | cbomosdb-queries.json | osquery for identifying ssl packages in OS |
11
- | jsf-0.82.schema.json | jsonschema for validation |
12
- | known-licenses.json | Hard coded list to correct any license id. Not maintained. |
13
- | lic-mapping.json | Hard coded list to match a license id based on name |
14
- | pypi-pkg-aliases.json | Hard coded list to match a pypi package name from module name |
15
- | python-stdlib.json | Standard libraries that can be filtered out in python |
16
- | queries-win.json | osquery used to generate obom for windows |
17
- | queries.json | osquery used to generate obom for linux |
18
- | queries-darwin.json | osquery used to generate obom for darwin |
19
- | spdx-licenses.json | valid spdx id |
20
- | spdx.schema.json | jsonschema for validation |
21
- | vendor-alias.json | List to correct the group names. Used while parsing .jar files |
22
- | wrapdb-releases.json | Database of all available meson wraps. Generated using contrib/wrapdb.py. |
23
- | frameworks-list.json | List of string fragments to categorize components into frameworks |
5
+ | Filename | Purpose |
6
+ | --------------------- | -------------------------------------------------------------------------------------------------------- |
7
+ | bom-1.4.schema.json | CycloneDX 1.4 jsonschema for validation |
8
+ | bom-1.5.schema.json | CycloneDX 1.5 jsonschema for validation |
9
+ | cosdb-queries.json | osquery useful for identifying OS packages for C |
10
+ | cbomosdb-queries.json | osquery for identifying ssl packages in OS |
11
+ | jsf-0.82.schema.json | jsonschema for validation |
12
+ | known-licenses.json | Hard coded list to correct any license id. Not maintained. |
13
+ | lic-mapping.json | Hard coded list to match a license id based on name |
14
+ | pypi-pkg-aliases.json | Hard coded list to match a pypi package name from module name |
15
+ | python-stdlib.json | Standard libraries that can be filtered out in python |
16
+ | queries-win.json | osquery used to generate obom for windows |
17
+ | queries.json | osquery used to generate obom for linux |
18
+ | queries-darwin.json | osquery used to generate obom for darwin |
19
+ | spdx-licenses.json | valid spdx id |
20
+ | spdx.schema.json | jsonschema for validation |
21
+ | vendor-alias.json | List to correct the group names. Used while parsing .jar files |
22
+ | wrapdb-releases.json | Database of all available meson wraps. Generated using contrib/wrapdb.py. |
23
+ | frameworks-list.json | List of string fragments to categorize components into frameworks |
24
+ | crypto-oid.json | Peter Gutmann's crypto oid [mapping](https://www.cs.auckland.ac.nz/~pgut001). GPL, BSD, or CC BY license |