@cyclonedx/cdxgen 8.5.3 → 8.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.
@@ -0,0 +1,307 @@
1
+ [
2
+ "_abc",
3
+ "_ast",
4
+ "_codecs",
5
+ "_collections",
6
+ "_functools",
7
+ "_imp",
8
+ "_io",
9
+ "_locale",
10
+ "_operator",
11
+ "_peg_parser",
12
+ "_signal",
13
+ "_sre",
14
+ "_stat",
15
+ "_string",
16
+ "_symtable",
17
+ "_thread",
18
+ "_tracemalloc",
19
+ "_warnings",
20
+ "_weakref",
21
+ "atexit",
22
+ "basehttpserver",
23
+ "simplehttpserver",
24
+ "builtins",
25
+ "errno",
26
+ "faulthandler",
27
+ "gc",
28
+ "itertools",
29
+ "marshal",
30
+ "posix",
31
+ "pwd",
32
+ "sys",
33
+ "time",
34
+ "xxsubtype",
35
+ "__future__",
36
+ "_aix_support",
37
+ "_bootlocale",
38
+ "_bootsubprocess",
39
+ "_collections_abc",
40
+ "_compat_pickle",
41
+ "_compression",
42
+ "_markupbase",
43
+ "_osx_support",
44
+ "_py_abc",
45
+ "_pydecimal",
46
+ "_pyio",
47
+ "_sitebuiltins",
48
+ "_strptime",
49
+ "_sysconfigdata__linux_x86_64-linux-gnu",
50
+ "_sysconfigdata_d_linux_x86_64-linux-gnu",
51
+ "_threading_local",
52
+ "_weakrefset",
53
+ "abc",
54
+ "aifc",
55
+ "antigravity",
56
+ "argparse",
57
+ "ast",
58
+ "asynchat",
59
+ "asyncio",
60
+ "asyncore",
61
+ "base64",
62
+ "bdb",
63
+ "binhex",
64
+ "bisect",
65
+ "bz2",
66
+ "cprofile",
67
+ "calendar",
68
+ "cgi",
69
+ "cgitb",
70
+ "chunk",
71
+ "cmd",
72
+ "code",
73
+ "codecs",
74
+ "codeop",
75
+ "collections",
76
+ "colorsys",
77
+ "compileall",
78
+ "concurrent",
79
+ "configparser",
80
+ "contextlib",
81
+ "contextvars",
82
+ "copy",
83
+ "copyreg",
84
+ "crypt",
85
+ "csv",
86
+ "ctypes",
87
+ "curses",
88
+ "dataclasses",
89
+ "datetime",
90
+ "dbm",
91
+ "decimal",
92
+ "dummy_threading",
93
+ "difflib",
94
+ "dis",
95
+ "distutils",
96
+ "doctest",
97
+ "email",
98
+ "encodings",
99
+ "ensurepip",
100
+ "enum",
101
+ "filecmp",
102
+ "fileinput",
103
+ "fnmatch",
104
+ "formatter",
105
+ "fractions",
106
+ "ftplib",
107
+ "functools",
108
+ "genericpath",
109
+ "getopt",
110
+ "getpass",
111
+ "gettext",
112
+ "glob",
113
+ "graphlib",
114
+ "gzip",
115
+ "hashlib",
116
+ "heapq",
117
+ "hmac",
118
+ "html",
119
+ "http",
120
+ "imaplib",
121
+ "imghdr",
122
+ "imp",
123
+ "importlib",
124
+ "inspect",
125
+ "io",
126
+ "ipaddress",
127
+ "json",
128
+ "keyword",
129
+ "lib2to3",
130
+ "linecache",
131
+ "locale",
132
+ "logging",
133
+ "lzma",
134
+ "mailbox",
135
+ "mailcap",
136
+ "mimetypes",
137
+ "modulefinder",
138
+ "msvcrt",
139
+ "multiprocessing",
140
+ "netrc",
141
+ "nntplib",
142
+ "ntpath",
143
+ "nturl2path",
144
+ "numbers",
145
+ "openssl",
146
+ "opcode",
147
+ "operator",
148
+ "optparse",
149
+ "os",
150
+ "pathlib",
151
+ "pdb",
152
+ "pickle",
153
+ "pickletools",
154
+ "pipes",
155
+ "pkgutil",
156
+ "platform",
157
+ "plistlib",
158
+ "poplib",
159
+ "posixpath",
160
+ "pprint",
161
+ "profile",
162
+ "pstats",
163
+ "pty",
164
+ "py_compile",
165
+ "pyclbr",
166
+ "pydoc",
167
+ "pydoc_data",
168
+ "queue",
169
+ "quopri",
170
+ "random",
171
+ "re",
172
+ "reprlib",
173
+ "rlcompleter",
174
+ "runpy",
175
+ "sched",
176
+ "secrets",
177
+ "selectors",
178
+ "shelve",
179
+ "shlex",
180
+ "shutil",
181
+ "signal",
182
+ "site",
183
+ "smtpd",
184
+ "smtplib",
185
+ "sndhdr",
186
+ "socket",
187
+ "socketserver",
188
+ "sqlite3",
189
+ "sre_compile",
190
+ "sre_constants",
191
+ "sre_parse",
192
+ "ssl",
193
+ "stat",
194
+ "statistics",
195
+ "string",
196
+ "stringio",
197
+ "cstringio",
198
+ "stringprep",
199
+ "struct",
200
+ "subprocess",
201
+ "sunau",
202
+ "symbol",
203
+ "symtable",
204
+ "sysconfig",
205
+ "tabnanny",
206
+ "tarfile",
207
+ "telnetlib",
208
+ "tempfile",
209
+ "textwrap",
210
+ "this",
211
+ "threading",
212
+ "timeit",
213
+ "token",
214
+ "tokenize",
215
+ "trace",
216
+ "traceback",
217
+ "tracemalloc",
218
+ "tty",
219
+ "types",
220
+ "typing",
221
+ "unittest",
222
+ "urllib",
223
+ "uu",
224
+ "uuid",
225
+ "venv",
226
+ "warnings",
227
+ "wave",
228
+ "weakref",
229
+ "webbrowser",
230
+ "wsgiref",
231
+ "winreg",
232
+ "xdrlib",
233
+ "xml",
234
+ "xmlrpc",
235
+ "zipapp",
236
+ "zipfile",
237
+ "zipimport",
238
+ "zoneinfo",
239
+ "_asyncio",
240
+ "_bisect",
241
+ "_blake2",
242
+ "_bz2",
243
+ "_codecs_cn",
244
+ "_codecs_hk",
245
+ "_codecs_iso2022",
246
+ "_codecs_jp",
247
+ "_codecs_kr",
248
+ "_codecs_tw",
249
+ "_contextvars",
250
+ "_crypt",
251
+ "_csv",
252
+ "_ctypes",
253
+ "_curses",
254
+ "_curses_panel",
255
+ "_datetime",
256
+ "_dbm",
257
+ "_decimal",
258
+ "_elementtree",
259
+ "_gdbm",
260
+ "_hashlib",
261
+ "_heapq",
262
+ "_json",
263
+ "_lsprof",
264
+ "_lzma",
265
+ "_multibytecodec",
266
+ "_multiprocessing",
267
+ "_opcode",
268
+ "_pickle",
269
+ "_posixshmem",
270
+ "_posixsubprocess",
271
+ "_queue",
272
+ "_random",
273
+ "_socket",
274
+ "_sqlite3",
275
+ "_ssl",
276
+ "_statistics",
277
+ "_struct",
278
+ "_uuid",
279
+ "_xxsubinterpreters",
280
+ "_zoneinfo",
281
+ "array",
282
+ "audioop",
283
+ "binascii",
284
+ "cmath",
285
+ "fcntl",
286
+ "grp",
287
+ "math",
288
+ "mmap",
289
+ "ossaudiodev",
290
+ "parser",
291
+ "pyexpat",
292
+ "readline",
293
+ "resource",
294
+ "select",
295
+ "spwd",
296
+ "syslog",
297
+ "termios",
298
+ "unicodedata",
299
+ "xxlimited",
300
+ "zlib",
301
+ "_distutils_hack",
302
+ "pip",
303
+ "pkg_resources",
304
+ "setuptools",
305
+ "_info",
306
+ "_registry"
307
+ ]
@@ -46,23 +46,23 @@
46
46
  "purlType": "pypi"
