@cyclonedx/cdxgen 12.0.0 → 12.1.0-beta.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 +34 -36
- package/bin/cdxgen.js +7 -5
- package/bin/dependencies.js +9 -0
- package/bin/evinse.js +1 -1
- package/bin/repl.js +196 -1
- package/bin/verify.js +10 -3
- package/data/README.md +23 -23
- package/data/vendor-alias.json +41961 -4
- package/lib/cli/index.js +160 -17
- package/lib/cli/index.poku.js +124 -0
- package/lib/evinser/evinser.js +5 -4
- package/lib/evinser/swiftsem.js +204 -80
- package/lib/evinser/swiftsem.poku.js +101 -4
- package/lib/helpers/caxa.js +55 -0
- package/lib/helpers/db.js +150 -69
- package/lib/helpers/db.poku.js +123 -0
- package/lib/helpers/display.js +5 -2
- package/lib/helpers/envcontext.js +12 -15
- package/lib/helpers/utils.js +417 -83
- package/lib/helpers/utils.poku.js +547 -38
- package/lib/managers/binary.js +34 -25
- package/lib/managers/docker.js +50 -3
- package/lib/managers/oci.js +5 -0
- package/lib/server/openapi.yaml +5 -5
- package/lib/server/server.js +1 -0
- package/lib/stages/postgen/annotator.js +1 -1
- package/lib/third-party/arborist/lib/node.js +0 -7
- package/package.json +120 -134
- package/types/bin/cdxgen.d.ts +3 -0
- package/types/bin/cdxgen.d.ts.map +1 -0
- package/types/bin/dependencies.d.ts +3 -0
- package/types/bin/dependencies.d.ts.map +1 -0
- package/types/bin/evinse.d.ts +3 -0
- package/types/bin/evinse.d.ts.map +1 -0
- package/types/bin/repl.d.ts +3 -0
- package/types/bin/repl.d.ts.map +1 -0
- package/types/bin/verify.d.ts +3 -0
- package/types/bin/verify.d.ts.map +1 -0
- package/types/cli/index.d.ts +11 -4
- package/types/cli/index.d.ts.map +1 -1
- package/types/evinser/swiftsem.d.ts +4 -4
- package/types/evinser/swiftsem.d.ts.map +1 -1
- package/types/helpers/caxa.d.ts +2 -0
- package/types/helpers/caxa.d.ts.map +1 -0
- package/types/helpers/db.d.ts +30 -14
- package/types/helpers/db.d.ts.map +1 -1
- package/types/helpers/display.d.ts.map +1 -1
- package/types/helpers/envcontext.d.ts +20 -19
- package/types/helpers/envcontext.d.ts.map +1 -1
- package/types/helpers/utils.d.ts +75 -48
- package/types/helpers/utils.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts +11 -4
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/evinser/evinser.d.ts +115 -553
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/swiftsem.d.ts +4 -4
- package/types/lib/evinser/swiftsem.d.ts.map +1 -1
- package/types/lib/helpers/caxa.d.ts +2 -0
- package/types/lib/helpers/caxa.d.ts.map +1 -0
- package/types/lib/helpers/db.d.ts +30 -14
- package/types/lib/helpers/db.d.ts.map +1 -1
- package/types/lib/helpers/display.d.ts.map +1 -1
- package/types/lib/helpers/envcontext.d.ts +20 -19
- package/types/lib/helpers/envcontext.d.ts.map +1 -1
- package/types/lib/helpers/utils.d.ts +107 -51
- package/types/lib/helpers/utils.d.ts.map +1 -1
- package/types/lib/helpers/validator.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts +1 -1
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +4 -4
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/managers/oci.d.ts.map +1 -1
- package/types/lib/managers/piptree.d.ts.map +1 -1
- package/types/lib/parsers/iri.d.ts +72 -0
- package/types/lib/parsers/iri.d.ts.map +1 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/third-party/arborist/lib/arborist/index.d.ts +37 -0
- package/types/lib/third-party/arborist/lib/arborist/index.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/arborist/load-actual.d.ts +34 -0
- package/types/lib/third-party/arborist/lib/arborist/load-actual.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/arborist/load-virtual.d.ts +24 -0
- package/types/lib/third-party/arborist/lib/arborist/load-virtual.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/calc-dep-flags.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/calc-dep-flags.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/can-place-dep.d.ts +38 -0
- package/types/lib/third-party/arborist/lib/can-place-dep.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/case-insensitive-map.d.ts +10 -0
- package/types/lib/third-party/arborist/lib/case-insensitive-map.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/consistent-resolve.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/consistent-resolve.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/debug.d.ts +6 -0
- package/types/lib/third-party/arborist/lib/debug.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/deepest-nesting-target.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/deepest-nesting-target.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/dep-valid.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/dep-valid.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/diff.d.ts +28 -0
- package/types/lib/third-party/arborist/lib/diff.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/edge.d.ts +45 -0
- package/types/lib/third-party/arborist/lib/edge.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/from-path.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/from-path.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/gather-dep-set.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/gather-dep-set.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/index.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/index.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/inventory.d.ts +13 -0
- package/types/lib/third-party/arborist/lib/inventory.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/link.d.ts +13 -0
- package/types/lib/third-party/arborist/lib/link.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/node.d.ts +94 -0
- package/types/lib/third-party/arborist/lib/node.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/optional-set.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/optional-set.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/override-resolves.d.ts +2 -0
- package/types/lib/third-party/arborist/lib/override-resolves.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/override-set.d.ts +25 -0
- package/types/lib/third-party/arborist/lib/override-set.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/peer-entry-sets.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/peer-entry-sets.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/place-dep.d.ts +45 -0
- package/types/lib/third-party/arborist/lib/place-dep.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/printable.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/printable.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/realpath.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/realpath.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/relpath.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/relpath.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/reset-dep-flags.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/reset-dep-flags.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/retire-path.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/retire-path.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/shrinkwrap.d.ts +54 -0
- package/types/lib/third-party/arborist/lib/shrinkwrap.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/signal-handling.d.ts +6 -0
- package/types/lib/third-party/arborist/lib/signal-handling.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/signals.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/signals.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/spec-from-lock.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/spec-from-lock.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/tracker.d.ts +13 -0
- package/types/lib/third-party/arborist/lib/tracker.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/tree-check.d.ts +3 -0
- package/types/lib/third-party/arborist/lib/tree-check.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/version-from-tgz.d.ts +6 -0
- package/types/lib/third-party/arborist/lib/version-from-tgz.d.ts.map +1 -0
- package/types/lib/third-party/arborist/lib/yarn-lock.d.ts +34 -0
- package/types/lib/third-party/arborist/lib/yarn-lock.d.ts.map +1 -0
- package/types/managers/binary.d.ts +1 -1
- package/types/managers/binary.d.ts.map +1 -1
- package/types/managers/docker.d.ts +4 -4
- package/types/managers/docker.d.ts.map +1 -1
- package/types/managers/oci.d.ts.map +1 -1
- package/types/server/server.d.ts.map +1 -1
- package/types/third-party/arborist/lib/arborist/index.d.ts +9 -8
- package/types/third-party/arborist/lib/arborist/index.d.ts.map +1 -1
- package/types/third-party/arborist/lib/arborist/load-actual.d.ts +3 -7
- package/types/third-party/arborist/lib/arborist/load-actual.d.ts.map +1 -1
- package/types/third-party/arborist/lib/arborist/load-virtual.d.ts +2 -4
- package/types/third-party/arborist/lib/arborist/load-virtual.d.ts.map +1 -1
- package/types/third-party/arborist/lib/can-place-dep.d.ts +5 -5
- package/types/third-party/arborist/lib/can-place-dep.d.ts.map +1 -1
- package/types/third-party/arborist/lib/case-insensitive-map.d.ts +4 -4
- package/types/third-party/arborist/lib/case-insensitive-map.d.ts.map +1 -1
- package/types/third-party/arborist/lib/diff.d.ts +1 -1
- package/types/third-party/arborist/lib/gather-dep-set.d.ts +1 -1
- package/types/third-party/arborist/lib/gather-dep-set.d.ts.map +1 -1
- package/types/third-party/arborist/lib/inventory.d.ts +2 -3
- package/types/third-party/arborist/lib/inventory.d.ts.map +1 -1
- package/types/third-party/arborist/lib/link.d.ts +5 -8
- package/types/third-party/arborist/lib/link.d.ts.map +1 -1
- package/types/third-party/arborist/lib/node.d.ts +9 -10
- package/types/third-party/arborist/lib/node.d.ts.map +1 -1
- package/types/third-party/arborist/lib/optional-set.d.ts +1 -1
- package/types/third-party/arborist/lib/optional-set.d.ts.map +1 -1
- package/types/third-party/arborist/lib/override-set.d.ts +3 -3
- package/types/third-party/arborist/lib/override-set.d.ts.map +1 -1
- package/types/third-party/arborist/lib/peer-entry-sets.d.ts +1 -1
- package/types/third-party/arborist/lib/peer-entry-sets.d.ts.map +1 -1
- package/types/third-party/arborist/lib/place-dep.d.ts +2 -2
- package/types/third-party/arborist/lib/place-dep.d.ts.map +1 -1
- package/types/third-party/arborist/lib/relpath.d.ts +1 -1
- package/types/third-party/arborist/lib/relpath.d.ts.map +1 -1
- package/types/third-party/arborist/lib/retire-path.d.ts +1 -1
- package/types/third-party/arborist/lib/retire-path.d.ts.map +1 -1
- package/types/third-party/arborist/lib/shrinkwrap.d.ts +8 -8
- package/types/third-party/arborist/lib/shrinkwrap.d.ts.map +1 -1
- package/types/third-party/arborist/lib/signal-handling.d.ts +1 -1
- package/types/third-party/arborist/lib/tracker.d.ts +1 -1
- package/types/third-party/arborist/lib/yarn-lock.d.ts +2 -3
- package/types/third-party/arborist/lib/yarn-lock.d.ts.map +1 -1
- package/lib/third-party/arborist/lib/query-selector-all.js +0 -182
- package/types/third-party/arborist/lib/query-selector-all.d.ts +0 -3
- package/types/third-party/arborist/lib/query-selector-all.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
<img src="./docs/_media/cdxgen.png" width="200" height="auto" />
|
|
12
12
|
|
|
13
|
-
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 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.
|
|
13
|
+
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 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.7.
|
|
14
14
|
|
|
15
15
|
Supported BOM formats:
|
|
16
16
|
|
|
@@ -51,6 +51,7 @@ Sections include:
|
|
|
51
51
|
## Usage
|
|
52
52
|
|
|
53
53
|
## For Contributors / Developers
|
|
54
|
+
|
|
54
55
|
```shell
|
|
55
56
|
pnpm install
|
|
56
57
|
pnpm dlx cdxgen
|
|
@@ -122,10 +123,10 @@ Commands:
|
|
|
122
123
|
|
|
123
124
|
Options:
|
|
124
125
|
-o, --output Output file. Default bom.json [default: "bom.json"]
|
|
125
|
-
-t, --type Project type. Please refer to https://
|
|
126
|
-
|
|
127
|
-
--exclude-type Project types to exclude. Please refer to https://
|
|
128
|
-
|
|
126
|
+
-t, --type Project type. Please refer to https://cdxgen.github.io/cdxgen/#/PROJECT_TYPES for supp
|
|
127
|
+
orted languages/platforms. [array]
|
|
128
|
+
--exclude-type Project types to exclude. Please refer to https://cdxgen.github.io/cdxgen/#/PROJECT_TY
|
|
129
|
+
PES for supported languages/platforms.
|
|
129
130
|
-r, --recurse Recurse mode suitable for mono-repos. Defaults to true. Pass --no-recurse to disable.
|
|
130
131
|
[boolean] [default: true]
|
|
131
132
|
-p, --print Print the SBOM as a table with tree. [boolean]
|
|
@@ -138,6 +139,7 @@ Options:
|
|
|
138
139
|
--project-group Dependency track project group
|
|
139
140
|
--project-name Dependency track project name. Default use the directory name
|
|
140
141
|
--project-version Dependency track project version [string] [default: ""]
|
|
142
|
+
--project-tag Dependency track project tag. Multiple values allowed. [array]
|
|
141
143
|
--project-id Dependency track project id. Either provide the id or the project name and version tog
|
|
142
144
|
ether [string]
|
|
143
145
|
--parent-project-id Dependency track parent project id [string]
|
|
@@ -297,7 +299,7 @@ curl -H "Content-Type: application/json" http://localhost:9090/sbom -XPOST -d $'
|
|
|
297
299
|
### Docker compose
|
|
298
300
|
|
|
299
301
|
```shell
|
|
300
|
-
git clone https://github.com/
|
|
302
|
+
git clone https://github.com/cdxgen/cdxgen.git
|
|
301
303
|
docker compose up
|
|
302
304
|
```
|
|
303
305
|
|
|
@@ -345,27 +347,23 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
|
|
|
345
347
|
- Ruby (Gemfile.lock)
|
|
346
348
|
- Rust (Cargo.lock)
|
|
347
349
|
|
|
348
|
-
|
|
349
|
-
|
|
350
350
|
## Plugins
|
|
351
351
|
|
|
352
352
|
cdxgen could be extended with external binary plugins to support more SBOM use cases. These are now installed as an optional dependency.
|
|
353
353
|
|
|
354
354
|
```shell
|
|
355
|
-
sudo npm install -g @
|
|
355
|
+
sudo npm install -g @cdxgen/cdxgen-plugins-bin
|
|
356
356
|
```
|
|
357
357
|
|
|
358
|
-
|
|
359
358
|
## Plugins (pnpm)
|
|
360
359
|
|
|
361
360
|
`cdxgen` can be extended with external binary plugins to support more SBOM use cases.
|
|
362
361
|
These are now installed as optional dependencies and can be used without a global install.
|
|
363
362
|
|
|
364
363
|
```shell
|
|
365
|
-
pnpm dlx @
|
|
364
|
+
pnpm dlx @cdxgen/cdxgen-plugins-bin
|
|
366
365
|
```
|
|
367
366
|
|
|
368
|
-
|
|
369
367
|
## Docker / OCI container support
|
|
370
368
|
|
|
371
369
|
`docker` type is automatically detected based on the presence of values such as `sha256` or `docker.io` prefix etc in the path.
|
|
@@ -411,7 +409,7 @@ obom
|
|
|
411
409
|
# cdxgen -t os
|
|
412
410
|
```
|
|
413
411
|
|
|
414
|
-
This feature is powered by osquery, which is [installed](https://github.com/
|
|
412
|
+
This feature is powered by osquery, which is [installed](https://github.com/cdxgen/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](data/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.
|
|
415
413
|
|
|
416
414
|
## Generate Cryptography Bill of Materials (CBOM)
|
|
417
415
|
|
|
@@ -447,7 +445,6 @@ npm install -g @cyclonedx/cdxgen
|
|
|
447
445
|
cdx-verify -i bom.json --public-key public.key
|
|
448
446
|
```
|
|
449
447
|
|
|
450
|
-
|
|
451
448
|
### Verifying the signature (pnpm)
|
|
452
449
|
|
|
453
450
|
Use the bundled `cdx-verify` command, which supports verifying a single signature added at the BOM level.
|
|
@@ -458,7 +455,6 @@ You can run it directly using pnpm (no global install needed):
|
|
|
458
455
|
pnpm dlx @cyclonedx/cdxgen cdx-verify -i bom.json --public-key public.key
|
|
459
456
|
```
|
|
460
457
|
|
|
461
|
-
|
|
462
458
|
### Custom verification tool (Node.js example)
|
|
463
459
|
|
|
464
460
|
There are many [libraries][jwt-libraries] available to validate JSON Web Tokens. Below is a javascript example.
|
|
@@ -566,11 +562,10 @@ Use `pnpm add -g` command to quickly test the main branch.
|
|
|
566
562
|
```shell
|
|
567
563
|
corepack pnpm bin -g
|
|
568
564
|
corepack pnpm setup
|
|
569
|
-
corepack pnpm add -g --allow-build @appthreat/sqlite3 https://github.com/
|
|
565
|
+
corepack pnpm add -g --allow-build @appthreat/sqlite3 https://github.com/cdxgen/cdxgen
|
|
570
566
|
cdxgen --help
|
|
571
567
|
```
|
|
572
568
|
|
|
573
|
-
|
|
574
569
|
### Testing main branch (No Global Install)
|
|
575
570
|
|
|
576
571
|
To quickly test the latest main branch without installing globally, you can use `pnpm` in a local or temporary environment.
|
|
@@ -581,15 +576,18 @@ pnpm install --prefer-offline
|
|
|
581
576
|
pnpm dlx cdxgen --help
|
|
582
577
|
```
|
|
583
578
|
|
|
584
|
-
|
|
585
579
|
## Sponsors
|
|
586
580
|
|
|
587
581
|
<div style="display: flex; align-items: center; gap: 20px;">
|
|
588
|
-
<img src="./docs/_media/
|
|
589
|
-
<img src="./docs/_media/
|
|
590
|
-
<img src="./docs/_media/MicrosoftLogo.png" width="180" height="auto">
|
|
582
|
+
<img src="./docs/_media/GithubLogo-LightBg.png" width="180" height="180">
|
|
583
|
+
<img src="./docs/_media/MicrosoftLogo.png" width="180" height="180">
|
|
591
584
|
</div>
|
|
592
585
|
|
|
586
|
+
Some features are funded through [NGI Zero Core](https://nlnet.nl/core), a fund established by [NLnet](https://nlnet.nl) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu) program. Learn more at the [NLnet project page](https://nlnet.nl/project/OWASP-dep-scan).
|
|
587
|
+
|
|
588
|
+
[<img src="https://nlnet.nl/logo/banner.png" alt="NLnet foundation logo" width="20%" />](https://nlnet.nl)
|
|
589
|
+
[<img src="https://nlnet.nl/image/logos/NGI0_tag.svg" alt="NGI Zero Logo" width="20%" />](https://nlnet.nl/core)
|
|
590
|
+
|
|
593
591
|
<!-- LINK LABELS -->
|
|
594
592
|
<!-- Badges -->
|
|
595
593
|
|
|
@@ -599,26 +597,26 @@ pnpm dlx cdxgen --help
|
|
|
599
597
|
[badge-jsr]: https://img.shields.io/jsr/v/%40cyclonedx/cdxgen
|
|
600
598
|
[badge-npm]: https://img.shields.io/npm/v/%40cyclonedx%2Fcdxgen
|
|
601
599
|
[badge-npm-downloads]: https://img.shields.io/npm/dy/%40cyclonedx%2Fcdxgen
|
|
602
|
-
[badge-swh]: https://archive.softwareheritage.org/badge/origin/https://github.com/
|
|
600
|
+
[badge-swh]: https://archive.softwareheritage.org/badge/origin/https://github.com/cdxgen/cdxgen/
|
|
603
601
|
|
|
604
602
|
<!-- cdxgen github project -->
|
|
605
603
|
|
|
606
|
-
[github-contribute]: https://github.com/
|
|
607
|
-
[github-contributors]: https://github.com/
|
|
608
|
-
[github-issues]: https://github.com/
|
|
609
|
-
[github-license]: https://github.com/
|
|
610
|
-
[github-releases]: https://github.com/
|
|
604
|
+
[github-contribute]: https://github.com/cdxgen/cdxgen/contribute
|
|
605
|
+
[github-contributors]: https://github.com/cdxgen/cdxgen/graphs/contributors
|
|
606
|
+
[github-issues]: https://github.com/cdxgen/cdxgen/issues
|
|
607
|
+
[github-license]: https://github.com/cdxgen/cdxgen/blob/master/LICENSE
|
|
608
|
+
[github-releases]: https://github.com/cdxgen/cdxgen/releases
|
|
611
609
|
|
|
612
610
|
<!-- cdxgen documentation site -->
|
|
613
611
|
|
|
614
|
-
[docs-homepage]: https://
|
|
615
|
-
[docs-advanced-usage]: https://
|
|
616
|
-
[docs-cli]: https://
|
|
617
|
-
[docs-env-vars]: https://
|
|
618
|
-
[docs-permissions]: https://
|
|
619
|
-
[docs-project-types]: https://
|
|
620
|
-
[docs-server]: https://
|
|
621
|
-
[docs-support]: https://
|
|
612
|
+
[docs-homepage]: https://cdxgen.github.io/cdxgen
|
|
613
|
+
[docs-advanced-usage]: https://cdxgen.github.io/cdxgen/#/ADVANCED
|
|
614
|
+
[docs-cli]: https://cdxgen.github.io/cdxgen/#/CLI
|
|
615
|
+
[docs-env-vars]: https://cdxgen.github.io/cdxgen/#/ENV
|
|
616
|
+
[docs-permissions]: https://cdxgen.github.io/cdxgen/#/PERMISSIONS
|
|
617
|
+
[docs-project-types]: https://cdxgen.github.io/cdxgen/#/PROJECT_TYPES
|
|
618
|
+
[docs-server]: https://cdxgen.github.io/cdxgen/#/SERVER
|
|
619
|
+
[docs-support]: https://cdxgen.github.io/cdxgen/#/PROJECT_TYPES
|
|
622
620
|
|
|
623
621
|
<!-- web links-->
|
|
624
622
|
|
|
@@ -637,5 +635,5 @@ pnpm dlx cdxgen --help
|
|
|
637
635
|
[npmjs-cdxgen]: https://www.npmjs.com/package/@cyclonedx/cdxgen
|
|
638
636
|
[podman-github-rootless]: https://github.com/containers/podman/blob/master/docs/tutorials/rootless_tutorial.md
|
|
639
637
|
[podman-github-remote]: https://github.com/containers/podman/blob/master/docs/tutorials/mac_win_client.md
|
|
640
|
-
[swh-cdxgen]: https://archive.softwareheritage.org/browse/origin/?origin_url=https://github.com/
|
|
638
|
+
[swh-cdxgen]: https://archive.softwareheritage.org/browse/origin/?origin_url=https://github.com/cdxgen/cdxgen
|
|
641
639
|
[cdxgen-gpt]: https://chatgpt.com/g/g-673bfeb4037481919be8a2cd1bf868d2-cyclonedx-generator-cdxgen
|
package/bin/cdxgen.js
CHANGED
|
@@ -85,11 +85,11 @@ const args = _yargs
|
|
|
85
85
|
.option("type", {
|
|
86
86
|
alias: "t",
|
|
87
87
|
description:
|
|
88
|
-
"Project type. Please refer to https://
|
|
88
|
+
"Project type. Please refer to https://cdxgen.github.io/cdxgen/#/PROJECT_TYPES for supported languages/platforms.",
|
|
89
89
|
})
|
|
90
90
|
.option("exclude-type", {
|
|
91
91
|
description:
|
|
92
|
-
"Project types to exclude. Please refer to https://
|
|
92
|
+
"Project types to exclude. Please refer to https://cdxgen.github.io/cdxgen/#/PROJECT_TYPES for supported languages/platforms.",
|
|
93
93
|
})
|
|
94
94
|
.option("recurse", {
|
|
95
95
|
alias: "r",
|
|
@@ -136,6 +136,9 @@ const args = _yargs
|
|
|
136
136
|
default: "",
|
|
137
137
|
type: "string",
|
|
138
138
|
})
|
|
139
|
+
.option("project-tag", {
|
|
140
|
+
description: "Dependency track project tag. Multiple values allowed.",
|
|
141
|
+
})
|
|
139
142
|
.option("project-id", {
|
|
140
143
|
description:
|
|
141
144
|
"Dependency track project id. Either provide the id or the project name and version together",
|
|
@@ -378,7 +381,7 @@ const args = _yargs
|
|
|
378
381
|
],
|
|
379
382
|
["$0 --server", "Run cdxgen as a server"],
|
|
380
383
|
])
|
|
381
|
-
.epilogue("for documentation, visit https://
|
|
384
|
+
.epilogue("for documentation, visit https://cdxgen.github.io/cdxgen")
|
|
382
385
|
.config(config)
|
|
383
386
|
.scriptName("cdxgen")
|
|
384
387
|
.version(retrieveCdxgenVersion())
|
|
@@ -592,8 +595,6 @@ const applyAdvancedOptions = (options) => {
|
|
|
592
595
|
case "post-build":
|
|
593
596
|
if (
|
|
594
597
|
!options.projectType ||
|
|
595
|
-
(Array.isArray(options.projectType) &&
|
|
596
|
-
options.projectType.length > 1) ||
|
|
597
598
|
![
|
|
598
599
|
"csharp",
|
|
599
600
|
"dotnet",
|
|
@@ -609,6 +610,7 @@ const applyAdvancedOptions = (options) => {
|
|
|
609
610
|
"rust",
|
|
610
611
|
"rust-lang",
|
|
611
612
|
"cargo",
|
|
613
|
+
"caxa",
|
|
612
614
|
].includes(options.projectType[0])
|
|
613
615
|
) {
|
|
614
616
|
console.log(
|
package/bin/dependencies.js
CHANGED
|
@@ -17,6 +17,15 @@ const missingPnpmOverrides = [];
|
|
|
17
17
|
const obsoleteNpmOverrides = [];
|
|
18
18
|
const obsoletePnpmOverrides = [];
|
|
19
19
|
|
|
20
|
+
for (const _package in pkgJson.dependencies) {
|
|
21
|
+
checkOverride(_package, pkgJson.dependencies[_package]);
|
|
22
|
+
}
|
|
23
|
+
for (const _package in pkgJson.devDependencies) {
|
|
24
|
+
checkOverride(_package, pkgJson.devDependencies[_package]);
|
|
25
|
+
}
|
|
26
|
+
for (const _package in pkgJson.optionalDependencies) {
|
|
27
|
+
checkOverride(_package, pkgJson.optionalDependencies[_package]);
|
|
28
|
+
}
|
|
20
29
|
for (const _package in pnpmLockYaml.snapshots) {
|
|
21
30
|
const indexOfSeparator = _package.split("(")[0].lastIndexOf("@");
|
|
22
31
|
const packageName = _package.substring(0, indexOfSeparator);
|
package/bin/evinse.js
CHANGED
|
@@ -128,7 +128,7 @@ const args = yargs(hideBin(process.argv))
|
|
|
128
128
|
],
|
|
129
129
|
])
|
|
130
130
|
.completion("completion", "Generate bash/zsh completion")
|
|
131
|
-
.epilogue("for documentation, visit https://
|
|
131
|
+
.epilogue("for documentation, visit https://cdxgen.github.io/cdxgen")
|
|
132
132
|
.scriptName("evinse")
|
|
133
133
|
.version()
|
|
134
134
|
.help("h")
|
package/bin/repl.js
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
import { readBinary } from "../lib/helpers/protobom.js";
|
|
24
24
|
import { getTmpDir } from "../lib/helpers/utils.js";
|
|
25
25
|
import { validateBom } from "../lib/helpers/validator.js";
|
|
26
|
+
import { getBomWithOras } from "../lib/managers/oci.js";
|
|
26
27
|
|
|
27
28
|
const options = {
|
|
28
29
|
useColors: true,
|
|
@@ -86,6 +87,22 @@ export const importSbom = (sbomOrPath) => {
|
|
|
86
87
|
) {
|
|
87
88
|
sbom = readBinary(sbomOrPath, true);
|
|
88
89
|
printSummary(sbom);
|
|
90
|
+
} else if (
|
|
91
|
+
sbomOrPath.startsWith("ghcr.io") ||
|
|
92
|
+
sbomOrPath.startsWith("docker.io")
|
|
93
|
+
) {
|
|
94
|
+
try {
|
|
95
|
+
sbom = getBomWithOras(sbomOrPath);
|
|
96
|
+
if (sbom) {
|
|
97
|
+
printSummary(sbom);
|
|
98
|
+
} else {
|
|
99
|
+
console.log(
|
|
100
|
+
`cyclonedx sbom attachment was not found within ${sbomOrPath}`,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
} catch (e) {
|
|
104
|
+
console.log(`⚠ Unable to import the BOM from ${sbomOrPath} due to ${e}`);
|
|
105
|
+
}
|
|
89
106
|
} else {
|
|
90
107
|
console.log(`⚠ ${sbomOrPath} is invalid.`);
|
|
91
108
|
}
|
|
@@ -574,7 +591,185 @@ cdxgenRepl.defineCommand("osinfocategories", {
|
|
|
574
591
|
this.displayPrompt();
|
|
575
592
|
},
|
|
576
593
|
});
|
|
577
|
-
|
|
594
|
+
cdxgenRepl.defineCommand("licenses", {
|
|
595
|
+
help: "visualize license distribution",
|
|
596
|
+
async action() {
|
|
597
|
+
if (!sbom || !sbom.components) {
|
|
598
|
+
console.log("⚠ No SBOM loaded.");
|
|
599
|
+
this.displayPrompt();
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
const licenseCounts = {};
|
|
603
|
+
let unknown = 0;
|
|
604
|
+
sbom.components.forEach((c) => {
|
|
605
|
+
if (c.licenses && c.licenses.length > 0) {
|
|
606
|
+
c.licenses.forEach((l) => {
|
|
607
|
+
const name = l.license?.id || l.license?.name || "Unknown";
|
|
608
|
+
licenseCounts[name] = (licenseCounts[name] || 0) + 1;
|
|
609
|
+
});
|
|
610
|
+
} else {
|
|
611
|
+
unknown++;
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
if (unknown > 0) licenseCounts["None/Unknown"] = unknown;
|
|
615
|
+
const sorted = Object.entries(licenseCounts).sort((a, b) => b[1] - a[1]);
|
|
616
|
+
const maxVal = sorted[0][1];
|
|
617
|
+
const maxBarLength = 40;
|
|
618
|
+
console.log("\n📊 License Distribution:\n");
|
|
619
|
+
sorted.forEach(([license, count]) => {
|
|
620
|
+
const barLen = Math.ceil((count / maxVal) * maxBarLength);
|
|
621
|
+
const bar = "█".repeat(barLen);
|
|
622
|
+
let icon = "✅";
|
|
623
|
+
if (["GPL", "AGPL"].some((r) => license.includes(r))) icon = "⚖️ ";
|
|
624
|
+
if (license === "None/Unknown") icon = "❓";
|
|
625
|
+
console.log(`${icon} ${license.padEnd(60)} | ${bar} (${count})`);
|
|
626
|
+
});
|
|
627
|
+
console.log("");
|
|
628
|
+
this.displayPrompt();
|
|
629
|
+
},
|
|
630
|
+
});
|
|
631
|
+
cdxgenRepl.defineCommand("inspect", {
|
|
632
|
+
help: "view full JSON details of a component: .inspect <name_search_string>",
|
|
633
|
+
async action(nameStr) {
|
|
634
|
+
if (sbom?.components) {
|
|
635
|
+
const found = sbom.components.find(
|
|
636
|
+
(c) =>
|
|
637
|
+
c.name.toLowerCase().includes(nameStr.toLowerCase()) ||
|
|
638
|
+
c.purl?.includes(nameStr),
|
|
639
|
+
);
|
|
640
|
+
if (found) {
|
|
641
|
+
console.log(JSON.stringify(found, null, 2));
|
|
642
|
+
} else {
|
|
643
|
+
console.log("❌ Component not found.");
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
this.displayPrompt();
|
|
647
|
+
},
|
|
648
|
+
});
|
|
649
|
+
cdxgenRepl.defineCommand("tagcloud", {
|
|
650
|
+
help: "generate a text/tag cloud based on component descriptions and tags",
|
|
651
|
+
action() {
|
|
652
|
+
if (!sbom || !sbom.components) {
|
|
653
|
+
console.log("⚠ No SBOM loaded.");
|
|
654
|
+
this.displayPrompt();
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
const stopWords = new Set([
|
|
658
|
+
"the",
|
|
659
|
+
"and",
|
|
660
|
+
"for",
|
|
661
|
+
"with",
|
|
662
|
+
"that",
|
|
663
|
+
"this",
|
|
664
|
+
"from",
|
|
665
|
+
"are",
|
|
666
|
+
"can",
|
|
667
|
+
"use",
|
|
668
|
+
"library",
|
|
669
|
+
"framework",
|
|
670
|
+
"package",
|
|
671
|
+
"component",
|
|
672
|
+
"module",
|
|
673
|
+
"application",
|
|
674
|
+
"software",
|
|
675
|
+
"tool",
|
|
676
|
+
"version",
|
|
677
|
+
"implementation",
|
|
678
|
+
"support",
|
|
679
|
+
"based",
|
|
680
|
+
"provided",
|
|
681
|
+
"provides",
|
|
682
|
+
"using",
|
|
683
|
+
"api",
|
|
684
|
+
"interface",
|
|
685
|
+
"data",
|
|
686
|
+
"system",
|
|
687
|
+
"http",
|
|
688
|
+
"https",
|
|
689
|
+
"com",
|
|
690
|
+
"org",
|
|
691
|
+
"net",
|
|
692
|
+
"git",
|
|
693
|
+
"source",
|
|
694
|
+
"code",
|
|
695
|
+
"file",
|
|
696
|
+
"project",
|
|
697
|
+
"open",
|
|
698
|
+
"free",
|
|
699
|
+
"web",
|
|
700
|
+
"runtime",
|
|
701
|
+
"client",
|
|
702
|
+
"server",
|
|
703
|
+
"utils",
|
|
704
|
+
]);
|
|
705
|
+
const wordCounts = new Map();
|
|
706
|
+
const addWord = (w) => {
|
|
707
|
+
if (!w) return;
|
|
708
|
+
const clean = w.toLowerCase().replace(/[^a-z0-9-]/g, "");
|
|
709
|
+
if (clean.length > 2 && !stopWords.has(clean) && Number.isNaN(clean)) {
|
|
710
|
+
wordCounts.set(clean, (wordCounts.get(clean) || 0) + 1);
|
|
711
|
+
}
|
|
712
|
+
};
|
|
713
|
+
sbom.components.forEach((c) => {
|
|
714
|
+
if (c.tags) {
|
|
715
|
+
c.tags.forEach((t) => {
|
|
716
|
+
addWord(t);
|
|
717
|
+
addWord(t);
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
if (c.description) {
|
|
721
|
+
c.description.split(/\s+/).forEach(addWord);
|
|
722
|
+
}
|
|
723
|
+
if (c.group) {
|
|
724
|
+
addWord(c.group);
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
if (wordCounts.size === 0) {
|
|
728
|
+
console.log("⚠ Not enough text data found in Description or Tags.");
|
|
729
|
+
this.displayPrompt();
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
let sortedWords = Array.from(wordCounts.entries()).sort(
|
|
733
|
+
(a, b) => b[1] - a[1],
|
|
734
|
+
);
|
|
735
|
+
sortedWords = sortedWords.slice(0, 100);
|
|
736
|
+
const maxCount = sortedWords[0][1];
|
|
737
|
+
const minCount = sortedWords[sortedWords.length - 1][1];
|
|
738
|
+
const styles = {
|
|
739
|
+
tier1: (str) => `\x1b[1;35m${str.toUpperCase()}\x1b[0m`,
|
|
740
|
+
tier2: (str) => `\x1b[1;36m${str}\x1b[0m`,
|
|
741
|
+
tier3: (str) => `\x1b[32m${str}\x1b[0m`,
|
|
742
|
+
tier4: (str) => `\x1b[2m${str}\x1b[0m`,
|
|
743
|
+
};
|
|
744
|
+
const cloudNodes = sortedWords.map(([word, count]) => {
|
|
745
|
+
const score = (count - minCount) / (maxCount - minCount || 1);
|
|
746
|
+
let styledWord = "";
|
|
747
|
+
if (score > 0.7) styledWord = styles.tier1(word);
|
|
748
|
+
else if (score > 0.4) styledWord = styles.tier2(word);
|
|
749
|
+
else if (score > 0.1) styledWord = styles.tier3(word);
|
|
750
|
+
else styledWord = styles.tier4(word);
|
|
751
|
+
return styledWord;
|
|
752
|
+
});
|
|
753
|
+
for (let i = cloudNodes.length - 1; i > 0; i--) {
|
|
754
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
755
|
+
[cloudNodes[i], cloudNodes[j]] = [cloudNodes[j], cloudNodes[i]];
|
|
756
|
+
}
|
|
757
|
+
console.log("\n☁️ Word Cloud\n");
|
|
758
|
+
const terminalWidth = process.stdout.columns || 80;
|
|
759
|
+
let currentLine = "";
|
|
760
|
+
cloudNodes.forEach((node) => {
|
|
761
|
+
const visualLength = node.replace(/[[0-9;]*m/g, "").length + 1;
|
|
762
|
+
if (currentLine.length + visualLength > terminalWidth) {
|
|
763
|
+
console.log(currentLine);
|
|
764
|
+
currentLine = "";
|
|
765
|
+
}
|
|
766
|
+
currentLine += `${node} `;
|
|
767
|
+
});
|
|
768
|
+
console.log(currentLine);
|
|
769
|
+
console.log("\n");
|
|
770
|
+
this.displayPrompt();
|
|
771
|
+
},
|
|
772
|
+
});
|
|
578
773
|
// Let's dynamically define more commands from the queries
|
|
579
774
|
[
|
|
580
775
|
"apt_sources",
|
package/bin/verify.js
CHANGED
|
@@ -8,7 +8,11 @@ import jws from "jws";
|
|
|
8
8
|
import yargs from "yargs";
|
|
9
9
|
import { hideBin } from "yargs/helpers";
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
dirNameStr,
|
|
13
|
+
retrieveCdxgenVersion,
|
|
14
|
+
safeExistsSync,
|
|
15
|
+
} from "../lib/helpers/utils.js";
|
|
12
16
|
import { getBomWithOras } from "../lib/managers/oci.js";
|
|
13
17
|
|
|
14
18
|
const dirName = dirNameStr;
|
|
@@ -29,7 +33,7 @@ const args = _yargs
|
|
|
29
33
|
description: "Public key in PEM format. Default public.key",
|
|
30
34
|
})
|
|
31
35
|
.completion("completion", "Generate bash/zsh completion")
|
|
32
|
-
.epilogue("for documentation, visit https://
|
|
36
|
+
.epilogue("for documentation, visit https://cdxgen.github.io/cdxgen")
|
|
33
37
|
.scriptName("cdx-verify")
|
|
34
38
|
.version(retrieveCdxgenVersion())
|
|
35
39
|
.help(false)
|
|
@@ -74,12 +78,15 @@ function getBom(args) {
|
|
|
74
78
|
}
|
|
75
79
|
return undefined;
|
|
76
80
|
}
|
|
77
|
-
|
|
78
81
|
const bomJson = getBom(args);
|
|
79
82
|
if (!bomJson) {
|
|
80
83
|
console.log(`${args.input} is invalid!`);
|
|
81
84
|
process.exit(1);
|
|
82
85
|
}
|
|
86
|
+
if (bomJson && !safeExistsSync(args.publicKey)) {
|
|
87
|
+
console.log("Public key for signature verification is missing!");
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
83
90
|
let hasInvalidComp = false;
|
|
84
91
|
// Validate any component signature
|
|
85
92
|
for (const comp of bomJson.components) {
|
package/data/README.md
CHANGED
|
@@ -2,26 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
Contents of data directory and their purpose.
|
|
4
4
|
|
|
5
|
-
| Filename
|
|
6
|
-
|
|
|
7
|
-
| bom-1.4.schema.json
|
|
8
|
-
| bom-1.5.schema.json
|
|
9
|
-
| cosdb-queries.json
|
|
10
|
-
| cbomosdb-queries.json
|
|
11
|
-
| jsf-0.82.schema.json
|
|
12
|
-
| known-licenses.json
|
|
13
|
-
| lic-mapping.json
|
|
14
|
-
| pypi-pkg-aliases.json
|
|
15
|
-
| python-stdlib.json
|
|
16
|
-
| queries-win.json
|
|
17
|
-
| queries.json
|
|
18
|
-
| queries-darwin.json
|
|
19
|
-
| spdx-licenses.json
|
|
20
|
-
| spdx.schema.json
|
|
21
|
-
| vendor-alias.json
|
|
22
|
-
| wrapdb-releases.json
|
|
23
|
-
| frameworks-list.json
|
|
24
|
-
| crypto-oid.json
|
|
25
|
-
| glibc-stdlib.json
|
|
26
|
-
| component-tags.json
|
|
27
|
-
| ruby-known-modules.json | Module names for certain known gems. Example: rails
|
|
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 |
|
|
25
|
+
| glibc-stdlib.json | Standard libraries that can be filtered out in C++ |
|
|
26
|
+
| component-tags.json | List of tags to extract from component description text for easy classification. |
|
|
27
|
+
| ruby-known-modules.json | Module names for certain known gems. Example: rails |
|