@cyclonedx/cdxgen 9.8.9 → 9.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,45 +12,45 @@ CycloneDX 1.5 specification is new and unsupported by many downstream tools. Use
12
12
 
13
13
  ## Why cdxgen?
14
14
 
15
- A typical application might have several repos, components, and libraries. Traditional techniques to generate a single SBOM per language or package manifest do not work in enterprise environments. So we built cdxgen - the universal polyglot SBOM generator!
15
+ Most SBOM tools are like barcode scanners. They can scan a few package manifest 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. Traditional techniques to generate a SBOM per language or package manifest either do not work in enterprise environments or doesn't provide the confidence required for both compliance and automated analysis. So we built cdxgen - the universal polyglot SBOM generator that is both precise and comprehensive!
16
16
 
17
17
  <img src="./docs/why-cdxgen.jpg" alt="why cdxgen" width="256">
18
18
 
19
19
  ## Supported languages and package format
20
20
 
21
- | Language/Platform | Package format | Transitive dependencies |
22
- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
23
- | node.js | npm-shrinkwrap.json, package-lock.json, pnpm-lock.yaml, yarn.lock, rush.js, bower.json, .min.js | Yes except .min.js |
24
- | 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 |
25
- | php | composer.lock | Yes |
26
- | 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 |
27
- | go | binary, go.mod, go.sum, Gopkg.lock | Yes except binary |
28
- | ruby | Gemfile.lock, gemspec | Only for Gemfile.lock |
29
- | rust | binary, Cargo.toml, Cargo.lock | Only for Cargo.lock |
30
- | .Net | .csproj, packages.config, project.assets.json [3], packages.lock.json, .nupkg, paket.lock | Only for project.assets.json, packages.lock.json, paket.lock |
31
- | dart | pubspec.lock, pubspec.yaml | Only for pubspec.lock |
32
- | haskell | cabal.project.freeze | Yes |
33
- | elixir | mix.lock | Yes |
34
- | 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. |
35
- | clojure | Clojure CLI (deps.edn), Leiningen (project.clj) | Yes unless the files are parsed manually due to lack of clojure cli or leiningen command |
36
- | swift | Package.resolved, Package.swift (swiftpm) | Yes |
37
- | docker / oci image | All supported languages. Linux OS packages with plugins [4] | Best effort based on lock files |
38
- | GitHub Actions | .github/workflows/\*.yml | N/A |
39
- | Linux | All supported languages. Linux OS packages with plugins [5] | Best effort based on lock files |
40
- | Windows | All supported languages. OS packages with best effort [5] | Best effort based on lock files |
41
- | Jenkins Plugins | .hpi files | |
42
- | Helm Charts | .yaml | N/A |
43
- | Skaffold | .yaml | N/A |
44
- | kustomization | .yaml | N/A |
45
- | Tekton tasks | .yaml | N/A |
46
- | Kubernetes | .yaml | N/A |
47
- | Maven Cache | $HOME/.m2/repository/\*\*/\*.jar | N/A |
48
- | SBT Cache | $HOME/.ivy2/cache/\*\*/\*.jar | N/A |
49
- | Gradle Cache | $HOME/caches/modules-2/files-2.1/\*\*/\*.jar | N/A |
50
- | Helm Index | $HOME/.cache/helm/repository/\*\*/\*.yaml | N/A |
51
- | Docker compose | docker-compose\*.yml. Images would also be scanned. | N/A |
52
- | Google CloudBuild configuration | cloudbuild.yaml | N/A |
53
- | OpenAPI | openapi\*.json, openapi\*.yaml | N/A |
21
+ | Language/Platform | Package format | Transitive dependencies | Evidence |
22
+ | ------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | -------- |
23
+ | node.js | npm-shrinkwrap.json, package-lock.json, pnpm-lock.yaml, yarn.lock, rush.js, bower.json, .min.js | Yes except .min.js | Yes |
24
+ | 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 |
25
+ | php | composer.lock | Yes | |
26
+ | 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 |
27
+ | go | binary, go.mod, go.sum, Gopkg.lock | Yes except binary | Yes |
28
+ | ruby | Gemfile.lock, gemspec | Only for Gemfile.lock | |
29
+ | rust | binary, Cargo.toml, Cargo.lock | Only for Cargo.lock | |
30
+ | .Net | .csproj, packages.config, project.assets.json [3], packages.lock.json, .nupkg, paket.lock | Only for project.assets.json, packages.lock.json, paket.lock | |
31
+ | dart | pubspec.lock, pubspec.yaml | Only for pubspec.lock | |
32
+ | haskell | cabal.project.freeze | Yes | |
33
+ | elixir | mix.lock | Yes | |
34
+ | 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 |
35
+ | clojure | Clojure CLI (deps.edn), Leiningen (project.clj) | Yes unless the files are parsed manually due to lack of clojure cli or leiningen command | |
36
+ | swift | Package.resolved, Package.swift (swiftpm) | Yes | |
37
+ | docker / oci image | All supported languages. Linux OS packages with plugins [4] | Best effort based on lock files | Yes |
38
+ | GitHub Actions | .github/workflows/\*.yml | N/A | Yes |
39
+ | Linux | All supported languages. Linux OS packages with plugins [5] | Best effort based on lock files | Yes |
40
+ | Windows | All supported languages. OS packages with best effort [5] | Best effort based on lock files | Yes |
41
+ | Jenkins Plugins | .hpi files | | Yes |
42
+ | Helm Charts | .yaml | N/A | |
43
+ | Skaffold | .yaml | N/A | |
44
+ | kustomization | .yaml | N/A | |
45
+ | Tekton tasks | .yaml | N/A | |
46
+ | Kubernetes | .yaml | N/A | |
47
+ | Maven Cache | $HOME/.m2/repository/\*\*/\*.jar | N/A | |
48
+ | SBT Cache | $HOME/.ivy2/cache/\*\*/\*.jar | N/A | |
49
+ | Gradle Cache | $HOME/caches/modules-2/files-2.1/\*\*/\*.jar | N/A | |
50
+ | Helm Index | $HOME/.cache/helm/repository/\*\*/\*.yaml | N/A | |
51
+ | Docker compose | docker-compose\*.yml. Images would also be scanned. | N/A | |
52
+ | Google CloudBuild configuration | cloudbuild.yaml | N/A | |
53
+ | OpenAPI | openapi\*.json, openapi\*.yaml | N/A | |
54
54
 