47
47
  },
48
48
  "windows_programs": {
49
- "query" : "select * from programs;",
50
- "description" : "Retrieves the list of products as they are installed by Windows Installer in the target Windows system.",
49
+ "query": "select * from programs;",
50
+ "description": "Retrieves the list of products as they are installed by Windows Installer in the target Windows system.",
51
51
  "purlType": "swid"
52
52
  },
53
53
  "windows_patches": {
54
- "query" : "select * from patches;",
55
- "description" : "Retrieves all the information for the current windows drivers in the target Windows system.",
54
+ "query": "select * from patches;",
55
+ "description": "Retrieves all the information for the current windows drivers in the target Windows system.",
56
56
  "purlType": "swid"
57
57
  },
58
58
  "windows_drivers": {
59
- "query" : "select * from drivers;",
60
- "description" : "Retrieves all the information for the current windows drivers in the target Windows system.",
59
+ "query": "select * from drivers;",
60
+ "description": "Retrieves all the information for the current windows drivers in the target Windows system.",
61
61
  "purlType": "swid"
62
62
  },
63
63
  "windows_shared_resources": {
64
- "query" : "select * from shared_resources;",
65
- "description" : "Retrieves the list of shared resources in the target Windows system.",
64
+ "query": "select * from shared_resources;",
65
+ "description": "Retrieves the list of shared resources in the target Windows system.",
66
66
  "purlType": "swid"
67
67
  }
