@cyclonedx/cdxgen 10.5.0 → 10.5.2

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
@@ -1,10 +1,14 @@
1
- [![JSR](https://img.shields.io/jsr/v/%40cyclonedx/cdxgen)](https://jsr.io/@cyclonedx/cdxgen) [![NPM](https://img.shields.io/npm/v/%40cyclonedx%2Fcdxgen)](https://www.npmjs.com/package/@cyclonedx/cdxgen) [![GitHub Releases](https://img.shields.io/github/v/release/cyclonedx/cdxgen)](https://github.com/CycloneDX/cdxgen/releases) [![NPM Downloads](https://img.shields.io/npm/dy/%40cyclonedx%2Fcdxgen)](<(https://www.npmjs.com/package/@cyclonedx/cdxgen)>) [![GitHub License](https://img.shields.io/github/license/cyclonedx/cdxgen)](./LICENSE.md) [![GitHub Contributors](https://img.shields.io/github/contributors/cyclonedx/cdxgen)](https://github.com/CycloneDX/cdxgen/graphs/contributors)
1
+ [![JSR][badge-jsr]][jsr-cdxgen]
2
+ [![NPM][badge-npm]][npmjs-cdxgen]
3
+ [![GitHub Releases][badge-github-releases]][github-releases]
4
+ [![NPM Downloads][badge-npm-downloads]][npmjs-cdxgen]
5
+ [![GitHub License][badge-github-license]][github-license]
6
+ [![GitHub Contributors][badge-github-contributors]][github-contributors]
7
+ [![SWH][badge-swh]][swh-cdxgen]
2
8
 
3
- [![SWH](https://archive.softwareheritage.org/badge/origin/https://github.com/CycloneDX/cdxgen/)](https://archive.softwareheritage.org/browse/origin/?origin_url=https://github.com/CycloneDX/cdxgen)
9
+ # CycloneDX Generator (cdxgen)
4
10
 
5
- # CycloneDX Generator
6
-
7
- ![cdxgen logo](cdxgen.png)
11
+ ![cdxgen logo](./docs/_media/cdxgen.png)
8
12
 
9
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 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.
10
14
 
@@ -17,70 +21,28 @@ When used with plugins:
17
21
 
18
22
  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!
19
23
 
20
- <img src="./docs/why-cdxgen.jpg" alt="why cdxgen" width="256">
21
-
22
- ## Supported languages and package format
23
-
24
- | Language/Platform | Package format | Transitive dependencies | Evidence |
25
- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | -------- |
26
- | Node.js | npm-shrinkwrap.json, package-lock.json, pnpm-lock.yaml, yarn.lock, rush.js, bower.json, .min.js | Yes except .min.js | Yes |
27
- | Java | maven (pom.xml [1]), gradle (build.gradle, .kts), scala (sbt), bazel | Yes unless pom.xml is manually parsed due to unavailability of maven or errors | Yes |
28
- | Android | apk, aab | |
29
- | PHP | composer.lock | Yes | Yes |
30
- | Python | pyproject.toml, setup.py, requirements.txt [2], Pipfile.lock, poetry.lock, pdm.lock, bdist_wheel, .whl, .egg-info | Yes using the automatic pip install/freeze. When disabled, only with Pipfile.lock and poetry.lock | Yes |
31
- | Go | binary, go.mod, go.sum, Gopkg.lock | Yes except binary | Yes |
32
- | Ruby | Gemfile.lock, gemspec | Only for Gemfile.lock | |
33
- | Rust | binary, Cargo.toml, Cargo.lock | Only for Cargo.lock | |
34
- | .Net | .csproj, .vbproj, .fsproj, packages.config, project.assets.json [3], packages.lock.json, .nupkg, paket.lock, binary | Only for project.assets.json, packages.lock.json, paket.lock | |
35
- | Dart | pubspec.lock, pubspec.yaml | Only for pubspec.lock | |
36
- | Haskell | cabal.project.freeze | Yes | |
37
- | Elixir | mix.lock | Yes | |
38
- | C/C++/Objective C/C++11 | conan.lock, conanfile.txt, \*.cmake, CMakeLists.txt, meson.build, codebase without package managers! | Yes only for conan.lock. Best effort basis for cmake without version numbers. | Yes |
39
- | Clojure | Clojure CLI (deps.edn), Leiningen (project.clj) | Yes unless the files are parsed manually due to lack of clojure cli or leiningen command | |
40
- | Swift | Package.resolved, Package.swift (swiftpm) | Yes | |
41
- | Docker / oci image | All supported languages. Linux OS packages with plugins [4] | Best effort based on lock files | Yes |
42
- | GitHub Actions | .github/workflows/\*.yml | N/A | Yes |
43
- | Linux | All supported languages. Linux OS packages with plugins [5] | Best effort based on lock files | Yes |
44
- | Windows | All supported languages. OS packages with best effort [5] | Best effort based on lock files | Yes |
45
- | Jenkins Plugins | .hpi files | | Yes |
46
- | Helm Charts | .yaml | N/A | |
47
- | Skaffold | .yaml | N/A | |
48
- | kustomization | .yaml | N/A | |
49
- | Tekton tasks | .yaml | N/A | |
50
- | Kubernetes | .yaml | N/A | |
51
- | Maven Cache | $HOME/.m2/repository/\*\*/\*.jar | N/A | |
52
- | SBT Cache | $HOME/.ivy2/cache/\*\*/\*.jar | N/A | |
53
- | Gradle Cache | $HOME/caches/modules-2/files-2.1/\*\*/\*.jar | N/A | |
54
- | Helm Index | $HOME/.cache/helm/repository/\*\*/\*.yaml | N/A | |
55
- | Docker compose | docker-compose\*.yml. Images would also be scanned. | N/A | |
56
- | Dockerfile | `*Dockerfile*` Images would also be scanned. | N/A | |
57
- | Containerfile | `*Containerfile*`. Images would also be scanned. | N/A | |
58
- | Bitbucket Pipelines | `bitbucket-pipelines.yml` images and pipes would also be scanned. | N/A | |
59
- | Google CloudBuild configuration | cloudbuild.yaml | N/A | |
60
- | OpenAPI | openapi\*.json, openapi\*.yaml | N/A | |
61
-
62
- NOTE:
63
-
64
- - Apache maven 3.x is required for parsing pom.xml
65
- - gradle or gradlew is required to parse gradle projects
66
- - sbt is required for parsing scala sbt projects. Only scala 2.10 + sbt 0.13.6+ and 2.12 + sbt 1.0+ are currently supported.
67
- - Alternatively, create a lock file using sbt-dependency-lock [plugin](https://github.com/stringbean/sbt-dependency-lock)
68
-
69
- Footnotes:
70
-
71
- - [1] - For multi-module applications, the BOM file could include components not included in the packaged war or ear file.
72
- - [2] - Pip freeze is automatically performed to improve precision. Requires virtual environment.
73
- - [3] - Perform dotnet or nuget restore to generate project.assets.json. Without this file, cdxgen would not include indirect dependencies.
74
- - [4] - See the section on plugins
75
- - [5] - Powered by osquery. See the section on plugins
76
-
77
- <img src="./docs/cdxgen-tree.jpg" alt="cdxgen tree" width="256">
24
+ <img src="./docs/_media/why-cdxgen.jpg" alt="why cdxgen" width="256">
25
+
26
+ ## Documentation
27
+
28
+ Please visit our [documentation site][docs-homepage] for detailed usage, tutorials and support documentation.
29
+
30
+ Sections include:
31
+ - [Getting Started][docs-homepage]
32
+ - [CLI Usage][docs-cli]
33
+ - [Server Usage][docs-server]
34
+ - [Supported Project Types][docs-project-types]
35
+ - [Environment Variables][docs-env-vars]
36
+ - [Advanced Usage][docs-advanced-usage]
37
+ - [Permissions][docs-permissions]
38
+ - [Support (Enterprise & Community)][docs-support]
39
+
78
40
 
79
41
  ### Automatic usage detection
80
42
 
81
43
  For node.js projects, lock files are parsed initially, so the SBOM would include all dependencies, including dev ones. An AST parser powered by babel-parser is then used to detect packages that are imported and used by non-test code. Such imported packages would automatically set their scope property to `required` in the resulting SBOM. You can turn off this analysis by passing the argument `--no-babel`. Scope property would then be set based on the `dev` attribute in the lock file.
82
44
 
83
- This attribute can be later used for various purposes. For example, [dep-scan](https://github.com/cyclonedx/dep-scan) uses this attribute to prioritize vulnerabilities. Unfortunately, tools such as dependency track, do not include this feature and might over-report the CVEs.
45
+ This attribute can be later used for various purposes. For example, [dep-scan][depscan-github] uses this attribute to prioritize vulnerabilities. Unfortunately, tools such as dependency track, do not include this feature and might over-report the CVEs.
84
46
 
85
47
  With the argument `--required-only`, you can limit the SBOM only to include packages with the scope "required", commonly called production or non-dev dependencies. Combine with `--no-babel` to limit this list to only non-dev dependencies based on the `dev` attribute being false in the lock files.
86
48
 
@@ -94,7 +56,7 @@ For go, `go mod why` command is used to identify required packages. For php, com
94
56
  npm install -g @cyclonedx/cdxgen
95
57
  ```
96
58
 
97
- If you are a [Homebrew](https://brew.sh/) user, you can also install [cdxgen](https://formulae.brew.sh/formula/cdxgen) via:
59
+ If you are a [Homebrew][homebrew-homepage] user, you can also install [cdxgen][homebrew-cdxgen] via:
98
60
 
99
61
  ```shell
100
62
  $ brew install cdxgen
@@ -103,7 +65,7 @@ $ brew install cdxgen
103
65
  Deno and bun runtime can be used with limited support.
104
66
 
105
67
  ```shell
106
- deno install --allow-read --allow-env --allow-run --allow-sys=uid,systemMemoryInfo,gid --allow-write --allow-net -n cdxgen "npm:@cyclonedx/cdxgen/cdxgen"
68
+ deno install --allow-read --allow-env --allow-run --allow-sys=uid,systemMemoryInfo,gid,homedir --allow-write --allow-net -n cdxgen "npm:@cyclonedx/cdxgen/cdxgen"
107
69
  ```
108
70
 
109
71
  You can also use the cdxgen container image with node, deno, or bun runtime versions.
@@ -139,7 +101,9 @@ $ cdxgen -h
139
101
  Options:
140
102
  -o, --output Output file. Default bom.json
141
103
  [default: "bom.json"]
142
- -t, --type Project type
104
+ -t, --type Project type. Please refer to https://cyclonedx.g
105
+ ithub.io/cdxgen/#/PROJECT_TYPES for supported lan
106
+ guages/platforms.
143
107
  -r, --recurse Recurse mode suitable for mono-repos. Defaults to
144
108
  true. Pass --no-recurse to disable.
145
109
  [boolean] [default: true]
@@ -290,7 +254,7 @@ Arguments can be passed either via the query string or as a JSON body. The follo
290
254
 
291
255
  | Argument | Description |
292
256
  | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
293
- | type | Project type |
257
+ | type | Project type. Please refer to [Supported Project Types][docs-project-types]. |
294
258
  | multiProject | [boolean] |
295
259
  | requiredOnly | Include only the packages with required scope on the SBOM. [boolean] |
296
260
  | noBabel | Do not use babel to perform usage analysis for JavaScript/TypeScript projects. [boolean] |
@@ -361,7 +325,7 @@ This would create a bom.json.map file with the jar - class name mapping. Refer t
361
325
 
362
326
  ## Resolving licenses
363
327
 
364
- cdxgen can automatically query public registries such as maven, npm, or nuget to resolve the package licenses. This is a time-consuming operation and is disabled by default. To enable, set the environment variable `FETCH_LICENSE` to `true`, as shown. Ensure that `GITHUB_TOKEN` is set or provided by [built-in GITHUB_TOKEN in GitHub Actions](https://docs.github.com/en/rest/overview/rate-limits-for-the-rest-api#primary-rate-limit-for-github_token-in-github-actions), otherwise rate limiting might prevent license resolving.
328
+ cdxgen can automatically query public registries such as maven, npm, or nuget to resolve the package licenses. This is a time-consuming operation and is disabled by default. To enable, set the environment variable `FETCH_LICENSE` to `true`, as shown. Ensure that `GITHUB_TOKEN` is set or provided by [built-in GITHUB_TOKEN in GitHub Actions][github-rate-limit], otherwise rate limiting might prevent license resolving.
365
329
 
366
330
  ```bash
367
331
  export FETCH_LICENSE=true
@@ -384,47 +348,6 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
384
348
  - Ruby (Gemfile.lock)
385
349
  - Rust (Cargo.lock)
386
350
 
387
- ## Environment variables
388
-
389
- | Variable | Description |
390
- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
391
- | CDXGEN_DEBUG_MODE | Set to `debug` to enable debug messages |
392
- | GITHUB_TOKEN | Specify GitHub token to prevent traffic shaping while querying license and repo information |
393
- | MVN_CMD | Set to override maven command |
394
- | MVN_ARGS | Set to pass additional arguments such as profile or settings to maven |
395
- | MAVEN_HOME | Specify maven home |
396
- | MAVEN_CENTRAL_URL | Specify URL of Maven Central for metadata fetching (e.g. when private repo is used) |
397
- | ANDROID_MAVEN_URL | Specify URL of Android Maven Repository for metadata fetching (e.g. when private repo is used) |
398
- | BAZEL_TARGET | Bazel target to build. Default :all (Eg: //java-maven) |
399
- | BAZEL_STRIP_MAVEN_PREFIX | Strip Maven group prefix (e.g. useful when private repo is used, defaults to `/maven2/`) |
400
- | BAZEL_USE_ACTION_GRAPH | SBOM for specific Bazel target, uses `bazel aquery 'outputs(".*.jar", deps(<BAZEL_TARGET>))'` (defaults to `false`) |
401
- | GRADLE_CACHE_DIR | Specify gradle cache directory. Useful for class name resolving |
402
- | GRADLE_MULTI_PROJECT_MODE | Unused. Automatically handled |
403
- | GRADLE_ARGS | Set to pass additional arguments such as profile or settings to gradle (all tasks). Eg: --configuration runtimeClassPath |
404
- | GRADLE_ARGS_PROPERTIES | Set to pass additional arguments only to the `gradle properties` task, used for collecting metadata about the project |
405
- | GRADLE_ARGS_DEPENDENCIES | Set to pass additional arguments only to the `gradle dependencies` task, used for listing actual project dependencies |
406
- | GRADLE_HOME | Specify gradle home |
407
- | GRADLE_CMD | Set to override gradle command |
408
- | GRADLE_DEPENDENCY_TASK | By default cdxgen use the task "dependencies" to collect packages. Set to override the task name. |
409
- | SBT_CACHE_DIR | Specify sbt cache directory. Useful for class name resolving |
410
- | FETCH_LICENSE | Set this variable to `true` or `1` to fetch license information from the registry. npm and golang |
411
- | SEARCH_MAVEN_ORG | If maven metadata is missing in jar file, a search is performed on search.maven.org. Set to `false` or `0` to disable search. |
412
- | USE_GOSUM | Set to `true` or `1` to generate BOMs for golang projects using go.sum as the dependency source of truth, instead of go.mod |
413
- | CDXGEN_TIMEOUT_MS | Default timeout for known execution involving maven, gradle or sbt |
414
- | CDXGEN_SERVER_TIMEOUT_MS | Default timeout in server mode |
415
- | CDXGEN_MAX_BUFFER | Max buffer for stdout and stderr. Defaults to 100MB |
416
- | CLJ_CMD | Set to override the clojure cli command |
417
- | LEIN_CMD | Set to override the leiningen command |
418
- | SBOM_SIGN_ALGORITHM | Signature algorithm. Some valid values are RS256, RS384, RS512, PS256, PS384, PS512, ES256 etc |
419
- | SBOM_SIGN_PRIVATE_KEY | Private key to use for signing |
420
- | SBOM_SIGN_PUBLIC_KEY | Optional. Public key to include in the SBOM signature |
421
- | CDX_MAVEN_PLUGIN | CycloneDX Maven plugin to use. Default "org.cyclonedx:cyclonedx-maven-plugin:2.7.11" |
422
- | CDX_MAVEN_GOAL | CycloneDX Maven plugin goal to use. Default makeAggregateBom. Other options: makeBom, makePackageBom |
423
- | CDX_MAVEN_INCLUDE_TEST_SCOPE | Whether test scoped dependencies should be included from Maven projects, Default: true |
424
- | ASTGEN_IGNORE_DIRS | Comma separated list of directories to ignore while analyzing using babel. The environment variable is also used by atom and astgen. |
425
- | ASTGEN_IGNORE_FILE_PATTERN | Ignore regex to use |
426
- | PYPI_URL | Override pypi url. Default: https://pypi.org/pypi/ |
427
-
428
351
  ## Plugins
429
352
 
430
353
  cdxgen could be extended with external binary plugins to support more SBOM use cases. These are now installed as an optional dependency.
@@ -458,7 +381,7 @@ cdxgen /tmp/slim.tar -o /tmp/bom.json -t docker
458
381
 
459
382
  ### Podman in rootless mode
460
383
 
461
- Setup podman in either [rootless](https://github.com/containers/podman/blob/master/docs/tutorials/rootless_tutorial.md) or [remote](https://github.com/containers/podman/blob/master/docs/tutorials/mac_win_client.md) mode
384
+ Setup podman in either [rootless][podman-github-rootless] or [remote][podman-github-remote] mode
462
385
 
463
386
  Do not forget to start the podman socket required for API access on Linux.
464
387
 
@@ -478,7 +401,7 @@ obom
478
401
  # cdxgen -t os
479
402
  ```
480
403
 
481
- 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.
404
+ 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](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.
482
405
 
483
406
  ## Generate Cryptography Bill of Materials (CBOM)
484
407
 
@@ -501,9 +424,9 @@ cdxgen can sign the generated BOM json file to increase authenticity and non-rep
501
424
  - SBOM_SIGN_PRIVATE_KEY: Location to the RSA private key
502
425
  - SBOM_SIGN_PUBLIC_KEY: Optional. Location to the RSA public key
503
426
 
504
- To generate test public/private key pairs, you can run cdxgen by passing the argument `--generate-key-and-sign`. The generated json file would have an attribute called `signature`, which could be used for validation. [jwt.io](https://jwt.io) is a known site that could be used for such signature validation.
427
+ To generate test public/private key pairs, you can run cdxgen by passing the argument `--generate-key-and-sign`. The generated json file would have an attribute called `signature`, which could be used for validation. [jwt.io][jwt-homepage] is a known site that could be used for such signature validation.
505
428
 
506
- ![SBOM signing](sbom-sign.jpg)
429
+ ![SBOM signing](./docs/_media/sbom-sign.jpg)
507
430
 
508
431
  ### Verifying the signature
509
432
 
@@ -516,7 +439,7 @@ cdx-verify -i bom.json --public-key public.key
516
439
 
517
440
  ### Custom verification tool (Node.js example)
518
441
 
519
- There are many [libraries](https://jwt.io/#libraries-io) available to validate JSON Web Tokens. Below is a javascript example.
442
+ There are many [libraries][jwt-libraries] available to validate JSON Web Tokens. Below is a javascript example.
520
443
 
521
444
  ```js
522
445
  # npm install jws
@@ -543,14 +466,13 @@ cdxgen can automatically detect names of services from YAML manifests such as do
543
466
 
544
467
  ## Conversion to SPDX format
545
468
 
546
- Use the [CycloneDX CLI](https://github.com/CycloneDX/cyclonedx-cli) tool for advanced use cases such as conversion, diff and merging.
469
+ Use the [CycloneDX CLI][cyclonedx-cli-github] tool for advanced use cases such as conversion, diff and merging.
547
470
 
548
471
  ## License
549
472
 
550
- Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE](LICENSE) file for the full license.
473
+ Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE][github-license] file for the full license.
474
+
551
475
 
552
- [license]: https://github.com/cyclonedx/cdxgen/blob/master/LICENSE
553
- [cyclonedx-homepage]: https://cyclonedx.org
554
476
 
555
477
  ## Integration as library
556
478
 
@@ -572,13 +494,12 @@ const bomNSData = await createBom(filePath, options);
572
494
  const dbody = await submitBom(args, bomNSData.bomJson);
573
495
  ```
574
496
 
575
- ## Node.js >= 20 permission model
497
+ ## Contributing
576
498
 
577
- Refer to the [permissions document](./docs/PERMISSIONS.md)
499
+ Please check out our [contribute to CycloneDX/cdxgen documentation][github-contribute] if you are interested in helping.
578
500
 
579
- ## Contributing
580
501
 
581
- Follow the usual PR process, but before raising a PR, run the following commands.
502
+ Before raising a PR, please run the following commands.
582
503
 
583
504
  ```bash
584
505
  # Generate types using jsdoc syntax
@@ -589,8 +510,46 @@ npm run lint
589
510
  npm test
590
511
  ```
591
512
 
592
- If you are completely new to contributing to open-source projects, then look for [issues](https://github.com/CycloneDX/cdxgen/issues) with the labels "good first issue" or "help wanted".
593
-
594
- ## Enterprise support
595
513
 
596
- Enterprise support, including custom development and integration services, is available via [AppThreat Ltd](https://www.appthreat.com). Free community support is also available via [Discord](https://discord.gg/tmmtjCEHNV).
514
+ <!-- LINK LABELS -->
515
+ <!-- Badges -->
516
+ [badge-github-contributors]: https://img.shields.io/github/contributors/cyclonedx/cdxgen
517
+ [badge-github-license]: https://img.shields.io/github/license/cyclonedx/cdxgen
518
+ [badge-github-releases]: https://img.shields.io/github/v/release/cyclonedx/cdxgen
519
+ [badge-jsr]: https://img.shields.io/jsr/v/%40cyclonedx/cdxgen
520
+ [badge-npm]: https://img.shields.io/npm/v/%40cyclonedx%2Fcdxgen
521
+ [badge-npm-downloads]: https://img.shields.io/npm/dy/%40cyclonedx%2Fcdxgen
522
+ [badge-swh]: https://archive.softwareheritage.org/badge/origin/https://github.com/CycloneDX/cdxgen/
523
+
524
+ <!-- cdxgen github project -->
525
+ [github-contribute]: https://github.com/CycloneDX/cdxgen/contribute
526
+ [github-contributors]: https://github.com/CycloneDX/cdxgen/graphs/contributors
527
+ [github-issues]: https://github.com/CycloneDX/cdxgen/issues
528
+ [github-license]: https://github.com/cyclonedx/cdxgen/blob/master/LICENSE
529
+ [github-releases]: https://github.com/CycloneDX/cdxgen/releases
530
+
531
+ <!-- cdxgen documentation site -->
532
+ [docs-homepage]: https://cyclonedx.github.io/cdxgen
533
+ [docs-advanced-usage]: https://cyclonedx.github.io/cdxgen/#/ADVANCED
534
+ [docs-cli]: https://cyclonedx.github.io/cdxgen/#/CLI
535
+ [docs-env-vars]: https://cyclonedx.github.io/cdxgen/#/ENV
536
+ [docs-permissions]: https://cyclonedx.github.io/cdxgen/#/PERMISSIONS
537
+ [docs-project-types]: https://cyclonedx.github.io/cdxgen/#/PROJECT_TYPES
538
+ [docs-server]: https://cyclonedx.github.io/cdxgen/#/SERVER
539
+ [docs-support]: https://cyclonedx.github.io/cdxgen/#/PROJECT_TYPES
540
+
541
+ <!-- web links-->
542
+ [appthreat-homepage]: https://www.appthreat.com
543
+ [cyclonedx-homepage]: https://cyclonedx.org
544
+ [cyclonedx-cli-github]: https://github.com/CycloneDX/cyclonedx-cli
545
+ [depscan-github]: https://github.com/cyclonedx/dep-scan
546
+ [github-rate-limit]: https://docs.github.com/en/rest/overview/rate-limits-for-the-rest-api#primary-rate-limit-for-github_token-in-github-actions
547
+ [homebrew-homepage]: https://brew.sh
548
+ [homebrew-cdxgen]: https://formulae.brew.sh/formula/cdxgen
549
+ [jsr-cdxgen]: https://jsr.io/@cyclonedx/cdxgen
550
+ [jwt-homepage]: https://jwt.io
551
+ [jwt-libraries]: https://jwt.io/libraries
552
+ [npmjs-cdxgen]: https://www.npmjs.com/package/@cyclonedx/cdxgen
553
+ [podman-github-rootless]: https://github.com/containers/podman/blob/master/docs/tutorials/rootless_tutorial.md
554
+ [podman-github-remote]: https://github.com/containers/podman/blob/master/docs/tutorials/mac_win_client.md
555
+ [swh-cdxgen]: https://archive.softwareheritage.org/browse/origin/?origin_url=https://github.com/CycloneDX/cdxgen
package/bin/cdxgen.js CHANGED
@@ -67,7 +67,8 @@ const args = yargs(hideBin(process.argv))
67
67
  })
68
68
  .option("type", {
69
69
  alias: "t",
70
- description: "Project type",
70
+ description:
71
+ "Project type. Please refer to https://cyclonedx.github.io/cdxgen/#/PROJECT_TYPES for supported languages/platforms.",
71
72
  })
72
73
  .option("recurse", {
73
74
  alias: "r",
@@ -279,7 +280,8 @@ const args = yargs(hideBin(process.argv))
279
280
  .version()
280
281
  .alias("v", "version")
281
282
  .help("h")
282
- .alias("h", "help").argv;
283
+ .alias("h", "help")
284
+ .wrap(Math.min(120, yargs().terminalWidth())).argv;
283
285
 
284
286
  if (args.version) {
285
287
  const packageJsonAsString = fs.readFileSync(
package/bin/evinse.js CHANGED
@@ -136,7 +136,8 @@ const args = yargs(hideBin(process.argv))
136
136
  .config(config)
137
137
  .scriptName("evinse")
138
138
  .version()
139
- .help("h").argv;
139
+ .help("h")
140
+ .wrap(Math.min(120, yargs().terminalWidth())).argv;
140
141
 
141
142
  const evinseArt = `
142
143
  ███████╗██╗ ██╗██╗███╗ ██╗███████╗███████╗
package/bin/repl.js CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  printOccurrences,
15
15
  printServices,
16
16
  printTable,
17
+ printVulnerabilities,
17
18
  } from "../display.js";
18
19
  import { createBom } from "../index.js";
19
20
  import { validateBom } from "../validator.js";
@@ -61,9 +62,13 @@ export const importSbom = (sbomOrPath) => {
61
62
  if (sbomOrPath?.endsWith(".json") && fs.existsSync(sbomOrPath)) {
62
63
  try {
63
64
  sbom = JSON.parse(fs.readFileSync(sbomOrPath, "utf-8"));
64
- console.log(`✅ SBOM imported successfully from ${sbomOrPath}`);
65
+ let bomType = "SBOM";
66
+ if (sbom?.vulnerabilities && Array.isArray(sbom.vulnerabilities)) {
67
+ bomType = "VDR";
68
+ }
69
+ console.log(`✅ ${bomType} imported successfully from ${sbomOrPath}`);
65
70
  } catch (e) {
66
- console.log(`⚠ Unable to import the SBOM from ${sbomOrPath} due to ${e}`);
71
+ console.log(`⚠ Unable to import the BOM from ${sbomOrPath} due to ${e}`);
67
72
  }
68
73
  } else {
69
74
  console.log(`⚠ ${sbomOrPath} is invalid.`);
@@ -72,13 +77,13 @@ export const importSbom = (sbomOrPath) => {
72
77
  // Load any sbom passed from the command line
73
78
  if (process.argv.length > 2) {
74
79
  importSbom(process.argv[process.argv.length - 1]);
75
- console.log("💭 Type .print to view the SBOM as a table");
80
+ console.log("💭 Type .print to view the BOM as a table");
76
81
  } else if (fs.existsSync("bom.json")) {
77
82
  // If the current directory has a bom.json load it
78
83
  importSbom("bom.json");
79
84
  } else {
80
85
  console.log("💭 Use .create <path> to create an SBOM for the given path.");
81
- console.log("💭 Use .import <json> to import an existing SBOM.");
86
+ console.log("💭 Use .import <json> to import an existing BOM.");
82
87
  console.log("💭 Type .exit or press ctrl+d to close.");
83
88
  }
84
89
 
@@ -302,7 +307,7 @@ cdxgenRepl.defineCommand("validate", {
302
307
  if (sbom) {
303
308
  const result = validateBom(sbom);
304
309
  if (result) {
305
- console.log("SBOM is valid!");
310
+ console.log("BOM is valid!");
306
311
  }
307
312
  } else {
308
313
  console.log(
@@ -387,22 +392,6 @@ cdxgenRepl.defineCommand("occurrences", {
387
392
  this.displayPrompt();
388
393
  },
389
394
  });
390
- cdxgenRepl.defineCommand("discord", {
391
- help: "display the discord invite link for support",
392
- action() {
393
- console.log("Head to https://discord.gg/pF4BYWEJcS for support");
394
- this.displayPrompt();
395
- },
396
- });
397
- cdxgenRepl.defineCommand("sponsor", {
398
- help: "display the sponsorship link to fund this project",
399
- action() {
400
- console.log(
401
- "Hey, thanks a lot for considering! https://github.com/sponsors/prabhu",
402
- );
403
- this.displayPrompt();
404
- },
405
- });
406
395
  cdxgenRepl.defineCommand("callstack", {
407
396
  help: "view components with evidence.callstack",
408
397
  async action() {
@@ -442,7 +431,7 @@ cdxgenRepl.defineCommand("services", {
442
431
  let services = await expression.evaluate(sbom);
443
432
  if (!services) {
444
433
  console.log(
445
- "No services found. Use evinse command to generate an SBOM with evidence.",
434
+ "No services found. Use evinse command to generate a SaaSBOM with evidence.",
446
435
  );
447
436
  } else {
448
437
  if (!Array.isArray(services)) {
@@ -455,12 +444,38 @@ cdxgenRepl.defineCommand("services", {
455
444
  }
456
445
  } else {
457
446
  console.log(
458
- "⚠ No SBOM is loaded. Use .import command to import an evinse SBOM",
447
+ "⚠ No SaaSBOM is loaded. Use .import command to import a SaaSBOM",
459
448
  );
460
449
  }
461
450
  this.displayPrompt();
462
451
  },
463
452
  });
453
+ cdxgenRepl.defineCommand("vulnerabilities", {
454
+ help: "view vulnerabilities",
455
+ async action() {
456
+ if (sbom) {
457
+ try {
458
+ const expression = jsonata("vulnerabilities");
459
+ let vulnerabilities = await expression.evaluate(sbom);
460
+ if (!vulnerabilities) {
461
+ console.log(
462
+ "No vulnerabilities found. Use depscan to generate a VDR file with vulnerabilities.",
463
+ );
464
+ } else {
465
+ if (!Array.isArray(vulnerabilities)) {
466
+ vulnerabilities = [vulnerabilities];
467
+ }
468
+ printVulnerabilities(vulnerabilities);
469
+ }
470
+ } catch (e) {
471
+ console.log(e);
472
+ }
473
+ } else {
474
+ console.log("⚠ No BOM is loaded. Use .import command to import a VDR");
475
+ }
476
+ this.displayPrompt();
477
+ },
478
+ });
464
479
  cdxgenRepl.defineCommand("osinfocategories", {
465
480
  help: "view the category names for the OS info from the obom",
466
481
  async action() {
package/bin/verify.js CHANGED
@@ -28,7 +28,8 @@ const args = yargs(hideBin(process.argv))
28
28
  .epilogue("for documentation, visit https://cyclonedx.github.io/cdxgen")
29
29
  .scriptName("cdx-verify")
30
30
  .version()
31
- .help("h").argv;
31
+ .help("h")
32
+ .wrap(Math.min(120, yargs().terminalWidth())).argv;
32
33
 
33
34
  if (args.version) {
34
35
  const packageJsonAsString = fs.readFileSync(
package/binary.js CHANGED
@@ -192,14 +192,10 @@ if (existsSync(join(CDXGEN_PLUGINS_DIR, "osquery"))) {
192
192
  }
193
193
  let DOSAI_BIN = null;
194
194
  if (existsSync(join(CDXGEN_PLUGINS_DIR, "dosai"))) {
195
- let platformToUse = platform;
196
- if (platform === "darwin") {
197
- platformToUse = "osx";
198
- }
199
195
  DOSAI_BIN = join(
200
196
  CDXGEN_PLUGINS_DIR,
201
197
  "dosai",
202
- `dosai-${platformToUse}-${arch}${extn}`,
198
+ `dosai-${platform}-${arch}${extn}`,
203
199
  );
204
200
  } else if (process.env.DOSAI_CMD) {
205
201
  DOSAI_BIN = process.env.DOSAI_CMD;
@@ -421,7 +417,12 @@ export function getOSPackages(src) {
421
417
  if (DEBUG_MODE) {
422
418
  console.log(osReleaseData);
423
419
  }
424
- let distro_codename = osReleaseData["VERSION_CODENAME"] || "";
420
+ let distro_codename =
421
+ osReleaseData["VERSION_CODENAME"] ||
422
+ osReleaseData["CENTOS_MANTISBT_PROJECT"] ||
423
+ osReleaseData["REDHAT_SUPPORT_PRODUCT"] ||
424
+ "";
425
+ distro_codename = distro_codename.toLowerCase();
425
426
  let distro_id = osReleaseData["ID"] || "";
426
427
  const distro_id_like = osReleaseData["ID_LIKE"] || "";
427
428
  let purl_type = "rpm";
@@ -505,6 +506,8 @@ export function getOSPackages(src) {
505
506
  if (distro_codename?.length) {
506
507
  purlObj.qualifiers["distro_name"] = distro_codename;
507
508
  }
509
+ // Remove any epoch values
510
+ delete purlObj.qualifiers.epoch;
508
511
  // Bug fix for mageia and oracle linux
509
512
  // Type is being returned as none for ubuntu as well!
510
513
  if (purlObj.type === "none") {
@@ -573,6 +576,32 @@ export function getOSPackages(src) {
573
576
  // continue regardless of error
574
577
  }
575
578
  }
579
+ if (comp.purl.includes("epoch=")) {
580
+ try {
581
+ purlObj = PackageURL.fromString(comp.purl);
582
+ purlObj.qualifiers = purlObj.qualifiers || {};
583
+ if (distro_id?.length) {
584
+ purlObj.qualifiers["distro"] = distro_id;
585
+ }
586
+ if (distro_codename?.length) {
587
+ purlObj.qualifiers["distro_name"] = distro_codename;
588
+ }
589
+ delete purlObj.qualifiers.epoch;
590
+ allTypes.add(purlObj.namespace);
591
+ comp.purl = new PackageURL(
592
+ purlObj.type,
593
+ purlObj.namespace,
594
+ name,
595
+ purlObj.version,
596
+ purlObj.qualifiers,
597
+ purlObj.subpath,
598
+ ).toString();
599
+ comp["bom-ref"] = decodeURIComponent(comp.purl);
600
+ } catch (err) {
601
+ // continue regardless of error
602
+ console.log(err);
603
+ }
604
+ }
576
605
  // Fix licenses
577
606
  if (
578
607
  comp.licenses &&
@@ -685,6 +714,7 @@ const retrieveDependencies = (tmpDependencies, origBomRef, comp) => {
685
714
  if (compPurl.qualifiers.distro) {
686
715
  tmpPurl.qualifiers.distro = compPurl.qualifiers.distro;
687
716
  }
717
+ delete tmpPurl.qualifiers.epoch;
688
718
  }
689
719
  dependsOn.add(decodeURIComponent(tmpPurl.toString()));
690
720
  } catch (e) {
@@ -720,7 +750,11 @@ export function executeOsQuery(query) {
720
750
  timeout: 60 * 1000,
721
751
  });
722
752
  if (result.status !== 0 || result.error) {
723
- if (DEBUG_MODE && result.stderr) {
753
+ if (
754
+ DEBUG_MODE &&
755
+ result.stderr &&
756
+ !result.stderr.includes("no such table")
757
+ ) {
724
758
  console.error(result.stdout, result.stderr);
725
759
  }
726
760
  }