@cyclonedx/cdxgen 10.5.1 → 10.6.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 +107 -135
- package/analyzer.js +1 -1
- package/bin/cdxgen.js +4 -2
- package/bin/evinse.js +2 -1
- package/bin/repl.js +38 -23
- package/bin/verify.js +2 -1
- package/binary.js +6 -6
- package/data/spdx.schema.json +117 -1
- package/display.js +28 -0
- package/docker.js +21 -6
- package/index.js +558 -208
- package/package.json +36 -21
- package/types/analyzer.d.ts +4 -7
- package/types/binary.d.ts +8 -12
- package/types/binary.d.ts.map +1 -1
- package/types/cbomutils.d.ts +1 -1
- package/types/db.d.ts +9 -22
- package/types/display.d.ts +2 -1
- package/types/display.d.ts.map +1 -1
- package/types/docker.d.ts +33 -52
- package/types/docker.d.ts.map +1 -1
- package/types/envcontext.d.ts +40 -40
- package/types/evinser.d.ts +717 -3436
- package/types/index.d.ts +48 -67
- package/types/index.d.ts.map +1 -1
- package/types/jest.config.d.ts +2 -2
- package/types/piptree.d.ts +2 -6
- package/types/postgen.d.ts +1 -1
- package/types/protobom.d.ts +2 -6
- package/types/server.d.ts +1 -1
- package/types/utils.d.ts +353 -512
- package/types/utils.d.ts.map +1 -1
- package/types/validator.d.ts +1 -1
- package/utils.js +503 -68
- package/utils.test.js +281 -27
package/README.md
CHANGED
|
@@ -1,86 +1,59 @@
|
|
|
1
|
-
[![JSR]
|
|
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
|
-
|
|
9
|
+
# CycloneDX Generator (cdxgen)
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+

|
|
6
12
|
|
|
7
|
-
|
|
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.6.
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
Supported BOM formats:
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
17
|
+
- Software (SBOM) - For many languages and container images.
|
|
18
|
+
- Cryptography (CBOM) - For Java and Python projects.
|
|
19
|
+
- Operations (OBOM) - For Linux container images and VMs running Linux or Windows operating systems.
|
|
20
|
+
- Software-as-a-Service (SaaSBOM) - For Java, Python, JavaScript, TypeScript, and PHP projects.
|
|
21
|
+
- Attestations (CDXA) - Generate SBOM with templates for multiple standards. Sign the BOM document at a granular level to improve authenticity.
|
|
22
|
+
- Vulnerability Disclosure Report (VDR) - Use cdxgen with [OWASP depscan](https://github.com/owasp-dep-scan/dep-scan) to automate the generation of VDR at scale.
|
|
15
23
|
|
|
16
24
|
## Why cdxgen?
|
|
17
25
|
|
|
18
26
|
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
27
|
|
|
20
|
-
<img src="./docs/why-cdxgen.jpg" alt="why cdxgen" width="256">
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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">
|
|
28
|
+
<img src="./docs/_media/why-cdxgen.jpg" alt="why cdxgen" width="256">
|
|
29
|
+
|
|
30
|
+
Our philosophy:
|
|
31
|
+
|
|
32
|
+
- Explainability: Don't list, but explain with evidence.
|
|
33
|
+
- Precision: Try using multiple techniques to improve precision, even if it takes extra time.
|
|
34
|
+
- Personas: Cater to the needs of a range of personas such as security researchers, compliance auditors, developers, and SOC.
|
|
35
|
+
- Lifecycle: Support BOM generation for various product lifecycles.
|
|
36
|
+
|
|
37
|
+
## Documentation
|
|
38
|
+
|
|
39
|
+
Please visit our [documentation site][docs-homepage] for detailed usage, tutorials, and support documentation.
|
|
40
|
+
|
|
41
|
+
Sections include:
|
|
42
|
+
|
|
43
|
+
- [Getting Started][docs-homepage]
|
|
44
|
+
- [CLI Usage][docs-cli]
|
|
45
|
+
- [Server Usage][docs-server]
|
|
46
|
+
- [Supported Project Types][docs-project-types]
|
|
47
|
+
- [Environment Variables][docs-env-vars]
|
|
48
|
+
- [Advanced Usage][docs-advanced-usage]
|
|
49
|
+
- [Permissions][docs-permissions]
|
|
50
|
+
- [Support (Enterprise & Community)][docs-support]
|
|
78
51
|
|
|
79
52
|
### Automatic usage detection
|
|
80
53
|
|
|
81
54
|
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
55
|
|
|
83
|
-
This attribute can be later used for various purposes. For example, [dep-scan]
|
|
56
|
+
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
57
|
|
|
85
58
|
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
59
|
|
|
@@ -94,7 +67,7 @@ For go, `go mod why` command is used to identify required packages. For php, com
|
|
|
94
67
|
npm install -g @cyclonedx/cdxgen
|
|
95
68
|
```
|
|
96
69
|
|
|
97
|
-
If you are a [Homebrew]
|
|
70
|
+
If you are a [Homebrew][homebrew-homepage] user, you can also install [cdxgen][homebrew-cdxgen] via:
|
|
98
71
|
|
|
99
72
|
```shell
|
|
100
73
|
$ brew install cdxgen
|
|
@@ -103,7 +76,7 @@ $ brew install cdxgen
|
|
|
103
76
|
Deno and bun runtime can be used with limited support.
|
|
104
77
|
|
|
105
78
|
```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"
|
|
79
|
+
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
80
|
```
|
|
108
81
|
|
|
109
82
|
You can also use the cdxgen container image with node, deno, or bun runtime versions.
|
|
@@ -139,7 +112,9 @@ $ cdxgen -h
|
|
|
139
112
|
Options:
|
|
140
113
|
-o, --output Output file. Default bom.json
|
|
141
114
|
[default: "bom.json"]
|
|
142
|
-
-t, --type Project type
|
|
115
|
+
-t, --type Project type. Please refer to https://cyclonedx.g
|
|
116
|
+
ithub.io/cdxgen/#/PROJECT_TYPES for supported lan
|
|
117
|
+
guages/platforms.
|
|
143
118
|
-r, --recurse Recurse mode suitable for mono-repos. Defaults to
|
|
144
119
|
true. Pass --no-recurse to disable.
|
|
145
120
|
[boolean] [default: true]
|
|
@@ -290,7 +265,7 @@ Arguments can be passed either via the query string or as a JSON body. The follo
|
|
|
290
265
|
|
|
291
266
|
| Argument | Description |
|
|
292
267
|
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
293
|
-
| type | Project type
|
|
268
|
+
| type | Project type. Please refer to [Supported Project Types][docs-project-types]. |
|
|
294
269
|
| multiProject | [boolean] |
|
|
295
270
|
| requiredOnly | Include only the packages with required scope on the SBOM. [boolean] |
|
|
296
271
|
| noBabel | Do not use babel to perform usage analysis for JavaScript/TypeScript projects. [boolean] |
|
|
@@ -361,7 +336,7 @@ This would create a bom.json.map file with the jar - class name mapping. Refer t
|
|
|
361
336
|
|
|
362
337
|
## Resolving licenses
|
|
363
338
|
|
|
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]
|
|
339
|
+
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
340
|
|
|
366
341
|
```bash
|
|
367
342
|
export FETCH_LICENSE=true
|
|
@@ -384,47 +359,6 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
|
|
|
384
359
|
- Ruby (Gemfile.lock)
|
|
385
360
|
- Rust (Cargo.lock)
|
|
386
361
|
|
|
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
362
|
## Plugins
|
|
429
363
|
|
|
430
364
|
cdxgen could be extended with external binary plugins to support more SBOM use cases. These are now installed as an optional dependency.
|
|
@@ -458,7 +392,7 @@ cdxgen /tmp/slim.tar -o /tmp/bom.json -t docker
|
|
|
458
392
|
|
|
459
393
|
### Podman in rootless mode
|
|
460
394
|
|
|
461
|
-
Setup podman in either [rootless]
|
|
395
|
+
Setup podman in either [rootless][podman-github-rootless] or [remote][podman-github-remote] mode
|
|
462
396
|
|
|
463
397
|
Do not forget to start the podman socket required for API access on Linux.
|
|
464
398
|
|
|
@@ -478,7 +412,7 @@ obom
|
|
|
478
412
|
# cdxgen -t os
|
|
479
413
|
```
|
|
480
414
|
|
|
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.
|
|
415
|
+
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
416
|
|
|
483
417
|
## Generate Cryptography Bill of Materials (CBOM)
|
|
484
418
|
|
|
@@ -501,9 +435,9 @@ cdxgen can sign the generated BOM json file to increase authenticity and non-rep
|
|
|
501
435
|
- SBOM_SIGN_PRIVATE_KEY: Location to the RSA private key
|
|
502
436
|
- SBOM_SIGN_PUBLIC_KEY: Optional. Location to the RSA public key
|
|
503
437
|
|
|
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]
|
|
438
|
+
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
439
|
|
|
506
|
-