68
68
  }
@@ -0,0 +1,10 @@
1
+ {
2
+ "commons-": "org.apache.commons",
3
+ "spring-": "org.springframework",
4
+ "jackson-dataformat-": "com.fasterxml.jackson.dataformat",
5
+ "jackson-databind": "com.fasterxml.jackson.core",
6
+ "jackson-core": "com.fasterxml.jackson.core",
7
+ "jackson-annotations": "com.fasterxml.jackson.core",
8
+ "jackson-jaxrs-": "com.fasterxml.jackson.jaxrs",
9
+ "spring.boot": "org.springframework.boot"
10
+ }
package/docker.js CHANGED
@@ -224,6 +224,9 @@ const getConnection = async (options) => {
224
224
  "Ensure docker/podman service or Docker for Desktop is running.",
225
225
  opts
226
226
  );
227
+ console.log(
228
+ "Check if the post-installation steps were performed correctly as per this documentation https://docs.docker.com/engine/install/linux-postinstall/"
229
+ );
227
230
  }
228
231
  }
229
232
  }
package/index.js CHANGED
@@ -14,7 +14,7 @@ const { findJSImports } = require("./analyzer");
14
14
  const semver = require("semver");
15
15
  const dockerLib = require("./docker");
16
16
  const binaryLib = require("./binary");
17
- const osQueries = require("./queries.json");
17
+ const osQueries = require("./data/queries.json");
18
18
  const isWin = require("os").platform() === "win32";
19
19
 
20
20
  const { table } = require("table");
@@ -39,11 +39,6 @@ if (process.env.LEIN_CMD) {
39
39
  LEIN_CMD = process.env.LEIN_CMD;
40
40
  }
41
41
 
42
- let PIP_CMD = "pip";
43
- if (process.env.PIP_CMD) {
44
- PIP_CMD = process.env.PIP_CMD;
45
- }
46
-
47
42
  let SWIFT_CMD = "swift";
