@cyclonedx/cdxgen 10.3.5 → 10.4.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/bin/evinse.js CHANGED
@@ -1,28 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import fs from "node:fs";
4
+ import process from "node:process";
5
+ import { findUpSync } from "find-up";
6
+ import { load as _load } from "js-yaml";
3
7
  // Evinse (Evinse Verification Is Nearly SBOM Evidence)
4
8
  import yargs from "yargs";
5
9
  import { hideBin } from "yargs/helpers";
6
- import fs from "node:fs";
7
- import process from "node:process";
8
- import { analyzeProject, createEvinseFile, prepareDB } from "../evinser.js";
9
- import { validateBom } from "../validator.js";
10
10
  import {
11
11
  printCallStack,
12
12
  printOccurrences,
13
13
  printReachables,
14
- printServices
14
+ printServices,
15
15
  } from "../display.js";
16
+ import { analyzeProject, createEvinseFile, prepareDB } from "../evinser.js";
16
17
  import { ATOM_DB } from "../utils.js";
17
- import { findUpSync } from "find-up";
18
- import { load as _load } from "js-yaml";
18
+ import { validateBom } from "../validator.js";
19
19
 
20
20
  // Support for config files
21
21
  const configPath = findUpSync([
22
22
  ".cdxgenrc",
23
23
  ".cdxgen.json",
24
24
  ".cdxgen.yml",
25
- ".cdxgen.yaml"
25
+ ".cdxgen.yaml",
26
26
  ]);
27
27
  let config = {};
28
28
  if (configPath) {
@@ -42,12 +42,12 @@ const args = yargs(hideBin(process.argv))
42
42
  .option("input", {
43
43
  alias: "i",
44
44
  description: "Input SBOM file. Default bom.json",
45
- default: "bom.json"
45
+ default: "bom.json",
46
46
  })
47
47
  .option("output", {
48
48
  alias: "o",
49
49
  description: "Output file. Default bom.evinse.json",
50
- default: "bom.evinse.json"
50
+ default: "bom.evinse.json",
51
51
  })
52
52
  .option("language", {
53
53
  alias: "l",
@@ -64,72 +64,72 @@ const args = yargs(hideBin(process.argv))
64
64
  "android",
65
65
  "c",
66
66
  "cpp",
67
- "php"
68
- ]
67
+ "php",
68
+ ],
69
69
  })
70
70
  .option("db-path", {
71
71
  description: `Atom slices DB path. Default ${ATOM_DB}`,
72
- default: process.env.ATOM_DB || ATOM_DB
72
+ default: process.env.ATOM_DB || ATOM_DB,
73
73
  })
74
74
  .option("force", {
75
75
  description: "Force creation of the database",
76
76
  default: false,
77
- type: "boolean"
77
+ type: "boolean",
78
78
  })
79
79
  .option("skip-maven-collector", {
80
80
  description:
81
81
  "Skip collecting jars from maven and gradle caches. Can speedup re-runs if the data was cached previously.",
82
82
  default: false,
83
- type: "boolean"
83
+ type: "boolean",
84
84
  })
85
85
  .option("with-deep-jar-collector", {
86
86
  description:
87
87
  "Enable collection of all jars from maven cache directory. Useful to improve the recall for callstack evidence.",
88
88
  default: false,
89
- type: "boolean"
89
+ type: "boolean",
90
90
  })
91
91
  .option("annotate", {
92
92
  description: "Include contents of atom slices as annotations",
93
93
  default: false,
94
- type: "boolean"
94
+ type: "boolean",
95
95
  })
96
96
  .option("with-data-flow", {
97
97
  description: "Enable inter-procedural data-flow slicing.",
98
98
  default: false,
99
- type: "boolean"
99
+ type: "boolean",
100
100
  })
101
101
  .option("with-reachables", {
102
102
  description:
103
103
  "Enable auto-tagged reachable slicing. Requires SBOM generated with --deep mode.",
104
104
  default: false,
105
- type: "boolean"
105
+ type: "boolean",
106
106
  })
