@cyclonedx/cdxgen 10.2.6 → 10.3.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 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
 
@@ -411,7 +417,7 @@ cdxgen could be extended with external binary plugins to support more SBOM use c
411
417
  sudo npm install -g @cyclonedx/cdxgen-plugins-bin
412
418
  ```
413
419
 
414
- ### Docker / OCI container support
420
+ ## Docker / OCI container support
415
421
 
416
422
  `docker` type is automatically detected based on the presence of values such as `sha256` or `docker.io` prefix etc in the path.
417
423
 
@@ -446,7 +452,7 @@ systemctl --user start podman.socket
446
452
  podman system service -t 0 &
447
453
  ```
448
454
 
449
- ### Generate OBOM for a live system
455
+ ## Generate OBOM for a live system
450
456
 
451
457
  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
458
 
@@ -458,6 +464,15 @@ obom
458
464
 
459
465
  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
466
 
467
+ ## Generate Cryptography Bill of Materials (CBOM)
468
+
469
+ Use the `cbom` alias to generate a CBOM. This is currently supported only for Java projects.
470
+
471
+ ```shell
472
+ cbom -t java
473
+ # cdxgen -t java --include-crypto -o bom.json .
474
+ ```
475
+
461
476
  ## Generating SaaSBOM and component evidences
462
477
 
463
478
  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
@@ -19,7 +19,12 @@ let url = import.meta.url;
19
19
  if (!url.startsWith("file://")) {
20
20
  url = new URL(`file://${import.meta.url}`).toString();
21
21
  }
22
- const dirName = import.meta ? dirname(fileURLToPath(url)) : __dirname;
22
+ let dirName = import.meta ? dirname(fileURLToPath(url)) : __dirname;
23
+ // When cdxgen is used as a library, dirName would be inside the node_modules directory
24
+ // we need to locate the base directory of the dependent project in this case.
25
+ if (dirName.includes("node_modules")) {
26
+ dirName = dirName.split(join("node_modules", "@cyclonedx"))[0];
27
+ }
23
28
 
24
29
  const isWin = _platform() === "win32";
25
30
 
@@ -399,10 +404,7 @@ export function getOSPackages(src) {
399
404
  osReleaseFile = join(src, "usr", "lib", "os-release");
400
405
  }
401
406
  if (osReleaseFile) {
402
- const osReleaseInfo = readFileSync(
403
- join(src, "usr", "lib", "os-release"),
404
- "utf-8"
405
- );
407
+ const osReleaseInfo = readFileSync(osReleaseFile, "utf-8");
406
408
  if (osReleaseInfo) {
407
409
  osReleaseInfo.split("\n").forEach((l) => {
408
410
  if (!l.startsWith("#") && l.includes("=")) {
@@ -425,6 +427,15 @@ export function getOSPackages(src) {
425
427
  case "pop":
426
428
  purl_type = "deb";
427
429
  break;
430
+ case "alpine":
431
+ purl_type = "apk";
432
+ if (osReleaseData.VERSION_ID) {
433
+ const versionParts = osReleaseData["VERSION_ID"].split(".");
434
+ if (versionParts.length >= 2) {
435
+ distro_codename = `alpine-${versionParts[0]}.${versionParts[1]}`;
436
+ }
437
+ }
438
+ break;
428
439
  default:
429
440
  if (distro_id_like.includes("debian")) {
430
441
  purl_type = "deb";
@@ -524,7 +535,7 @@ export function getOSPackages(src) {
524
535
  } else if (group === "alpine") {
525
536
  const dtmpA = purlObj.qualifiers.distro.split(".");
526
537
  if (dtmpA && dtmpA.length > 2) {
527
- distro_codename = group + "-" + dtmpA[0] + "." + dtmpA[1];
538
+ distro_codename = dtmpA[0] + "." + dtmpA[1];
528
539
  }
529
540
  } else if (group === "photon") {
530
541
  const dtmpA = purlObj.qualifiers.distro.split("-");
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 |