48
43
  if (process.env.SWIFT_CMD) {
49
44
  SWIFT_CMD = process.env.SWIFT_CMD;
@@ -510,6 +505,7 @@ function addComponent(
510
505
  }
511
506
  if (!isRootPkg) {
512
507
  let pkgIdentifier = parsePackageJsonName(pkg.name);
508
+ let author = pkg.author || "";
513
509
  let publisher = pkg.publisher || "";
514
510
  let group = pkg.group || pkgIdentifier.scope;
515
511
  // Create empty group
@@ -573,6 +569,7 @@ function addComponent(
573
569
  return;
574
570
  }
575
571
  let component = {
572
+ author,
576
573
  publisher,
577
574
  group,
578
575
  name,
@@ -994,7 +991,7 @@ const createJavaBom = async (path, options) => {
994
991
  if (pomFiles && pomFiles.length) {
995
992
  const cdxMavenPlugin =
996
993
  process.env.CDX_MAVEN_PLUGIN ||
997
- "org.cyclonedx:cyclonedx-maven-plugin:2.7.8";
994
+ "org.cyclonedx:cyclonedx-maven-plugin:2.7.9";
998
995
  const cdxMavenGoal = process.env.CDX_MAVEN_GOAL || "makeAggregateBom";
999
996
  let mvnArgs = [`${cdxMavenPlugin}:${cdxMavenGoal}`, "-DoutputName=bom"];
1000
997
  if (utils.includeMavenTestScope) {
@@ -1073,7 +1070,7 @@ const createJavaBom = async (path, options) => {
1073
1070
  );
1074
1071
  } else {
1075
1072
  console.log(
1076
- "1. Java version requirement: cdxgen container image bundles Java 17 with maven 3.8 which might be incompatible."
1073
+ "1. Java version requirement: cdxgen container image bundles Java 19 with maven 3.9 which might be incompatible."
1077
1074
  );
1078
1075
  }
1079
1076
  console.log(
@@ -1923,8 +1920,7 @@ const createNodejsBom = async (path, options) => {
1923
1920
  * @param options Parse options from the cli
1924
1921
  */
1925
1922
  const createPythonBom = async (path, options) => {
1926
- let pkgList = [];
1927
- let dlist = [];
1923
+ let allImports = {};
1928
1924
  let metadataFilename = "";
1929
1925
  const pipenvMode = fs.existsSync(pathLib.join(path, "Pipfile"));
1930
1926
  const poetryFiles = utils.getAllFiles(
@@ -1951,7 +1947,10 @@ const createPythonBom = async (path, options) => {
1951
1947
  path,
1952
1948
  (options.multiProject ? "**/" : "") + "*.egg-info"
1953
1949
  );
1950
+ let pkgList = [];
1954
1951
  const setupPy = pathLib.join(path, "setup.py");
1952
+ const pyProjectFile = pathLib.join(path, "pyproject.toml");
1953
+ const pyProjectMode = fs.existsSync(pyProjectFile);
1955
1954
  const requirementsMode =
1956
1955
  (reqFiles && reqFiles.length) || (reqDirFiles && reqDirFiles.length);
1957
1956
  const poetryMode = poetryFiles && poetryFiles.length;
@@ -1997,7 +1996,7 @@ const createPythonBom = async (path, options) => {
1997
1996
  // .egg-info files
1998
1997
  if (eggInfoFiles && eggInfoFiles.length) {
1999
1998
  for (let ef of eggInfoFiles) {
2000
- dlist = utils.parseBdistMetadata(
1999
+ const dlist = utils.parseBdistMetadata(
2001
2000
  fs.readFileSync(ef, { encoding: "utf-8" })
2002
2001
  );
2003
2002
  if (dlist && dlist.length) {
@@ -2011,7 +2010,7 @@ const createPythonBom = async (path, options) => {
2011
2010
  const piplockFile = pathLib.join(path, "Pipfile.lock");
2012
2011
  if (fs.existsSync(piplockFile)) {
2013
2012
  const lockData = JSON.parse(fs.readFileSync(piplockFile));
2014
- dlist = await utils.parsePiplockData(lockData);
2013
+ const dlist = await utils.parsePiplockData(lockData);
2015
2014
  if (dlist && dlist.length) {
2016
2015
  pkgList = pkgList.concat(dlist);
2017
2016
  }
@@ -2022,40 +2021,20 @@ const createPythonBom = async (path, options) => {
2022
2021
  } else if (requirementsMode) {
2023
2022
  metadataFilename = "requirements.txt";
2024
2023
  if (reqFiles && reqFiles.length) {
2025
- let pipWarningShown = false;
2026
2024
  for (let f of reqFiles) {
2027
2025
  const basePath = pathLib.dirname(f);
2028
2026
  let reqData = undefined;
2029
- let frozenMode = false;
2030
- // Attempt to pip freeze to improve precision. First try in venv mode
2027
+ let frozen = false;
2028
+ // Attempt to pip freeze in a virtualenv to improve precision
2031
2029
  if (options.installDeps) {
2032
- const result = spawnSync(
2033
- PIP_CMD,
2034
- ["freeze", "-r", f, "-l", "--require-virtualenv"],
2035
- {
2036
- cwd: basePath,
2037
- encoding: "utf-8",
2038
- timeout: TIMEOUT_MS
2039
- }
2040
- );
2041
- if (result.status === 0 && result.stdout) {
2042
- reqData = Buffer.from(result.stdout).toString();
2043
- const dlist = await utils.parseReqFile(reqData, false);
2044
- if (dlist && dlist.length) {
2045
- pkgList = pkgList.concat(dlist);
2046
- }
2047
- frozenMode = true;
2048
- } else if (result.status !== 0 || result.error) {
2049
- if (DEBUG_MODE && !pipWarningShown) {
2050
- pipWarningShown = true;
2051
- console.log(
2052
- "NOTE: Setup and activate a python virtual environment for this project prior to invoking cdxgen to improve SBoM accuracy."
2053
- );
2054
- }
2030
+ const dlist = await utils.executePipFreezeInVenv(basePath, f);
2031
+ if (dlist && dlist.length) {
2032
+ pkgList = pkgList.concat(dlist);
2033
+ frozen = true;
2055
2034
  }
2056
2035
  }
2057
2036
  // Fallback to parsing manually
2058
- if (!frozenMode) {
2037
+ if (!pkgList.length || !frozen) {
2059
2038
  if (DEBUG_MODE) {
2060
2039
  console.log(
2061
2040
  `Manually parsing ${f}. The result would include only direct dependencies.`
@@ -2082,14 +2061,42 @@ const createPythonBom = async (path, options) => {
2082
2061
  }
2083
2062
  }
2084
2063
  }
2064
+ // Use atom in requirements, setup.py and pyproject.toml mode
2065
+ if (requirementsMode || setupPyMode || pyProjectMode) {
2066
+ let dlist = undefined;
2067
+ /**
2068
+ * The order of preference is pyproject.toml (newer) and then setup.py
2069
+ */
2070
+ if (options.installDeps) {
2071
+ if (pyProjectMode) {
2072
+ dlist = await utils.executePipFreezeInVenv(path, pyProjectFile);
2073
+ } else if (setupPyMode) {
2074
+ dlist = await utils.executePipFreezeInVenv(path, setupPy);
2075
+ }
2076
+ if (dlist && dlist.length) {
2077
+ pkgList = pkgList.concat(dlist);
2078
+ }
2079
+ }
2080
+ // Get the imported modules and a dedupe list of packages
2081
+ const retMap = await utils.getPyModules(path, pkgList);
2082
+ if (retMap.pkgList && retMap.pkgList.length) {
2083
+ pkgList = pkgList.concat(retMap.pkgList);
2084
+ }
2085
+ if (retMap.allImports) {
2086
+ allImports = { ...allImports, ...retMap.allImports };
2087
+ }
2088
+ }
2089
+ // Final fallback is to manually parse setup.py if we still
2090
+ // have an empty list
2085
2091
  if (!pkgList.length && setupPyMode) {
2086
2092
  const setupPyData = fs.readFileSync(setupPy, { encoding: "utf-8" });
2087
- dlist = await utils.parseSetupPyFile(setupPyData);
2093
+ const dlist = await utils.parseSetupPyFile(setupPyData);
2088
2094
  if (dlist && dlist.length) {
2089
2095
  pkgList = pkgList.concat(dlist);
2090
2096
  }
2091
2097
  }
2092
2098
  return buildBomNSData(options, pkgList, "pypi", {
2099
+ allImports,
2093
2100
  src: path,
2094
2101
  filename: metadataFilename
2095
2102
  });
@@ -4015,6 +4022,12 @@ const createXBom = async (path, options) => {
4015
4022
  // python
4016
4023
  const pipenvMode = fs.existsSync(pathLib.join(path, "Pipfile"));
4017
4024
  const poetryMode = fs.existsSync(pathLib.join(path, "poetry.lock"));
4025
+ const pyProjectMode =
4026
+ !poetryMode && fs.existsSync(pathLib.join(path, "pyproject.toml"));
4027
+ const setupPyMode = fs.existsSync(pathLib.join(path, "setup.py"));
4028
+ if (pipenvMode || poetryMode || pyProjectMode || setupPyMode) {
4029
+ return await createPythonBom(path, options);
4030
+ }
4018
4031
  const reqFiles = utils.getAllFiles(
4019
4032
  path,
4020
4033
  (options.multiProject ? "**/" : "") + "*requirements*.txt"
@@ -4023,21 +4036,13 @@ const createXBom = async (path, options) => {
4023
4036
  path,
4024
4037
  (options.multiProject ? "**/" : "") + "requirements/*.txt"
4025
4038
  );
4026
- const setupPy = pathLib.join(path, "setup.py");
4027
4039
  const requirementsMode =
4028
4040
  (reqFiles && reqFiles.length) || (reqDirFiles && reqDirFiles.length);
4029
4041
  const whlFiles = utils.getAllFiles(
4030
4042
  path,
4031
4043
  (options.multiProject ? "**/" : "") + "*.whl"
4032
4044
  );
4033
- const setupPyMode = fs.existsSync(setupPy);
4034
- if (
4035
- requirementsMode ||
4036
- pipenvMode ||
4037
- poetryMode ||
4038
- setupPyMode ||
4039
- whlFiles.length
4040
- ) {
4045
+ if (requirementsMode || whlFiles.length) {
4041
4046
  return await createPythonBom(path, options);
4042
4047
  }
4043
4048
  // go
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyclonedx/cdxgen",
3
- "version": "8.5.3",
3
+ "version": "8.6.1",
4
4
  "description": "Creates CycloneDX Software Bill-of-Materials (SBOM) from source or container image",
5
5
  "homepage": "http://github.com/cyclonedx/cdxgen",
6
6
  "author": "Prabhu Subramanian <prabhu@appthreat.com>",
@@ -36,7 +36,7 @@
36
36
  "test": "jest --inject-globals false",
37
37
  "watch": "jest --watch --inject-globals false",
38
38
  "lint": "eslint index.js utils.js binary.js server.js docker.js *.test.js bin/cdxgen",
39
- "pretty": "prettier --write *.js bin/cdxgen --trailing-comma=none"
39
+ "pretty": "prettier --write *.js data/*.json bin/cdxgen --trailing-comma=none"
40
40
  },
41
41
  "engines": {
42
42
  "node": ">=12.0.0"
@@ -49,8 +49,8 @@
49
49
  "url": "https://github.com/cyclonedx/cdxgen/issues"
50
50
  },
51
51
  "dependencies": {
52
- "@babel/parser": "^7.21.8",
53
- "@babel/traverse": "^7.21.5",
52
+ "@babel/parser": "^7.22.5",
53
+ "@babel/traverse": "^7.22.5",
54
54
  "cheerio": "^1.0.0-rc.12",
55
55
  "edn-data": "^1.0.0",
56
56
  "glob": "^8.1.0",
@@ -63,16 +63,17 @@
63
63
  "parse-packagejson-name": "^1.0.1",
64
64
  "prettify-xml": "^1.2.0",
65
65
  "properties-reader": "^2.2.0",
66
- "semver": "^7.5.0",
66
+ "semver": "^7.5.1",
67
67
  "ssri": "^8.0.1",
68
68
  "table": "^6.8.1",
69
- "tar": "^6.1.14",
69
+ "tar": "^6.1.15",
70
70
  "uuid": "^9.0.0",
71
71
  "xml-js": "^1.6.11",
72
72
  "xmlbuilder": "^15.1.1",
73
73
  "yargs": "^17.7.2"
74
74
  },
75
75
  "optionalDependencies": {
76
+ "@appthreat/atom": "^0.10.1",
76
77
  "@cyclonedx/cdxgen-plugins-bin": "^1.1.0",
77
78
  "body-parser": "^1.20.2",
78
79
  "compression": "^1.7.4",
@@ -81,14 +82,10 @@
81
82
  "files": [
82
83
  "*.js",
83
84
  "bin/",
84
- "spdx-licenses.json",
85
- "lic-mapping.json",
86
- "known-licenses.json",
87
- "vendor-alias.json",
88
- "queries.json"
85
+ "data/"
89
86
  ],
90
87
  "devDependencies": {
91
- "eslint": "^8.40.0",
88
+ "eslint": "^8.42.0",
92
89
  "jest": "^29.5.0"
93
90
  }
94
91
  }