107
107
  .option("usages-slices-file", {
108
108
  description: "Use an existing usages slices file.",
109
- default: "usages.slices.json"
109
+ default: "usages.slices.json",
110
110
  })
111
111
  .option("data-flow-slices-file", {
112
112
  description: "Use an existing data-flow slices file.",
113
- default: "data-flow.slices.json"
113
+ default: "data-flow.slices.json",
114
114
  })
115
115
  .option("reachables-slices-file", {
116
116
  description: "Use an existing reachables slices file.",
117
- default: "reachables.slices.json"
117
+ default: "reachables.slices.json",
118
118
  })
119
119
  .option("print", {
120
120
  alias: "p",
121
121
  type: "boolean",
122
- description: "Print the evidences as table"
122
+ description: "Print the evidences as table",
123
123
  })
124
124
  .example([
125
125
  [
126
126
  "$0 -i bom.json -o bom.evinse.json -l java .",
127
- "Generate a Java SBOM with evidence for the current directory"
127
+ "Generate a Java SBOM with evidence for the current directory",
128
128
  ],
129
129
  [
130
130
  "$0 -i bom.json -o bom.evinse.json -l java --with-reachables .",
131
- "Generate a Java SBOM with occurrence and reachable evidence for the current directory"
132
- ]
131
+ "Generate a Java SBOM with occurrence and reachable evidence for the current directory",
132
+ ],
133
133
  ])
134
134
  .completion("completion", "Generate bash/zsh completion")
135
135
  .epilogue("for documentation, visit https://cyclonedx.github.io/cdxgen")
package/bin/repl.js CHANGED
@@ -1,22 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import repl from "node:repl";
4
- import jsonata from "jsonata";
5
3
  import fs from "node:fs";
6
- import { join } from "node:path";
7
4
  import { homedir, tmpdir } from "node:os";
5
+ import { join } from "node:path";
8
6
  import process from "node:process";
7
+ import repl from "node:repl";
8
+ import jsonata from "jsonata";
9
9
 
10
- import { createBom } from "../index.js";
11
- import { validateBom } from "../validator.js";
12
10
  import {
13
11
  printCallStack,
14
12
  printDependencyTree,
15
13
  printOSTable,
16
14
  printOccurrences,
17
15
  printServices,
18
- printTable
16
+ printTable,
19
17
  } from "../display.js";
18
+ import { createBom } from "../index.js";
19
+ import { validateBom } from "../validator.js";
20
20
 
21
21
  const options = {
22
22
  useColors: true,
@@ -24,7 +24,7 @@ const options = {
24
24
  preview: true,
25
25
  prompt: "cdx ↝ ",
26
26
  ignoreUndefined: true,
27
- useGlobal: true
27
+ useGlobal: true,
28
28
  };
29
29
 
30
30
  // Use canonical terminal settings to support custom readlines
@@ -63,9 +63,7 @@ export const importSbom = (sbomOrPath) => {
63
63
  sbom = JSON.parse(fs.readFileSync(sbomOrPath, "utf-8"));
64
64
  console.log(`✅ SBOM imported successfully from ${sbomOrPath}`);
65
65
  } catch (e) {
66
- console.log(
67
- `⚠ Unable to import the SBOM from ${sbomOrPath} due to ${e}`
68
- );
66
+ console.log(`⚠ Unable to import the SBOM from ${sbomOrPath} due to ${e}`);
69
67
  }
70
68
  } else {
71
69
  console.log(`⚠ ${sbomOrPath} is invalid.`);
@@ -91,10 +89,10 @@ if (historyFile) {
91
89
  (err) => {
92
90
  if (err) {
93
91
  console.log(
94
- "⚠ REPL history would not be persisted for this session. Set the environment variable CDXGEN_REPL_HISTORY to specify a custom history file"
92
+ "⚠ REPL history would not be persisted for this session. Set the environment variable CDXGEN_REPL_HISTORY to specify a custom history file",
95
93
  );
96
94
  }
97
- }
95
+ },
98
96
  );
99
97
  }
