@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 +24 -9
- package/bin/cdxgen.js +11 -3
- package/binary.js +17 -6
- package/cbomutils.js +30 -2
- package/data/README.md +20 -19
- package/data/bom-1.6.schema.json +5489 -0
- package/data/crypto-oid.json +1950 -0
- package/docker.js +2 -3
- package/envcontext.js +28 -1
- package/evinser.js +94 -6
- package/index.js +294 -58
- package/package.json +5 -5
- package/postgen.js +7 -2
- package/types/binary.d.ts.map +1 -1
- package/types/cbomutils.d.ts +13 -0
- package/types/cbomutils.d.ts.map +1 -1
- package/types/docker.d.ts.map +1 -1
- package/types/envcontext.d.ts +1 -0
- package/types/envcontext.d.ts.map +1 -1
- package/types/evinser.d.ts +16 -1
- package/types/evinser.d.ts.map +1 -1
- package/types/index.d.ts +34 -2
- package/types/index.d.ts.map +1 -1
- package/types/postgen.d.ts.map +1 -1
- package/types/utils.d.ts +33 -3
- package/types/utils.d.ts.map +1 -1
- package/types/validator.d.ts.map +1 -1
- package/utils.js +373 -79
- package/utils.test.js +353 -36
- package/validator.js +62 -11
package/README.md
CHANGED
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://jsr.io/@cyclonedx/cdxgen)
|
|
6
6
|
|
|
7
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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 |
|