55
55
  NOTE:
56
56
 
@@ -126,6 +126,7 @@ import { createBom, submitBom } from "npm:@cyclonedx/cdxgen@^9.0.1";
126
126
 
127
127
  ```text
128
128
  $ cdxgen -h
129
+ Options:
129
130
  -o, --output Output file for bom.xml or bom.json. Default bom.
130
131
  json
131
132
  -t, --type Project type
@@ -149,7 +150,9 @@ $ cdxgen -h
149
150
  d or the project name and version together
150
151
  --parent-project-id Dependency track parent project id
151
152
  --required-only Include only the packages with required scope on
152
- the SBOM. [boolean]
153
+ the SBOM. Would set compositions.aggregate to inc
154
+ omplete unless --no-auto-compositions is passed.
155
+ [boolean]
153
156
  --fail-on-error Fail if any dependency extractor fails. [boolean]
154
157
  --no-babel Do not use babel to perform usage analysis for Ja
155
158
  vaScript/TypeScript projects. [boolean]
@@ -166,11 +169,24 @@ $ cdxgen -h
166
169
  --validate Validate the generated SBOM using json schema. De
167
170
  faults to true. Pass --no-validate to disable.
168
171
  [boolean] [default: true]
172
+ --evidence Generate SBOM with evidence for supported languag
173
+ es. WIP [boolean] [default: false]
169
174
  --usages-slices-file Path for the usages slice file created by atom.
170
175
  --data-flow-slices-file Path for the data-flow slice file created by atom
171
176
  .
172
177
  --spec-version CycloneDX Specification version to use. Defaults
173
178
  to 1.5 [default: 1.5]
179
+ --filter Filter components containining this word in purl.
180
+ Multiple values allowed. [array]
181
+ --only Include components only containining this word in
182
+ purl. Useful to generate BOM with first party co
183
+ mponents alone. Multiple values allowed. [array]
184
+ --author The person(s) who created the BOM. Set this value
185
+ if you're intending the modify the BOM and claim
186
+ authorship.[array] [default: "OWASP Foundation"]
187
+ --auto-compositions Automatically set compositions when the BOM was f
188
+ iltered. Defaults to true
189
+ [boolean] [default: true]
174
190
  -h, --help Show help [boolean]
175
191
  -v, --version Show version number [boolean]
176
192
  ```