100
98
  cdxgenRepl.defineCommand("create", {
@@ -106,7 +104,7 @@ cdxgenRepl.defineCommand("create", {
106
104
  const bomNSData = await createBom(sbomOrPath, {
107
105
  multiProject: true,
108
106
  installDeps: true,
109
- output: bomFile
107
+ output: bomFile,
110
108
  });
111
109
  if (bomNSData) {
112
110
  sbom = bomNSData.bomJson;
@@ -116,7 +114,7 @@ cdxgenRepl.defineCommand("create", {
116
114
  console.log("BOM was not generated successfully");
117
115
  }
118
116
  this.displayPrompt();
119
- }
117
+ },
120
118
  });
121
119
  cdxgenRepl.defineCommand("import", {
122
120
  help: "import an existing BOM",
@@ -124,13 +122,13 @@ cdxgenRepl.defineCommand("import", {
124
122
  this.clearBufferedCommand();
125
123
  importSbom(sbomOrPath);
126
124
  this.displayPrompt();
127
- }
125
+ },
128
126
  });
129
127
  cdxgenRepl.defineCommand("exit", {
130
128
  help: "exit",
131
129
  action() {
132
130
  this.close();
133
- }
131
+ },
134
132
  });
135
133
  cdxgenRepl.defineCommand("sbom", {
136
134
  help: "show the current sbom",
@@ -139,11 +137,11 @@ cdxgenRepl.defineCommand("sbom", {
139
137
  console.log(sbom);
140
138
  } else {
141
139
  console.log(
142
- "⚠ No BOM is loaded. Use .import command to import an existing BOM"
140
+ "⚠ No BOM is loaded. Use .import command to import an existing BOM",
143
141
  );
144
142
  }
145
143
  this.displayPrompt();
146
- }
144
+ },
147
145
  });
148
146
  cdxgenRepl.defineCommand("search", {
149
147
  help: "search the current bom. performs case insensitive search on various attributes.",
@@ -165,17 +163,15 @@ cdxgenRepl.defineCommand("search", {
165
163
  console.log(e);
166
164
  }
167
165
  } else {
168
- console.log(
169
- "⚠ Specify the search string. Eg: .search <search string>"
170
- );
166
+ console.log("⚠ Specify the search string. Eg: .search <search string>");
171
167
  }
172
168
  } else {
173
169
  console.log(
174
- "⚠ No BOM is loaded. Use .import command to import an existing BOM"
170
+ "⚠ No BOM is loaded. Use .import command to import an existing BOM",
175
171
  );
176
172
  }
177
173
  this.displayPrompt();
178
- }
174
+ },
179
175
  });
180
176
  cdxgenRepl.defineCommand("sort", {
181
177
  help: "sort the current bom based on the attribute",
@@ -205,11 +201,11 @@ cdxgenRepl.defineCommand("sort", {
205
201
  }
206
202
  } else {
207
203
  console.log(
208
- "⚠ No BOM is loaded. Use .import command to import an existing BOM"
204
+ "⚠ No BOM is loaded. Use .import command to import an existing BOM",
209
205
  );
210
206
  }
211
207
  this.displayPrompt();
212
- }
208
+ },
213
209
  });
214
210
  cdxgenRepl.defineCommand("query", {
215
211
  help: "query the current bom using jsonata expression",
@@ -224,16 +220,16 @@ cdxgenRepl.defineCommand("query", {
224
220
  }
225
221
  } else {
226
222
  console.log(
227
- "⚠ Specify the search specification in jsonata format. Eg: .query metadata.component"
223
+ "⚠ Specify the search specification in jsonata format. Eg: .query metadata.component",
228
224
  );
229
225
  }
230
226
  } else {
231
227
  console.log(
232
- "⚠ No BOM is loaded. Use .import command to import an existing BOM"
228
+ "⚠ No BOM is loaded. Use .import command to import an existing BOM",
233
229
  );
234
230
  }
235
231
  this.displayPrompt();
236
- }
232
+ },
237
233
  });