|
|
440
|
+

|
|
507
441
|
|
|
508
442
|
### Verifying the signature
|
|
509
443
|
|
|
@@ -516,7 +450,7 @@ cdx-verify -i bom.json --public-key public.key
|
|
|
516
450
|
|
|
517
451
|
### Custom verification tool (Node.js example)
|
|
518
452
|
|
|
519
|
-
There are many [libraries]
|
|
453
|
+
There are many [libraries][jwt-libraries] available to validate JSON Web Tokens. Below is a javascript example.
|
|
520
454
|
|
|
521
455
|
```js
|
|
522
456
|
# npm install jws
|
|
@@ -543,14 +477,11 @@ cdxgen can automatically detect names of services from YAML manifests such as do
|
|
|
543
477
|
|
|
544
478
|
## Conversion to SPDX format
|
|
545
479
|
|
|
546
|
-
Use the [CycloneDX CLI]
|
|
480
|
+
Use the [CycloneDX CLI][cyclonedx-cli-github] tool for advanced use cases such as conversion, diff and merging.
|
|
547
481
|
|
|
548
482
|
## License
|
|
549
483
|
|
|
550
|
-
Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE]
|
|
551
|
-
|
|
552
|
-
[license]: https://github.com/cyclonedx/cdxgen/blob/master/LICENSE
|
|
553
|
-
[cyclonedx-homepage]: https://cyclonedx.org
|
|
484
|
+
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.
|
|
554
485
|
|
|
555
486
|
## Integration as library
|
|
556
487
|
|
|
@@ -572,25 +503,66 @@ const bomNSData = await createBom(filePath, options);
|
|
|
572
503
|
const dbody = await submitBom(args, bomNSData.bomJson);
|
|
573
504
|
```
|
|
574
505
|
|
|
575
|
-
## Node.js >= 20 permission model
|
|
576
|
-
|
|
577
|
-
Refer to the [permissions document](./docs/PERMISSIONS.md)
|
|
578
|
-
|
|
579
506
|
## Contributing
|
|
580
507
|
|
|
581
|
-
|
|
508
|
+
Please check out our [contribute to CycloneDX/cdxgen documentation][github-contribute] if you are interested in helping.
|
|
509
|
+
|
|
510
|
+
Before raising a PR, please run the following commands.
|
|
582
511
|
|
|
583
512
|
```bash
|
|
513
|
+
corepack enable
|
|
514
|
+
corepack pnpm install
|
|
584
515
|
# Generate types using jsdoc syntax
|
|
585
|
-
|
|
516
|
+
corepack pnpm run gen-types
|
|
586
517
|
# Run biomejs formatter and linter with auto fix
|
|
587
|
-
|
|
518
|
+
corepack pnpm run lint
|
|
588
519
|
# Run jest tests
|
|
589
|
-
|
|
520
|
+
corepack pnpm test
|
|
590
521
|
```
|
|
591
522
|
|
|
592
|
-
|
|
523
|
+
<!-- LINK LABELS -->
|
|
524
|
+
<!-- Badges -->
|
|
525
|
+
|
|
526
|
+
[badge-github-contributors]: https://img.shields.io/github/contributors/cyclonedx/cdxgen
|
|
527
|
+
[badge-github-license]: https://img.shields.io/github/license/cyclonedx/cdxgen
|
|
528
|
+
[badge-github-releases]: https://img.shields.io/github/v/release/cyclonedx/cdxgen
|
|
529
|
+
[badge-jsr]: https://img.shields.io/jsr/v/%40cyclonedx/cdxgen
|
|
530
|
+
[badge-npm]: https://img.shields.io/npm/v/%40cyclonedx%2Fcdxgen
|
|
531
|
+
[badge-npm-downloads]: https://img.shields.io/npm/dy/%40cyclonedx%2Fcdxgen
|
|
532
|
+
[badge-swh]: https://archive.softwareheritage.org/badge/origin/https://github.com/CycloneDX/cdxgen/
|
|
533
|
+
|
|
534
|
+
<!-- cdxgen github project -->
|
|
593
535
|
|
|
594
|
-
|
|
536
|
+
[github-contribute]: https://github.com/CycloneDX/cdxgen/contribute
|
|
537
|
+
[github-contributors]: https://github.com/CycloneDX/cdxgen/graphs/contributors
|
|
538
|
+
[github-issues]: https://github.com/CycloneDX/cdxgen/issues
|
|
539
|
+
[github-license]: https://github.com/cyclonedx/cdxgen/blob/master/LICENSE
|
|
540
|
+
[github-releases]: https://github.com/CycloneDX/cdxgen/releases
|
|
595
541
|
|
|
596
|
-
|
|
542
|
+
<!-- cdxgen documentation site -->
|
|
543
|
+
|
|
544
|
+
[docs-homepage]: https://cyclonedx.github.io/cdxgen
|
|
545
|
+
[docs-advanced-usage]: https://cyclonedx.github.io/cdxgen/#/ADVANCED
|
|
546
|
+
[docs-cli]: https://cyclonedx.github.io/cdxgen/#/CLI
|
|
547
|
+
[docs-env-vars]: https://cyclonedx.github.io/cdxgen/#/ENV
|
|
548
|
+
[docs-permissions]: https://cyclonedx.github.io/cdxgen/#/PERMISSIONS
|
|
549
|
+
[docs-project-types]: https://cyclonedx.github.io/cdxgen/#/PROJECT_TYPES
|
|
550
|
+
[docs-server]: https://cyclonedx.github.io/cdxgen/#/SERVER
|
|
551
|
+
[docs-support]: https://cyclonedx.github.io/cdxgen/#/PROJECT_TYPES
|
|
552
|
+
|
|
553
|
+
<!-- web links-->
|
|
554
|
+
|
|
555
|
+
[appthreat-homepage]: https://www.appthreat.com
|
|
556
|
+
[cyclonedx-homepage]: https://cyclonedx.org
|
|
557
|
+
[cyclonedx-cli-github]: https://github.com/CycloneDX/cyclonedx-cli
|
|
558
|
+
[depscan-github]: https://github.com/cyclonedx/dep-scan
|
|
559
|
+
[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
|
|
560
|
+
[homebrew-homepage]: https://brew.sh
|
|
561
|
+
[homebrew-cdxgen]: https://formulae.brew.sh/formula/cdxgen
|
|
562
|
+
[jsr-cdxgen]: https://jsr.io/@cyclonedx/cdxgen
|
|
563
|
+
[jwt-homepage]: https://jwt.io
|
|
564
|
+
[jwt-libraries]: https://jwt.io/libraries
|
|
565
|
+
[npmjs-cdxgen]: https://www.npmjs.com/package/@cyclonedx/cdxgen
|
|
566
|
+
[podman-github-rootless]: https://github.com/containers/podman/blob/master/docs/tutorials/rootless_tutorial.md
|
|
567
|
+
[podman-github-remote]: https://github.com/containers/podman/blob/master/docs/tutorials/mac_win_client.md
|
|
568
|
+
[swh-cdxgen]: https://archive.softwareheritage.org/browse/origin/?origin_url=https://github.com/CycloneDX/cdxgen
|
package/analyzer.js
CHANGED
|
@@ -292,7 +292,7 @@ export const findJSImportsExports = async (src, deep) => {
|
|
|
292
292
|
const errFiles = [];
|
|
293
293
|
try {
|
|
294
294
|
const promiseMap = await getAllSrcJSAndTSFiles(src, deep);
|
|
295
|
-
const srcFiles = promiseMap.
|
|
295
|
+
const srcFiles = promiseMap.flat();
|
|
296
296
|
for (const file of srcFiles) {
|
|
297
297
|
try {
|
|
298
298
|
parseFileASTTree(src, file, allImports, allExports);
|
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:
|
|
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")
|
|
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")
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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("
|
|
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
|
|
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
|
|
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")
|
|
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-${
|
|
198
|
+
`dosai-${platform}-${arch}${extn}`,
|
|
203
199
|
);
|
|
204
200
|
} else if (process.env.DOSAI_CMD) {
|
|
205
201
|
DOSAI_BIN = process.env.DOSAI_CMD;
|
|
@@ -754,7 +750,11 @@ export function executeOsQuery(query) {
|
|
|
754
750
|
timeout: 60 * 1000,
|
|
755
751
|
});
|
|
756
752
|
if (result.status !== 0 || result.error) {
|
|
757
|
-
if (
|
|
753
|
+
if (
|
|
754
|
+
DEBUG_MODE &&
|
|
755
|
+
result.stderr &&
|
|
756
|
+
!result.stderr.includes("no such table")
|
|
757
|
+
) {
|
|
758
758
|
console.error(result.stdout, result.stderr);
|
|
759
759
|
}
|
|
760
760
|
}
|