@@ -325,7 +341,7 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
325
341
  - Gradle
326
342
  - Scala SBT
327
343
  - Python (requirements.txt, setup.py, pyproject.toml, poetry.lock)
328
- - csharp (projects.assets.json)
344
+ - .NET (project.assets.json, paket.lock)
329
345
  - Go (go.mod)
330
346
 
331
347
  ## Environment variables
@@ -354,6 +370,7 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
354
370
  | 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 |
355
371
  | CDXGEN_TIMEOUT_MS | Default timeout for known execution involving maven, gradle or sbt |
356
372
  | CDXGEN_SERVER_TIMEOUT_MS | Default timeout in server mode |
373
+ | CDXGEN_MAX_BUFFER | Max buffer for stdout and stderr. Defaults to 100MB |
357
374
  | CLJ_CMD | Set to override the clojure cli command |
358
375
  | LEIN_CMD | Set to override the leiningen command |
359
376
  | SBOM_SIGN_ALGORITHM | Signature algorithm. Some valid values are RS256, RS384, RS512, PS256, PS384, PS512, ES256 etc |
@@ -364,6 +381,7 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
364
381
  | CDX_MAVEN_INCLUDE_TEST_SCOPE | Whether test scoped dependencies should be included from Maven projects, Default: true |
365
382
  | ASTGEN_IGNORE_DIRS | Comma separated list of directories to ignore while analyzing using babel. The environment variable is also used by atom and astgen. |
366
383
  | ASTGEN_IGNORE_FILE_PATTERN | Ignore regex to use |
384
+ | PYPI_URL | Override pypi url. Default: https://pypi.org/pypi/ |
367
385
 
368
386
  ## Plugins
369
387
 
package/analyzer.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { parse } from "@babel/parser";
2
2
  import traverse from "@babel/traverse";
3
3
  import { join } from "node:path";
4
- import { readdirSync, statSync, readFileSync } from "node:fs";
4
+ import { readdirSync, lstatSync, readFileSync } from "node:fs";
5
5
  import { basename, resolve, isAbsolute, relative } from "node:path";
6
6
 
7
7
  const IGNORE_DIRS = process.env.ASTGEN_IGNORE_DIRS
@@ -46,7 +46,11 @@ const getAllFiles = (dir, extn, files, result, regex) => {
46
46
  continue;
47
47
  }
48
48
  const file = join(dir, files[i]);