238
234
  cdxgenRepl.defineCommand("print", {
239
235
  help: "print the current bom as a table",
@@ -242,11 +238,11 @@ cdxgenRepl.defineCommand("print", {
242
238
  printTable(sbom);
243
239
  } else {
244
240
  console.log(
245
- "⚠ No BOM is loaded. Use .import command to import an existing BOM"
241
+ "⚠ No BOM is loaded. Use .import command to import an existing BOM",
246
242
  );
247
243
  }
248
244
  this.displayPrompt();
249
- }
245
+ },
250
246
  });
251
247
  cdxgenRepl.defineCommand("tree", {
252
248
  help: "display the dependency tree",
@@ -255,11 +251,11 @@ cdxgenRepl.defineCommand("tree", {
255
251
  printDependencyTree(sbom);
256
252
  } else {
257
253
  console.log(
258
- "⚠ No BOM is loaded. Use .import command to import an existing BOM"
254
+ "⚠ No BOM is loaded. Use .import command to import an existing BOM",
259
255
  );
260
256
  }
261
257
  this.displayPrompt();
262
- }
258
+ },
263
259
  });
264
260
  cdxgenRepl.defineCommand("validate", {
265
261
  help: "validate the bom using jsonschema",
@@ -271,11 +267,11 @@ cdxgenRepl.defineCommand("validate", {
271
267
  }
272
268
  } else {
273
269
  console.log(
274
- "⚠ No BOM is loaded. Use .import command to import an existing BOM"
270
+ "⚠ No BOM is loaded. Use .import command to import an existing BOM",
275
271
  );
276
272
  }
277
273
  this.displayPrompt();
278
- }
274
+ },
279
275
  });
280
276
  cdxgenRepl.defineCommand("save", {
281
277
  help: "save the bom to a new file",
@@ -288,11 +284,11 @@ cdxgenRepl.defineCommand("save", {
288
284
  console.log(`BOM saved successfully to ${saveToFile}`);
289
285
  } else {
290
286
  console.log(
291
- "⚠ No BOM is loaded. Use .import command to import an existing BOM"
287
+ "⚠ No BOM is loaded. Use .import command to import an existing BOM",
292
288
  );
293
289
  }
294
290
  this.displayPrompt();
295
- }
291
+ },
296
292
  });
297
293
  cdxgenRepl.defineCommand("update", {
298
294
  help: "update the bom components based on the given query",
@@ -316,11 +312,11 @@ cdxgenRepl.defineCommand("update", {
316
312
  console.log("BOM updated successfully.");
317
313
  } else {
318
314
  console.log(
319
- "⚠ No BOM is loaded. Use .import command to import an existing BOM"
315
+ "⚠ No BOM is loaded. Use .import command to import an existing BOM",
320
316
  );
321
317
  }
322
318
  this.displayPrompt();
323
- }
319
+ },
324
320
  });