49
- if (statSync(file).isDirectory()) {
49
+ const fileStat = lstatSync(file);
50
+ if (fileStat.isSymbolicLink()) {
51
+ continue;
52
+ }
53
+ if (fileStat.isDirectory()) {
50
54
  // Ignore directories
51
55
  const dirName = basename(file);
52
56
  if (
package/bin/cdxgen.js CHANGED
@@ -11,6 +11,29 @@ import { fileURLToPath } from "node:url";
11
11
  import globalAgent from "global-agent";
12
12
  import process from "node:process";
13
13
  import { printTable, printDependencyTree } from "../display.js";
14
+ import { findUpSync } from "find-up";
15
+ import { load as _load } from "js-yaml";
16
+ import { postProcess } from "../postgen.js";
17
+
18
+ // Support for config files
19
+ const configPath = findUpSync([
20
+ ".cdxgenrc",
21
+ ".cdxgen.json",
22
+ ".cdxgen.yml",
23
+ ".cdxgen.yaml"
24
+ ]);
25
+ let config = {};
26
+ if (configPath) {
27
+ try {
28
+ if (configPath.endsWith(".yml") || configPath.endsWith(".yaml")) {
29
+ config = _load(fs.readFileSync(configPath, "utf-8"));
30
+ } else {
31
+ config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
32
+ }
33
+ } catch (e) {
34
+ console.log("Invalid config file", configPath);
35
+ }
36
+ }
14
37
 
15
38
  let url = import.meta.url;
16
39
  if (!url.startsWith("file://")) {
@@ -22,6 +45,7 @@ import yargs from "yargs";
22
45
  import { hideBin } from "yargs/helpers";
23
46
 
24
47
  const args = yargs(hideBin(process.argv))
48
+ .env("CDXGEN")
25
49
  .option("output", {
26
50
  alias: "o",
27
51
  description: "Output file for bom.xml or bom.json. Default bom.json"
@@ -77,7 +101,8 @@ const args = yargs(hideBin(process.argv))
77
101
  })
78
102
  .option("required-only", {
79
103
  type: "boolean",
80
- description: "Include only the packages with required scope on the SBOM."
104
+ description:
105
+ "Include only the packages with required scope on the SBOM. Would set compositions.aggregate to incomplete unless --no-auto-compositions is passed."
81
106
  })
82
107
  .option("fail-on-error", {
83
108
  type: "boolean",
@@ -118,6 +143,7 @@ const args = yargs(hideBin(process.argv))
118
143
  "Validate the generated SBOM using json schema. Defaults to true. Pass --no-validate to disable."
119
144
  })
120
145
  .option("evidence", {
146
+ hidden: true,
121
147
  type: "boolean",
122
148
  default: false,
123
149
  description: "Generate SBOM with evidence for supported languages. WIP"
@@ -132,6 +158,35 @@ const args = yargs(hideBin(process.argv))
132
158
  description: "CycloneDX Specification version to use. Defaults to 1.5",
133
159
  default: 1.5
134
160
  })
161
+ .option("filter", {
162
+ description:
163
+ "Filter components containining this word in purl. Multiple values allowed."
164
+ })
165
+ .option("only", {
166
+ description:
167
+ "Include components only containining this word in purl. Useful to generate BOM with first party components alone. Multiple values allowed."
168
+ })
169
+ .option("author", {
170
+ description:
171
+ "The person(s) who created the BOM. Set this value if you're intending the modify the BOM and claim authorship.",
172
+ default: "OWASP Foundation"
173
+ })
174
+ .completion("completion", "Generate bash/zsh completion")
175
+ .array("filter")
176
+ .array("only")
177
+ .array("author")
178
+ .option("auto-compositions", {
179
+ type: "boolean",
180
+ default: true,
181
+ description:
182
+ "Automatically set compositions when the BOM was filtered. Defaults to true"
183
+ })
184
+ .example([
185
+ ["$0 -t java .", "Generate a Java SBOM for the current directory"],
186
+ ["$0 --server", "Run cdxgen as a server"]
187
+ ])
188
+ .epilogue("for documentation, visit https://cyclonedx.github.io/cdxgen")
189
+ .config(config)
135
190
  .scriptName("cdxgen")
136
191
  .version()
137
192
  .alias("v", "version")
@@ -166,43 +221,20 @@ if (!args.projectName) {
166
221
  }
167
222
  }
168
223
 
169
- // To help dependency track users, we downgrade the spec version to 1.4 automatically
170
- if (args.serverUrl || args.apiKey) {
171
- args.specVersion = 1.4;
172
- }
173
-
174
224
  // Support for obom aliases
175
225
  if (process.argv[1].includes("obom") && !args.type) {
176
226
  args.type = "os";
177
227
  }
178
228
 
179
229
  /**
180
- * projectType: python, nodejs, java, golang
181
- * multiProject: Boolean to indicate monorepo or multi-module projects
230
+ * Command line options
182
231
  */
183
- const options = {
232
+ const options = Object.assign({}, args, {
184
233
  projectType: args.type,
185
234
  multiProject: args.recurse,
186
- output: args.output,
187
- resolveClass: args.resolveClass,
188
- installDeps: args.installDeps,
189
- requiredOnly: args.requiredOnly,
190
- failOnError: args.failOnError,
191
235
  noBabel: args.noBabel || args.babel === false,
192
- deep: args.deep,
193
- generateKeyAndSign: args.generateKeyAndSign,
194
- project: args.projectId,
195
- projectName: args.projectName,
196
- projectGroup: args.projectGroup,
197
- projectVersion: args.projectVersion,
198
- server: args.server,
199
- serverHost: args.serverHost,
200
- serverPort: args.serverPort,
201
- specVersion: args.specVersion,
202
- evidence: args.evidence,
203
- usagesSlicesFile: args.usagesSlicesFile,
204
- dataFlowSlicesFile: args.dataFlowSlicesFile
205
- };
236
+ project: args.projectId
237
+ });
206
238
 
207
239
  /**
208
240
  * Check for node >= 20 permissions
@@ -243,7 +275,7 @@ const checkPermissions = (filePath) => {
243
275
  // Start SBOM server
244
276
  if (args.server) {
245
277
  const serverModule = await import("../server.js");
246
- return await serverModule.start(options);
278
+ return serverModule.start(options);
247
279
  }
248
280
  // Check if cdxgen has the required permissions
249
281
  if (!checkPermissions(filePath)) {
@@ -253,7 +285,10 @@ const checkPermissions = (filePath) => {
253
285
  if (!options.usagesSlicesFile) {
254
286
  options.usagesSlicesFile = `${options.projectName}-usages.json`;
255
287
  }
256
- const bomNSData = (await createBom(filePath, options)) || {};
288
+ let bomNSData = (await createBom(filePath, options)) || {};
289
+ if (options.requiredOnly || options["filter"] || options["only"]) {
290
+ bomNSData = postProcess(bomNSData, options);
291
+ }
257
292
  if (!args.output) {
258
293
  args.output = "bom.json";
259
294
  }
package/bin/evinse.js CHANGED
@@ -9,7 +9,34 @@ import { homedir, platform as _platform } from "node:os";
9
9
  import process from "node:process";
10
10
  import { analyzeProject, createEvinseFile, prepareDB } from "../evinser.js";
11
11
  import { validateBom } from "../validator.js";
12
- import { printCallStack, printOccurrences, printServices } from "../display.js";
12
+ import {
13
+ printCallStack,
14
+ printOccurrences,
15
+ printServices,
16
+ printReachables
17
+ } from "../display.js";
18
+ import { findUpSync } from "find-up";
19
+ import { load as _load } from "js-yaml";
20
+
21
+ // Support for config files
22
+ const configPath = findUpSync([
23
+ ".cdxgenrc",
24
+ ".cdxgen.json",
25
+ ".cdxgen.yml",
26
+ ".cdxgen.yaml"
27
+ ]);
28
+ let config = {};
29
+ if (configPath) {
30
+ try {
31
+ if (configPath.endsWith(".yml") || configPath.endsWith(".yaml")) {
32
+ config = _load(fs.readFileSync(configPath, "utf-8"));
33
+ } else {
34
+ config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
35
+ }
36
+ } catch (e) {
37
+ console.log("Invalid config file", configPath);
38
+ }
39
+ }
13
40
 
14
41
  const isWin = _platform() === "win32";
15
42
  const isMac = _platform() === "darwin";
@@ -28,6 +55,7 @@ if (!process.env.ATOM_DB && !fs.existsSync(ATOM_DB)) {
28
55
  }
29
56
  }
30
57
  const args = yargs(hideBin(process.argv))
58
+ .env("EVINSE")
31
59
  .option("input", {
32
60
  alias: "i",
33
61
  description: "Input SBOM file. Default bom.json",
@@ -42,7 +70,18 @@ const args = yargs(hideBin(process.argv))
42
70
  alias: "l",
43
71
  description: "Application language",
44
72
  default: "java",
45
- choices: ["java", "jar", "javascript", "python", "android", "cpp"]
73
+ choices: [
74
+ "java",
75
+ "jar",
76
+ "js",
77
+ "ts",
78
+ "javascript",
79
+ "py",
80
+ "python",
81
+ "android",
82
+ "c",
83
+ "cpp"
84
+ ]
46
85
  })
47
86
  .option("db-path", {
48
87
  description: `Atom slices DB path. Default ${ATOM_DB}`,
@@ -75,6 +114,12 @@ const args = yargs(hideBin(process.argv))
75
114
  default: false,
76
115
  type: "boolean"
77
116
  })
117
+ .option("with-reachables", {
118
+ description:
119
+ "Enable auto-tagged reachable slicing. Requires SBOM generated with --deep mode.",
120
+ default: false,
121
+ type: "boolean"
122
+ })
78
123
  .option("usages-slices-file", {
79
124
  description: "Use an existing usages slices file.",
80
125
  default: "usages.slices.json"
@@ -83,11 +128,28 @@ const args = yargs(hideBin(process.argv))
83
128
  description: "Use an existing data-flow slices file.",
84
129
  default: "data-flow.slices.json"
85
130
  })
131
+ .option("reachables-slices-file", {
132
+ description: "Use an existing reachables slices file.",
133
+ default: "reachables.slices.json"
134
+ })
86
135
  .option("print", {
87
136
  alias: "p",
88
137
  type: "boolean",
89
138
  description: "Print the evidences as table"
90
139
  })
140
+ .example([
141
+ [
142
+ "$0 -i bom.json -o bom.evinse.json -l java .",
143
+ "Generate a Java SBOM with evidence for the current directory"
144
+ ],
145
+ [
146
+ "$0 -i bom.json -o bom.evinse.json -l java --with-reachables .",
147
+ "Generate a Java SBOM with occurrence and reachable evidence for the current directory"
148
+ ]
149
+ ])
150
+ .completion("completion", "Generate bash/zsh completion")
151
+ .epilogue("for documentation, visit https://cyclonedx.github.io/cdxgen")
152
+ .config(config)
91
153
  .scriptName("evinse")
92
154
  .version()
93
155
  .help("h").argv;
@@ -95,8 +157,8 @@ const args = yargs(hideBin(process.argv))
95
157
  const evinseArt = `
96
158
  ███████╗██╗ ██╗██╗███╗ ██╗███████╗███████╗
97
159
  ██╔════╝██║ ██║██║████╗ ██║██╔════╝██╔════╝
98
- █████╗ ██║ ██║██║██╔██╗ ██║███████╗█████╗
99
- ██╔══╝ ╚██╗ ██╔╝██║██║╚██╗██║╚════██║██╔══╝
160
+ █████╗ ██║ ██║██║██╔██╗ ██║███████╗█████╗
161
+ ██╔══╝ ╚██╗ ██╔╝██║██║╚██╗██║╚════██║██╔══╝
100
162
  ███████╗ ╚████╔╝ ██║██║ ╚████║███████║███████╗
101
163
  ╚══════╝ ╚═══╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚══════╝
102
164
  `;
@@ -117,6 +179,7 @@ console.log(evinseArt);
117
179
  if (args.print) {
118
180
  printOccurrences(bomJson);
119
181
  printCallStack(bomJson);
182
+ printReachables(sliceArtefacts);
120
183
  printServices(bomJson);
121
184
  }
122
185
  }
package/bin/verify.js CHANGED
@@ -24,6 +24,8 @@ const args = yargs(hideBin(process.argv))
24
24
  default: "public.key",
25
25
  description: "Public key in PEM format. Default public.key"
26
26
  })
27
+ .completion("completion", "Generate bash/zsh completion")
28
+ .epilogue("for documentation, visit https://cyclonedx.github.io/cdxgen")
27
29
  .scriptName("cdx-verify")
28
30
  .version()
29
31
  .help("h").argv;
package/binary.js CHANGED
@@ -1,5 +1,11 @@
1
- import { platform as _platform, arch as _arch, tmpdir } from "node:os";
2
- import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
1
+ import { platform as _platform, arch as _arch, tmpdir, homedir } from "node:os";
2
+ import {
3
+ existsSync,
4
+ mkdirSync,
5
+ mkdtempSync,
6
+ readFileSync,
7
+ rmSync
8
+ } from "node:fs";
3
9
  import { join, dirname, basename } from "node:path";
4
10
  import { spawnSync } from "node:child_process";
5
11
  import { PackageURL } from "packageurl-js";
@@ -284,6 +290,13 @@ export const getOSPackages = (src) => {
284
290
  const allTypes = new Set();
285
291
  if (TRIVY_BIN) {
286
292
  let imageType = "image";
293
+ const trivyCacheDir = join(homedir(), ".cache", "trivy");
294
+ try {
295
+ mkdirSync(join(trivyCacheDir, "db"), { recursive: true });
296
+ mkdirSync(join(trivyCacheDir, "java-db"), { recursive: true });
297
+ } catch (err) {
298
+ // ignore errors
299
+ }
287
300
  if (existsSync(src)) {
288
301
  imageType = "rootfs";
289
302
  }
@@ -292,12 +305,17 @@ export const getOSPackages = (src) => {
292
305
  const args = [
293
306
  imageType,
294
307
  "--skip-db-update",
308
+ "--skip-java-db-update",
295
309
  "--offline-scan",
310
+ "--skip-files",
311
+ "**/*.jar",
296
312
  "--no-progress",
297
313
  "--exit-code",
298
314
  "0",
299
315
  "--format",
300
316
  "cyclonedx",
317
+ "--cache-dir",
318
+ trivyCacheDir,
301
319
  "--output",
302
320
  bomJsonFile
303
321
  ];
package/data/README.md CHANGED
@@ -18,3 +18,4 @@ Contents of data directory and their purpose.
18
18
  | spdx.schema.json | jsonschema for validation |
19
19
  | vendor-alias.json | List to correct the group names. Used while parsing .jar files |
20
20
  | wrapdb-releases.json | Database of all available meson wraps. Generated using contrib/wrapdb.py. |
21
+ | frameworks-list.json | List of string fragments to categorize components into frameworks |
@@ -0,0 +1,128 @@
1
+ {
2
+ "all": [
3
+ "System.Web",
4
+ "System.ServiceModel",
5
+ "System.Data",
6
+ "spring",
7
+ "flask",
8
+ "django",
9
+ "beego",
10
+ "chi",
11
+ "echo",
12
+ "github.com/gin-gonic/gin",
13
+ "gorilla",
14
+ "rye",
15
+ "httprouter",
16
+ "akka",
17
+ "dropwizard",
18
+ "vertx",
19
+ "gwt",
20
+ "jax-rs",
21
+ "jax-ws",
22
+ "jsf",
23
+ "play",
24
+ "spark",
25
+ "struts",
26
+ "angular",
27
+ "react",
28
+ "next",
29
+ "ember",
30
+ "express",
31
+ "knex",
32
+ "vue",
33
+ "aiohttp",
34
+ "bottle",
35
+ "cherrypy",
36
+ "drt",
37
+ "falcon",
38
+ "hug",
39
+ "pyramid",
40
+ "sanic",
41
+ "tornado",
42
+ "vibora",
43
+ "koa",
44
+ "-sdk",
45
+ "org.apache",
46
+ "appfuse",
47
+ "drools",
48
+ "jbpm",
49
+ "activiti",
50
+ "barracuda",
51
+ "birt",
52
+ "biojava",
53
+ "bluecove",
54
+ "bouncycastle",
55
+ "cascading",
56
+ "deeplearning4j",
57
+ "eclipselink",
58
+ "geoapi",
59
+ "geotools",
60
+ "hibernate",
61
+ "hsqldb",
62
+ "ibatis",
63
+ "javassist",
64
+ "jersey",
65
+ "jetty",
66
+ "jfreechart",
67
+ "jhipster",
68
+ "jmonkeyengine",
69
+ "jsf",
70
+ "keycloak",
71
+ "liquibase",
72
+ "lwjgl",
73
+ "micronaut",
74
+ "mybatis",
75
+ "netty",
76
+ "neuroph",
77
+ "opencv",
78
+ "orientdb",
79
+ "ormlite",
80
+ "payara",
81
+ "primefaces",
82
+ "quarkus",
83
+ "quartz",
84
+ "sax",
85
+ "slf4j",
86
+ "jasper",
87
+ "spock",
88
+ "thymeleaf",
89
+ "vaadin",
90
+ "vertx",
91
+ "wildfly",
92
+ "zkoss",
93
+ "org.ow2.asm",
94
+ "backbone",
95
+ "dojo",
96
+ "ember",
97
+ "enyo",
98
+ "extjs",
99
+ "jquery",
100
+ "jqwidgets",
101
+ "knockout",
102
+ "mootools",
103
+ "prototypejs",
104
+ "qooxdoo",
105
+ "openui5",
106
+ "solidjs",
107
+ "sproutcore",
108
+ "svelte",
109
+ "wakanda",
110
+ "webix",
111
+ "github.com/aerogo/aero",
112
+ "github.com/aofei/air",
113
+ "github.com/go-the-way/anoweb",
114
+ "github.com/appist/appy",
115
+ "github.com/ungerik/go-rest",
116
+ "goa.design/goa",
117
+ "github.com/aceld/zinx",
118
+ "github.com/dolab/gogo",
119
+ "github.com/yarf-framework/yarf",
120
+ "github.com/norunners/vert",
121
+ "pkg:cargo/rocket",
122
+ "pkg:cargo/actix",
123
+ "pkg:cargo/nickel",
124
+ "pkg:cargo/yew",
125
+ "pkg:cargo/azul",
126
+ "pkg:cargo/conrod"
127
+ ]
128
+ }