325
321
  cdxgenRepl.defineCommand("occurrences", {
326
322
  help: "view components with evidence.occurrences",
@@ -328,12 +324,12 @@ cdxgenRepl.defineCommand("occurrences", {
328
324
  if (sbom) {
329
325
  try {
330
326
  const expression = jsonata(
331
- "components[$count(evidence.occurrences) > 0]"
327
+ "components[$count(evidence.occurrences) > 0]",
332
328
  );
333
329
  let components = await expression.evaluate(sbom);
334
330
  if (!components) {
335
331
  console.log(
336
- "No results found. Use evinse command to generate an BOM with evidence."
332
+ "No results found. Use evinse command to generate an BOM with evidence.",
337
333
  );
338
334
  } else {
339
335
  if (!Array.isArray(components)) {
@@ -346,27 +342,27 @@ cdxgenRepl.defineCommand("occurrences", {
346
342
  }
347
343
  } else {
348
344
  console.log(
349
- "⚠ No BOM is loaded. Use .import command to import an evinse BOM"
345
+ "⚠ No BOM is loaded. Use .import command to import an evinse BOM",
350
346
  );
351
347
  }
352
348
  this.displayPrompt();
353
- }
349
+ },
354
350
  });
355
351
  cdxgenRepl.defineCommand("discord", {
356
352
  help: "display the discord invite link for support",
357
353
  action() {
358
354
  console.log("Head to https://discord.gg/pF4BYWEJcS for support");
359
355
  this.displayPrompt();
360
- }
356
+ },
361
357
  });
362
358
  cdxgenRepl.defineCommand("sponsor", {
363
359
  help: "display the sponsorship link to fund this project",
364
360
  action() {
365
361
  console.log(
366
- "Hey, thanks a lot for considering! https://github.com/sponsors/prabhu"
362
+ "Hey, thanks a lot for considering! https://github.com/sponsors/prabhu",
367
363
  );
368
364
  this.displayPrompt();
369
- }
365
+ },
370
366
  });
371
367
  cdxgenRepl.defineCommand("callstack", {
372
368
  help: "view components with evidence.callstack",
@@ -374,12 +370,12 @@ cdxgenRepl.defineCommand("callstack", {
374
370
  if (sbom) {
375
371
  try {
376
372
  const expression = jsonata(
377
- "components[$count(evidence.callstack.frames) > 0]"
373
+ "components[$count(evidence.callstack.frames) > 0]",
378
374
  );
379
375
  let components = await expression.evaluate(sbom);
380
376
  if (!components) {
381
377
  console.log(
382
- "callstack evidence was not found. Use evinse command to generate an SBOM with evidence."
378
+ "callstack evidence was not found. Use evinse command to generate an SBOM with evidence.",
383
379
  );
384
380
  } else {
385
381
  if (!Array.isArray(components)) {
@@ -392,11 +388,11 @@ cdxgenRepl.defineCommand("callstack", {
392
388
  }
393
389
  } else {
394
390
  console.log(
395
- "⚠ No SBOM is loaded. Use .import command to import an evinse SBOM"
391
+ "⚠ No SBOM is loaded. Use .import command to import an evinse SBOM",
396
392
  );
397
393
  }
398
394
  this.displayPrompt();
399
- }
395
+ },
400
396
  });
401
397
  cdxgenRepl.defineCommand("services", {
402
398
  help: "view services",
@@ -407,7 +403,7 @@ cdxgenRepl.defineCommand("services", {
407
403
  let services = await expression.evaluate(sbom);
408
404
  if (!services) {
409
405
  console.log(
410
- "No services found. Use evinse command to generate an SBOM with evidence."
406
+ "No services found. Use evinse command to generate an SBOM with evidence.",
411
407
  );
412
408
  } else {
413
409
  if (!Array.isArray(services)) {
@@ -420,11 +416,11 @@ cdxgenRepl.defineCommand("services", {
420
416
  }
421
417
  } else {
422
418
  console.log(
423
- "⚠ No SBOM is loaded. Use .import command to import an evinse SBOM"
419
+ "⚠ No SBOM is loaded. Use .import command to import an evinse SBOM",
424
420
  );
425
421
  }
426
422
  this.displayPrompt();
427
- }
423
+ },
428
424
  });
429
425
  cdxgenRepl.defineCommand("osinfocategories", {
430
426
  help: "view the category names for the OS info from the obom",
@@ -432,12 +428,12 @@ cdxgenRepl.defineCommand("osinfocategories", {
432
428
  if (sbom) {
433
429
  try {
434
430
  const expression = jsonata(
435
- '$distinct(components.properties[name="cdx:osquery:category"].value)'
431
+ '$distinct(components.properties[name="cdx:osquery:category"].value)',
436
432
  );
437
433
  const catgories = await expression.evaluate(sbom);
438
434
  if (!catgories) {
439
435
  console.log(
440
- "Unable to retrieve the os info categories. Only OBOMs generated by cdxgen are supported by this tool."
436
+ "Unable to retrieve the os info categories. Only OBOMs generated by cdxgen are supported by this tool.",
441
437
  );
442
438
  } else {
443
439
  console.log(catgories.join("\n"));
@@ -446,12 +442,10 @@ cdxgenRepl.defineCommand("osinfocategories", {
446
442
  console.log(e);
447
443
  }
448
444
  } else {
449
- console.log(
450
- "⚠ No OBOM is loaded. Use .import command to import an OBOM"
451
- );
445
+ console.log("⚠ No OBOM is loaded. Use .import command to import an OBOM");
452
446
  }
453
447
  this.displayPrompt();
454
- }
448
+ },
455
449
  });
456
450
 
457
451
  // Let's dynamically define more commands from the queries
@@ -522,7 +516,7 @@ cdxgenRepl.defineCommand("osinfocategories", {
522
516
  "wmi_cli_event_consumers",
523
517
  "wmi_cli_event_consumers_snapshot",
524
518
  "wmi_event_filters",
525
- "wmi_filter_consumer_binding"
519
+ "wmi_filter_consumer_binding",
526
520
  ].forEach((c) => {
527
521
  cdxgenRepl.defineCommand(c, {
528
522
  help: `query the ${c} category from the OS info`,
@@ -530,7 +524,7 @@ cdxgenRepl.defineCommand("osinfocategories", {
530
524
  if (sbom) {
531
525
  try {
532
526
  const expression = jsonata(
533
- `components[properties[name="cdx:osquery:category" and value="${c}"]]`
527
+ `components[properties[name="cdx:osquery:category" and value="${c}"]]`,
534
528
  );
535
529
  let components = await expression.evaluate(sbom);
536
530
  if (!components) {
@@ -546,10 +540,10 @@ cdxgenRepl.defineCommand("osinfocategories", {
546
540
  }
547
541
  } else {
548
542
  console.log(
549
- "⚠ No OBOM is loaded. Use .import command to import an OBOM"
543
+ "⚠ No OBOM is loaded. Use .import command to import an OBOM",
550
544
  );
551
545
  }
552
546
  this.displayPrompt();
553
- }
547
+ },
554
548
  });
555
549
  });
package/bin/verify.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import yargs from "yargs";
4
- import { hideBin } from "yargs/helpers";
5
3
  import fs from "node:fs";
6
- import jws from "jws";
4
+ import { dirname, join } from "node:path";
7
5
  import process from "node:process";
8
6
  import { URL, fileURLToPath } from "node:url";
9
- import { dirname, join } from "node:path";
7
+ import jws from "jws";
8
+ import yargs from "yargs";
9
+ import { hideBin } from "yargs/helpers";
10
10
 
11
11
  let url = import.meta.url;
12
12
  if (!url.startsWith("file://")) {
@@ -18,11 +18,11 @@ const args = yargs(hideBin(process.argv))
18
18
  .option("input", {
19
19
  alias: "i",
20
20
  default: "bom.json",
21
- description: "Input json to validate. Default bom.json"
21
+ description: "Input json to validate. Default bom.json",
22
22
  })
23
23
  .option("public-key", {
24
24
  default: "public.key",
25
- description: "Public key in PEM format. Default public.key"
25
+ description: "Public key in PEM format. Default public.key",
26
26
  })
27
27
  .completion("completion", "Generate bash/zsh completion")
28
28
  .epilogue("for documentation, visit https://cyclonedx.github.io/cdxgen")
@@ -33,7 +33,7 @@ const args = yargs(hideBin(process.argv))
33
33
  if (args.version) {
34
34
  const packageJsonAsString = fs.readFileSync(
35
35
  join(dirName, "..", "package.json"),
36
- "utf-8"
36
+ "utf-8",
37
37
  );
38
38
  const packageJson = JSON.parse(packageJsonAsString);
39
39
 
@@ -50,7 +50,7 @@ for (const comp of bomJson.components) {
50
50
  const validationResult = jws.verify(
51
51
  compSignature,
52
52
  comp.signature.algorithm,
53
- fs.readFileSync(args.publicKey, "utf8")
53
+ fs.readFileSync(args.publicKey, "utf8"),
54
54
  );
55
55
  if (!validationResult) {
56
56
  console.log(`${comp["bom-ref"]} signature is invalid!`);
@@ -71,7 +71,7 @@ if (!bomSignature) {
71
71
  const validationResult = jws.verify(
72
72
  bomSignature,
73
73
  bomJson.signature.algorithm,
74
- fs.readFileSync(args.publicKey, "utf8")
74
+ fs.readFileSync(args.publicKey, "utf8"),
75
75
  );
76
76
  if (validationResult) {
77
77
  console.log("Signature is valid!");