@cyclonedx/cdxgen 10.0.0 → 10.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/repl.js +1 -1
- package/binary.js +21 -2
- package/data/README.md +1 -0
- package/data/queries-darwin.json +122 -0
- package/data/queries-win.json +10 -7
- package/data/queries.json +6 -60
- package/docker.js +40 -6
- package/index.js +49 -28
- package/package.json +8 -5
- package/utils.js +66 -34
- package/utils.test.js +2 -2
package/bin/repl.js
CHANGED
|
@@ -468,6 +468,7 @@ cdxgenRepl.defineCommand("osinfocategories", {
|
|
|
468
468
|
"docker_volumes",
|
|
469
469
|
"etc_hosts",
|
|
470
470
|
"firefox_addons",
|
|
471
|
+
"vscode_extensions",
|
|
471
472
|
"homebrew_packages",
|
|
472
473
|
"installed_applications",
|
|
473
474
|
"interface_addresses",
|
|
@@ -494,7 +495,6 @@ cdxgenRepl.defineCommand("osinfocategories", {
|
|
|
494
495
|
"windows_shared_resources",
|
|
495
496
|
"yum_sources",
|
|
496
497
|
"appcompat_shims",
|
|
497
|
-
"atom_packages",
|
|
498
498
|
"browser_plugins",
|
|
499
499
|
"certificates",
|
|
500
500
|
"chocolatey_packages",
|
package/binary.js
CHANGED
|
@@ -40,10 +40,17 @@ switch (arch) {
|
|
|
40
40
|
arch = "amd64";
|
|
41
41
|
if (platform === "windows") {
|
|
42
42
|
pluginsBinSuffix = "-windows-amd64";
|
|
43
|
+
} else if (platform === "darwin") {
|
|
44
|
+
pluginsBinSuffix = "-darwin-amd64";
|
|
43
45
|
}
|
|
44
46
|
break;
|
|
45
47
|
case "arm64":
|
|
46
48
|
pluginsBinSuffix = "-arm64";
|
|
49
|
+
if (platform === "windows") {
|
|
50
|
+
pluginsBinSuffix = "-windows-arm64";
|
|
51
|
+
} else if (platform === "darwin") {
|
|
52
|
+
pluginsBinSuffix = "-darwin-arm64";
|
|
53
|
+
}
|
|
47
54
|
break;
|
|
48
55
|
case "ppc64":
|
|
49
56
|
arch = "ppc64le";
|
|
@@ -169,18 +176,23 @@ if (existsSync(join(CDXGEN_PLUGINS_DIR, "osquery"))) {
|
|
|
169
176
|
"osquery",
|
|
170
177
|
"osqueryi-" + platform + "-" + arch + extn
|
|
171
178
|
);
|
|
179
|
+
// osqueryi-darwin-amd64.app/Contents/MacOS/osqueryd
|
|
180
|
+
if (platform === "darwin") {
|
|
181
|
+
OSQUERY_BIN = `${OSQUERY_BIN}.app/Contents/MacOS/osqueryd`;
|
|
182
|
+
}
|
|
172
183
|
} else if (process.env.OSQUERY_CMD) {
|
|
173
184
|
OSQUERY_BIN = process.env.OSQUERY_CMD;
|
|
174
185
|
}
|
|
175
186
|
let DOSAI_BIN = null;
|
|
176
187
|
if (existsSync(join(CDXGEN_PLUGINS_DIR, "dosai"))) {
|
|
188
|
+
let platformToUse = platform;
|
|
177
189
|
if (platform === "darwin") {
|
|
178
|
-
|
|
190
|
+
platformToUse = "osx";
|
|
179
191
|
}
|
|
180
192
|
DOSAI_BIN = join(
|
|
181
193
|
CDXGEN_PLUGINS_DIR,
|
|
182
194
|
"dosai",
|
|
183
|
-
"dosai-" +
|
|
195
|
+
"dosai-" + platformToUse + "-" + arch + extn
|
|
184
196
|
);
|
|
185
197
|
} else if (process.env.DOSAI_CMD) {
|
|
186
198
|
DOSAI_BIN = process.env.DOSAI_CMD;
|
|
@@ -679,6 +691,13 @@ export const executeOsQuery = (query) => {
|
|
|
679
691
|
query = query + ";";
|
|
680
692
|
}
|
|
681
693
|
const args = ["--json", query];
|
|
694
|
+
// On darwin, we need to disable the safety check and run cdxgen with sudo
|
|
695
|
+
// https://github.com/osquery/osquery/issues/1382
|
|
696
|
+
if (platform === "darwin") {
|
|
697
|
+
args.push("--allow_unsafe");
|
|
698
|
+
args.push("--disable_logging");
|
|
699
|
+
args.push("--disable_events");
|
|
700
|
+
}
|
|
682
701
|
if (DEBUG_MODE) {
|
|
683
702
|
console.log("Executing", OSQUERY_BIN, args.join(" "));
|
|
684
703
|
}
|
package/data/README.md
CHANGED
|
@@ -15,6 +15,7 @@ Contents of data directory and their purpose.
|
|
|
15
15
|
| python-stdlib.json | Standard libraries that can be filtered out in python |
|
|
16
16
|
| queries-win.json | osquery used to generate obom for windows |
|
|
17
17
|
| queries.json | osquery used to generate obom for linux |
|
|
18
|
+
| queries-darwin.json | osquery used to generate obom for darwin |
|
|
18
19
|
| spdx-licenses.json | valid spdx id |
|
|
19
20
|
| spdx.schema.json | jsonschema for validation |
|
|
20
21
|
| vendor-alias.json | List to correct the group names. Used while parsing .jar files |
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
{
|
|
2
|
+
"os_version": {
|
|
3
|
+
"query": "select * from os_version;",
|
|
4
|
+
"description": "Retrieves the current version of the running osquery in the target system and where the configuration was loaded from.",
|
|
5
|
+
"purlType": "swid",
|
|
6
|
+
"componentType": "operating-system"
|
|
7
|
+
},
|
|
8
|
+
"safari_extensions": {
|
|
9
|
+
"query": "select safari_extensions.* from users join safari_extensions using (uid);",
|
|
10
|
+
"description": "Safari browser extension details for all users. This table requires Full Disk Access (FDA) permission.",
|
|
11
|
+
"purlType": "swid",
|
|
12
|
+
"componentType": "application"
|
|
13
|
+
},
|
|
14
|
+
"chrome_extensions": {
|
|
15
|
+
"query": "select chrome_extensions.* from users join chrome_extensions using (uid);",
|
|
16
|
+
"description": "Retrieves the list of extensions for Chrome in the target system.",
|
|
17
|
+
"purlType": "swid",
|
|
18
|
+
"componentType": "application"
|
|
19
|
+
},
|
|
20
|
+
"firefox_addons": {
|
|
21
|
+
"query": "select firefox_addons.* from users join firefox_addons using (uid);",
|
|
22
|
+
"description": "Retrieves the list of addons for Firefox in the target system.",
|
|
23
|
+
"purlType": "swid",
|
|
24
|
+
"componentType": "application"
|
|
25
|
+
},
|
|
26
|
+
"vscode_extensions": {
|
|
27
|
+
"query": "select vscode_extensions.* from users join vscode_extensions using (uid);",
|
|
28
|
+
"description": "Lists all vscode extensions.",
|
|
29
|
+
"purlType": "vsix",
|
|
30
|
+
"componentType": "application"
|
|
31
|
+
},
|
|
32
|
+
"apps": {
|
|
33
|
+
"query": "select * from apps;",
|
|
34
|
+
"description": "macOS applications installed in known search paths (e.g., /Applications).",
|
|
35
|
+
"purlType": "swid",
|
|
36
|
+
"componentType": "application"
|
|
37
|
+
},
|
|
38
|
+
"system_extensions": {
|
|
39
|
+
"query": "select * from system_extensions;",
|
|
40
|
+
"description": "macOS (>= 10.15) system extension table.",
|
|
41
|
+
"purlType": "swid",
|
|
42
|
+
"componentType": "application"
|
|
43
|
+
},
|
|
44
|
+
"certificates": {
|
|
45
|
+
"query": "SELECT * FROM certificates WHERE path != 'Other People';",
|
|
46
|
+
"description": "List all certificates in the trust store.",
|
|
47
|
+
"purlType": "swid",
|
|
48
|
+
"componentType": "data"
|
|
49
|
+
},
|
|
50
|
+
"package_bom": {
|
|
51
|
+
"query": "SELECT * FROM package_bom;",
|
|
52
|
+
"description": "macOS package bill of materials (BOM) file list.",
|
|
53
|
+
"purlType": "swid",
|
|
54
|
+
"componentType": "application"
|
|
55
|
+
},
|
|
56
|
+
"package_install_history": {
|
|
57
|
+
"query": "SELECT * FROM package_install_history;",
|
|
58
|
+
"description": "macOS package install history.",
|
|
59
|
+
"purlType": "swid",
|
|
60
|
+
"componentType": "application"
|
|
61
|
+
},
|
|
62
|
+
"package_receipts": {
|
|
63
|
+
"query": "SELECT * FROM package_receipts;",
|
|
64
|
+
"description": "macOS package receipt details.",
|
|
65
|
+
"purlType": "swid",
|
|
66
|
+
"componentType": "application"
|
|
67
|
+
},
|
|
68
|
+
"running_apps": {
|
|
69
|
+
"query": "SELECT * FROM running_apps;",
|
|
70
|
+
"description": "macOS applications currently running on the host system.",
|
|
71
|
+
"purlType": "swid",
|
|
72
|
+
"componentType": "data"
|
|
73
|
+
},
|
|
74
|
+
"sandboxes": {
|
|
75
|
+
"query": "SELECT * FROM sandboxes;",
|
|
76
|
+
"description": "macOS application sandboxes container details.",
|
|
77
|
+
"purlType": "swid",
|
|
78
|
+
"componentType": "data"
|
|
79
|
+
},
|
|
80
|
+
"startup_items": {
|
|
81
|
+
"query": "SELECT * FROM startup_items;",
|
|
82
|
+
"description": "List all startup_items.",
|
|
83
|
+
"purlType": "swid",
|
|
84
|
+
"componentType": "data"
|
|
85
|
+
},
|
|
86
|
+
"listening_ports": {
|
|
87
|
+
"query": "SELECT DISTINCT process.name, listening.port, listening.protocol, listening.family, listening.address, process.pid, process.path, process.on_disk, process.parent, process.start_time FROM processes AS process JOIN listening_ports AS listening ON process.pid = listening.pid;",
|
|
88
|
+
"description": "List all processes and their listening_ports.",
|
|
89
|
+
"purlType": "swid",
|
|
90
|
+
"componentType": "application"
|
|
91
|
+
},
|
|
92
|
+
"interface_addresses": {
|
|
93
|
+
"query": "SELECT * FROM interface_addresses;",
|
|
94
|
+
"description": "List all interface_addresses.",
|
|
95
|
+
"purlType": "swid",
|
|
96
|
+
"componentType": "data"
|
|
97
|
+
},
|
|
98
|
+
"docker_container_ports": {
|
|
99
|
+
"query": "SELECT * FROM docker_container_ports;",
|
|
100
|
+
"description": "List all docker_container_ports.",
|
|
101
|
+
"purlType": "swid",
|
|
102
|
+
"componentType": "data"
|
|
103
|
+
},
|
|
104
|
+
"docker_containers": {
|
|
105
|
+
"query": "SELECT * FROM docker_containers;",
|
|
106
|
+
"description": "List all docker_containers.",
|
|
107
|
+
"purlType": "swid",
|
|
108
|
+
"componentType": "data"
|
|
109
|
+
},
|
|
110
|
+
"docker_networks": {
|
|
111
|
+
"query": "SELECT * FROM docker_networks;",
|
|
112
|
+
"description": "List all docker_networks.",
|
|
113
|
+
"purlType": "swid",
|
|
114
|
+
"componentType": "data"
|
|
115
|
+
},
|
|
116
|
+
"docker_volumes": {
|
|
117
|
+
"query": "SELECT * FROM docker_volumes;",
|
|
118
|
+
"description": "List all docker_volumes.",
|
|
119
|
+
"purlType": "swid",
|
|
120
|
+
"componentType": "data"
|
|
121
|
+
}
|
|
122
|
+
}
|
package/data/queries-win.json
CHANGED
|
@@ -15,12 +15,20 @@
|
|
|
15
15
|
"chrome_extensions": {
|
|
16
16
|
"query": "select chrome_extensions.* from users join chrome_extensions using (uid);",
|
|
17
17
|
"description": "Retrieves the list of extensions for Chrome in the target system.",
|
|
18
|
-
"purlType": "swid"
|
|
18
|
+
"purlType": "swid",
|
|
19
|
+
"componentType": "application"
|
|
19
20
|
},
|
|
20
21
|
"firefox_addons": {
|
|
21
22
|
"query": "select firefox_addons.* from users join firefox_addons using (uid);",
|
|
22
23
|
"description": "Retrieves the list of addons for Firefox in the target system.",
|
|
23
|
-
"purlType": "swid"
|
|
24
|
+
"purlType": "swid",
|
|
25
|
+
"componentType": "application"
|
|
26
|
+
},
|
|
27
|
+
"vscode_extensions": {
|
|
28
|
+
"query": "select vscode_extensions.* from users join vscode_extensions using (uid);",
|
|
29
|
+
"description": "Lists all vscode extensions.",
|
|
30
|
+
"purlType": "vsix",
|
|
31
|
+
"componentType": "application"
|
|
24
32
|
},
|
|
25
33
|
"browser_plugins": {
|
|
26
34
|
"query": "select browser_plugins.* from users join browser_plugins using (uid);",
|
|
@@ -144,11 +152,6 @@
|
|
|
144
152
|
"description": "List all npm_packages.",
|
|
145
153
|
"purlType": "npm"
|
|
146
154
|
},
|
|
147
|
-
"atom_packages": {
|
|
148
|
-
"query": "SELECT * FROM atom_packages;",
|
|
149
|
-
"description": "List all atom_packages.",
|
|
150
|
-
"purlType": "atom"
|
|
151
|
-
},
|
|
152
155
|
"startup_items": {
|
|
153
156
|
"query": "SELECT * FROM startup_items;",
|
|
154
157
|
"description": "List all startup_items.",
|
package/data/queries.json
CHANGED
|
@@ -24,6 +24,12 @@
|
|
|
24
24
|
"purlType": "swid",
|
|
25
25
|
"componentType": "application"
|
|
26
26
|
},
|
|
27
|
+
"vscode_extensions": {
|
|
28
|
+
"query": "select vscode_extensions.* from users join vscode_extensions using (uid);",
|
|
29
|
+
"description": "Lists all vscode extensions.",
|
|
30
|
+
"purlType": "vsix",
|
|
31
|
+
"componentType": "application"
|
|
32
|
+
},
|
|
27
33
|
"deb_packages": {
|
|
28
34
|
"query": "select * from deb_packages;",
|
|
29
35
|
"description": "Retrieves all the installed DEB packages in the target Linux system.",
|
|
@@ -54,78 +60,18 @@
|
|
|
54
60
|
"description": "Python packages installed on system.",
|
|
55
61
|
"purlType": "pypi"
|
|
56
62
|
},
|
|
57
|
-
"windows_programs": {
|
|
58
|
-
"query": "select * from programs;",
|
|
59
|
-
"description": "Retrieves the list of products as they are installed by Windows Installer in the target Windows system.",
|
|
60
|
-
"purlType": "swid",
|
|
61
|
-
"componentType": "application"
|
|
62
|
-
},
|
|
63
|
-
"windows_patches": {
|
|
64
|
-
"query": "select * from patches;",
|
|
65
|
-
"description": "Retrieves all the information for the current windows drivers in the target Windows system.",
|
|
66
|
-
"purlType": "swid",
|
|
67
|
-
"componentType": "application"
|
|
68
|
-
},
|
|
69
|
-
"windows_drivers": {
|
|
70
|
-
"query": "select * from drivers;",
|
|
71
|
-
"description": "Retrieves all the information for the current windows drivers in the target Windows system.",
|
|
72
|
-
"purlType": "swid",
|
|
73
|
-
"componentType": "device-driver"
|
|
74
|
-
},
|
|
75
|
-
"windows_shared_resources": {
|
|
76
|
-
"query": "select * from shared_resources;",
|
|
77
|
-
"description": "Retrieves the list of shared resources in the target Windows system.",
|
|
78
|
-
"purlType": "swid",
|
|
79
|
-
"componentType": "data"
|
|
80
|
-
},
|
|
81
63
|
"system_info_snapshot": {
|
|
82
64
|
"query": "SELECT * FROM system_info;",
|
|
83
65
|
"description": "System info snapshot query.",
|
|
84
66
|
"purlType": "swid",
|
|
85
67
|
"componentType": "data"
|
|
86
68
|
},
|
|
87
|
-
"pipes_snapshot": {
|
|
88
|
-
"query": "SELECT processes.path, processes.cmdline, processes.uid, processes.on_disk, pipes.name, pid FROM pipes JOIN processes USING (pid);",
|
|
89
|
-
"description": "Pipes snapshot query.",
|
|
90
|
-
"purlType": "swid",
|
|
91
|
-
"componentType": "data"
|
|
92
|
-
},
|
|
93
|
-
"services_snapshot": {
|
|
94
|
-
"query": "SELECT * FROM services;",
|
|
95
|
-
"description": "Services snapshot query.",
|
|
96
|
-
"purlType": "swid",
|
|
97
|
-
"componentType": "data"
|
|
98
|
-
},
|
|
99
69
|
"etc_hosts": {
|
|
100
70
|
"query": "SELECT * FROM etc_hosts;",
|
|
101
71
|
"description": "List the contents of the Windows hosts file.",
|
|
102
72
|
"purlType": "swid",
|
|
103
73
|
"componentType": "data"
|
|
104
74
|
},
|
|
105
|
-
"scheduled_tasks": {
|
|
106
|
-
"query": "SELECT * FROM scheduled_tasks;",
|
|
107
|
-
"description": "List all scheduled_tasks.",
|
|
108
|
-
"purlType": "swid",
|
|
109
|
-
"componentType": "data"
|
|
110
|
-
},
|
|
111
|
-
"homebrew_packages": {
|
|
112
|
-
"query": "SELECT * FROM homebrew_packages;",
|
|
113
|
-
"description": "List all homebrew_packages.",
|
|
114
|
-
"purlType": "swid",
|
|
115
|
-
"componentType": "data"
|
|
116
|
-
},
|
|
117
|
-
"installed_applications": {
|
|
118
|
-
"query": "SELECT * FROM apps;",
|
|
119
|
-
"description": "List all macos apps.",
|
|
120
|
-
"purlType": "swid",
|
|
121
|
-
"componentType": "data"
|
|
122
|
-
},
|
|
123
|
-
"kernel_integrity": {
|
|
124
|
-
"query": "SELECT * FROM kernel_integrity;",
|
|
125
|
-
"description": "Various Linux kernel integrity checked attributes.",
|
|
126
|
-
"purlType": "swid",
|
|
127
|
-
"componentType": "data"
|
|
128
|
-
},
|
|
129
75
|
"crontab_snapshot": {
|
|
130
76
|
"query": "SELECT * FROM crontab;",
|
|
131
77
|
"description": "Retrieves all the jobs scheduled in crontab in the target system.",
|
package/docker.js
CHANGED
|
@@ -684,7 +684,7 @@ export const extractTar = async (fullImageName, dir) => {
|
|
|
684
684
|
preserveOwner: false,
|
|
685
685
|
noMtime: true,
|
|
686
686
|
noChmod: true,
|
|
687
|
-
strict:
|
|
687
|
+
strict: false,
|
|
688
688
|
C: dir,
|
|
689
689
|
portable: true,
|
|
690
690
|
onwarn: () => {},
|
|
@@ -696,6 +696,9 @@ export const extractTar = async (fullImageName, dir) => {
|
|
|
696
696
|
path.includes("etc/") ||
|
|
697
697
|
path.includes("logs/") ||
|
|
698
698
|
path.includes("dev/") ||
|
|
699
|
+
path.includes("usr/share/zoneinfo/") ||
|
|
700
|
+
path.includes("usr/share/doc/") ||
|
|
701
|
+
path.includes("usr/share/i18n/") ||
|
|
699
702
|
[
|
|
700
703
|
"BlockDevice",
|
|
701
704
|
"CharacterDevice",
|
|
@@ -727,6 +730,12 @@ export const extractTar = async (fullImageName, dir) => {
|
|
|
727
730
|
console.log("------------");
|
|
728
731
|
console.log(err);
|
|
729
732
|
console.log("------------");
|
|
733
|
+
} else if (err.code === "TAR_BAD_ARCHIVE") {
|
|
734
|
+
if (DEBUG_MODE) {
|
|
735
|
+
console.log(`Archive ${fullImageName} is empty. Skipping.`);
|
|
736
|
+
}
|
|
737
|
+
} else {
|
|
738
|
+
console.log(err);
|
|
730
739
|
}
|
|
731
740
|
return false;
|
|
732
741
|
}
|
|
@@ -832,13 +841,30 @@ export const extractFromManifest = async (
|
|
|
832
841
|
}
|
|
833
842
|
const lastLayer = layers[layers.length - 1];
|
|
834
843
|
for (const layer of layers) {
|
|
844
|
+
try {
|
|
845
|
+
if (!lstatSync(join(tempDir, layer)).isFile()) {
|
|
846
|
+
console.log(
|
|
847
|
+
`Skipping layer ${layer} since it is not a readable file.`
|
|
848
|
+
);
|
|
849
|
+
continue;
|
|
850
|
+
}
|
|
851
|
+
} catch (e) {
|
|
852
|
+
console.log(`Skipping layer ${layer} since it is not a readable file.`);
|
|
853
|
+
continue;
|
|
854
|
+
}
|
|
835
855
|
if (DEBUG_MODE) {
|
|
836
856
|
console.log(`Extracting layer ${layer} to ${allLayersExplodedDir}`);
|
|
837
857
|
}
|
|
838
858
|
try {
|
|
839
859
|
await extractTar(join(tempDir, layer), allLayersExplodedDir);
|
|
840
860
|
} catch (err) {
|
|
841
|
-
|
|
861
|
+
if (err.code === "TAR_BAD_ARCHIVE") {
|
|
862
|
+
if (DEBUG_MODE) {
|
|
863
|
+
console.log(`Layer ${layer} is empty.`);
|
|
864
|
+
}
|
|
865
|
+
} else {
|
|
866
|
+
console.log(err);
|
|
867
|
+
}
|
|
842
868
|
}
|
|
843
869
|
}
|
|
844
870
|
if (manifest.Config) {
|
|
@@ -1058,15 +1084,23 @@ export const getPkgPathList = (exportData, lastWorkingDir) => {
|
|
|
1058
1084
|
}
|
|
1059
1085
|
}
|
|
1060
1086
|
if (lastWorkingDir && lastWorkingDir !== "") {
|
|
1061
|
-
|
|
1087
|
+
if (
|
|
1088
|
+
!lastWorkingDir.includes("/opt/") &&
|
|
1089
|
+
!lastWorkingDir.includes("/home/")
|
|
1090
|
+
) {
|
|
1091
|
+
knownSysPaths.push(lastWorkingDir);
|
|
1092
|
+
}
|
|
1062
1093
|
// Some more common app dirs
|
|
1063
|
-
if (!lastWorkingDir.
|
|
1094
|
+
if (!lastWorkingDir.includes("/app/")) {
|
|
1064
1095
|
knownSysPaths.push(join(allLayersExplodedDir, "/app"));
|
|
1065
1096
|
}
|
|
1066
|
-
if (!lastWorkingDir.
|
|
1097
|
+
if (!lastWorkingDir.includes("/layers/")) {
|
|
1098
|
+
knownSysPaths.push(join(allLayersExplodedDir, "/layers"));
|
|
1099
|
+
}
|
|
1100
|
+
if (!lastWorkingDir.includes("/data/")) {
|
|
1067
1101
|
knownSysPaths.push(join(allLayersExplodedDir, "/data"));
|
|
1068
1102
|
}
|
|
1069
|
-
if (!lastWorkingDir.
|
|
1103
|
+
if (!lastWorkingDir.includes("/srv/")) {
|
|
1070
1104
|
knownSysPaths.push(join(allLayersExplodedDir, "/srv"));
|
|
1071
1105
|
}
|
|
1072
1106
|
}
|
package/index.js
CHANGED
|
@@ -152,11 +152,24 @@ import { collectOSCryptoLibs } from "./cbomutils.js";
|
|
|
152
152
|
|
|
153
153
|
const isWin = _platform() === "win32";
|
|
154
154
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
:
|
|
155
|
+
let osQueries = {};
|
|
156
|
+
switch (_platform()) {
|
|
157
|
+
case "win32":
|
|
158
|
+
osQueries = JSON.parse(
|
|
158
159
|
readFileSync(join(dirName, "data", "queries-win.json"), "utf-8")
|
|
159
160
|
);
|
|
161
|
+
break;
|
|
162
|
+
case "darwin":
|
|
163
|
+
osQueries = JSON.parse(
|
|
164
|
+
readFileSync(join(dirName, "data", "queries-darwin.json"), "utf-8")
|
|
165
|
+
);
|
|
166
|
+
break;
|
|
167
|
+
default:
|
|
168
|
+
osQueries = JSON.parse(
|
|
169
|
+
readFileSync(join(dirName, "data", "queries.json"), "utf-8")
|
|
170
|
+
);
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
160
173
|
const cosDbQueries = JSON.parse(
|
|
161
174
|
readFileSync(join(dirName, "data", "cosdb-queries.json"), "utf-8")
|
|
162
175
|
);
|
|
@@ -948,39 +961,42 @@ export const createJarBom = async (path, options) => {
|
|
|
948
961
|
false,
|
|
949
962
|
true
|
|
950
963
|
);
|
|
964
|
+
}
|
|
965
|
+
if (path.endsWith(".jar")) {
|
|
966
|
+
jarFiles = [resolve(path)];
|
|
951
967
|
} else {
|
|
952
968
|
jarFiles = getAllFiles(
|
|
953
969
|
path,
|
|
954
970
|
(options.multiProject ? "**/" : "") + "*.[jw]ar",
|
|
955
971
|
options
|
|
956
972
|
);
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
973
|
+
}
|
|
974
|
+
// Jenkins plugins
|
|
975
|
+
const hpiFiles = getAllFiles(
|
|
976
|
+
path,
|
|
977
|
+
(options.multiProject ? "**/" : "") + "*.hpi",
|
|
978
|
+
options
|
|
979
|
+
);
|
|
980
|
+
if (hpiFiles.length) {
|
|
981
|
+
jarFiles = jarFiles.concat(hpiFiles);
|
|
982
|
+
}
|
|
983
|
+
const tempDir = mkdtempSync(join(tmpdir(), "jar-deps-"));
|
|
984
|
+
for (const jar of jarFiles) {
|
|
985
|
+
if (DEBUG_MODE) {
|
|
986
|
+
console.log(`Parsing ${jar}`);
|
|
965
987
|
}
|
|
966
|
-
const
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
console.log(`Parsing ${jar}`);
|
|
970
|
-
}
|
|
971
|
-
const dlist = await extractJarArchive(jar, tempDir);
|
|
972
|
-
if (dlist && dlist.length) {
|
|
973
|
-
pkgList = pkgList.concat(dlist);
|
|
974
|
-
}
|
|
975
|
-
if (pkgList.length) {
|
|
976
|
-
pkgList = await getMvnMetadata(pkgList);
|
|
977
|
-
}
|
|
988
|
+
const dlist = await extractJarArchive(jar, tempDir);
|
|
989
|
+
if (dlist && dlist.length) {
|
|
990
|
+
pkgList = pkgList.concat(dlist);
|
|
978
991
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
rmSync(tempDir, { recursive: true, force: true });
|
|
992
|
+
if (pkgList.length) {
|
|
993
|
+
pkgList = await getMvnMetadata(pkgList);
|
|
982
994
|
}
|
|
983
995
|
}
|
|
996
|
+
// Clean up
|
|
997
|
+
if (tempDir && tempDir.startsWith(tmpdir()) && rmSync) {
|
|
998
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
999
|
+
}
|
|
984
1000
|
pkgList = pkgList.concat(convertJarNSToPackages(nsMapping));
|
|
985
1001
|
return buildBomNSData(options, pkgList, "maven", {
|
|
986
1002
|
src: path,
|
|
@@ -1002,7 +1018,7 @@ export const createJavaBom = async (path, options) => {
|
|
|
1002
1018
|
// This is subsequently referred to in the dependencies list
|
|
1003
1019
|
let parentComponent = {};
|
|
1004
1020
|
// war/ear mode
|
|
1005
|
-
if (path.endsWith(".war")) {
|
|
1021
|
+
if (path.endsWith(".war") || path.endsWith(".jar")) {
|
|
1006
1022
|
// Check if the file exists
|
|
1007
1023
|
if (existsSync(path)) {
|
|
1008
1024
|
if (DEBUG_MODE) {
|
|
@@ -4800,7 +4816,12 @@ export const createMultiXBom = async (pathList, options) => {
|
|
|
4800
4816
|
}
|
|
4801
4817
|
}
|
|
4802
4818
|
} // for
|
|
4803
|
-
if (
|
|
4819
|
+
if (
|
|
4820
|
+
options.lastWorkingDir &&
|
|
4821
|
+
options.lastWorkingDir !== "" &&
|
|
4822
|
+
!options.lastWorkingDir.includes("/opt/") &&
|
|
4823
|
+
!options.lastWorkingDir.includes("/home/")
|
|
4824
|
+
) {
|
|
4804
4825
|
bomData = await createJarBom(options.lastWorkingDir, options);
|
|
4805
4826
|
if (
|
|
4806
4827
|
bomData &&
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyclonedx/cdxgen",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.2",
|
|
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>",
|
|
@@ -84,10 +84,13 @@
|
|
|
84
84
|
"optionalDependencies": {
|
|
85
85
|
"@appthreat/atom": "2.0.6",
|
|
86
86
|
"@appthreat/cdx-proto": "^0.0.4",
|
|
87
|
-
"@cyclonedx/cdxgen-plugins-bin": "^1.5.
|
|
88
|
-
"@cyclonedx/cdxgen-plugins-bin-windows-amd64": "^1.5.
|
|
89
|
-
"@cyclonedx/cdxgen-plugins-bin-arm64": "^1.5.
|
|
90
|
-
"@cyclonedx/cdxgen-plugins-bin-
|
|
87
|
+
"@cyclonedx/cdxgen-plugins-bin": "^1.5.8",
|
|
88
|
+
"@cyclonedx/cdxgen-plugins-bin-windows-amd64": "^1.5.8",
|
|
89
|
+
"@cyclonedx/cdxgen-plugins-bin-arm64": "^1.5.8",
|
|
90
|
+
"@cyclonedx/cdxgen-plugins-bin-windows-arm64": "^1.5.8",
|
|
91
|
+
"@cyclonedx/cdxgen-plugins-bin-darwin-arm64": "^1.5.8",
|
|
92
|
+
"@cyclonedx/cdxgen-plugins-bin-darwin-amd64": "^1.5.8",
|
|
93
|
+
"@cyclonedx/cdxgen-plugins-bin-ppc64": "^1.5.8",
|
|
91
94
|
"body-parser": "^1.20.2",
|
|
92
95
|
"compression": "^1.7.4",
|
|
93
96
|
"connect": "^3.7.0",
|
package/utils.js
CHANGED
|
@@ -7026,7 +7026,7 @@ export const extractJarArchive = async function (
|
|
|
7026
7026
|
existsSync(manifestname)
|
|
7027
7027
|
) {
|
|
7028
7028
|
tempDir = dirname(jarFile);
|
|
7029
|
-
} else if (!existsSync(join(tempDir, fname))) {
|
|
7029
|
+
} else if (!existsSync(join(tempDir, fname)) && lstatSync(jarFile).isFile()) {
|
|
7030
7030
|
// Only copy if the file doesn't exist
|
|
7031
7031
|
copyFileSync(jarFile, join(tempDir, fname), constants.COPYFILE_FICLONE);
|
|
7032
7032
|
}
|
|
@@ -7040,29 +7040,47 @@ export const extractJarArchive = async function (
|
|
|
7040
7040
|
"bin"
|
|
7041
7041
|
)}`;
|
|
7042
7042
|
}
|
|
7043
|
-
if (
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
);
|
|
7043
|
+
if (
|
|
7044
|
+
jarFile.endsWith(".war") ||
|
|
7045
|
+
jarFile.endsWith(".hpi") ||
|
|
7046
|
+
jarFile.endsWith(".jar")
|
|
7047
|
+
) {
|
|
7048
|
+
try {
|
|
7049
|
+
const zip = new StreamZip.async({ file: join(tempDir, fname) });
|
|
7050
|
+
await zip.extract(null, tempDir);
|
|
7051
|
+
await zip.close();
|
|
7052
|
+
} catch (e) {
|
|
7053
|
+
console.log(`Unable to extract ${join(tempDir, fname)}. Skipping.`);
|
|
7055
7054
|
return pkgList;
|
|
7056
7055
|
}
|
|
7057
7056
|
jarFiles = getAllFiles(join(tempDir, "WEB-INF", "lib"), "**/*.jar");
|
|
7058
7057
|
if (jarFile.endsWith(".hpi")) {
|
|
7059
7058
|
jarFiles.push(jarFile);
|
|
7060
7059
|
}
|
|
7060
|
+
// Some jar files could also have more jar files inside BOOT-INF directory
|
|
7061
|
+
const jarFiles2 = getAllFiles(join(tempDir, "BOOT-INF", "lib"), "**/*.jar");
|
|
7062
|
+
if (jarFiles && jarFiles2.length) {
|
|
7063
|
+
jarFiles = jarFiles.concat(jarFiles2);
|
|
7064
|
+
}
|
|
7065
|
+
// Fallback. If our jar file didn't include any jar
|
|
7066
|
+
if (jarFile.endsWith(".jar") && !jarFiles.length) {
|
|
7067
|
+
jarFiles = [join(tempDir, fname)];
|
|
7068
|
+
}
|
|
7061
7069
|
} else {
|
|
7062
7070
|
jarFiles = [join(tempDir, fname)];
|
|
7063
7071
|
}
|
|
7072
|
+
if (DEBUG_MODE) {
|
|
7073
|
+
console.log(`List of jars: ${jarFiles}`);
|
|
7074
|
+
}
|
|
7064
7075
|
if (jarFiles && jarFiles.length) {
|
|
7065
7076
|
for (const jf of jarFiles) {
|
|
7077
|
+
// If the jar file doesn't exist at the point of use, skip it
|
|
7078
|
+
if (!existsSync(jf)) {
|
|
7079
|
+
if (DEBUG_MODE) {
|
|
7080
|
+
console.log(jf, "is not a readable file");
|
|
7081
|
+
}
|
|
7082
|
+
continue;
|
|
7083
|
+
}
|
|
7066
7084
|
pomname = jf.replace(".jar", ".pom");
|
|
7067
7085
|
const jarname = basename(jf);
|
|
7068
7086
|
// Ignore test jars
|
|
@@ -7070,6 +7088,9 @@ export const extractJarArchive = async function (
|
|
|
7070
7088
|
jarname.endsWith("-tests.jar") ||
|
|
7071
7089
|
jarname.endsWith("-test-sources.jar")
|
|
7072
7090
|
) {
|
|
7091
|
+
if (DEBUG_MODE) {
|
|
7092
|
+
console.log(`Skipping tests jar ${jarname}`);
|
|
7093
|
+
}
|
|
7073
7094
|
continue;
|
|
7074
7095
|
}
|
|
7075
7096
|
const manifestDir = join(tempDir, "META-INF");
|
|
@@ -7081,16 +7102,20 @@ export const extractJarArchive = async function (
|
|
|
7081
7102
|
if (existsSync(pomname)) {
|
|
7082
7103
|
jarResult = { status: 0 };
|
|
7083
7104
|
} else {
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7105
|
+
// Unzip natively
|
|
7106
|
+
try {
|
|
7107
|
+
const zip = new StreamZip.async({ file: jf });
|
|
7108
|
+
await zip.extract(null, tempDir);
|
|
7109
|
+
await zip.close();
|
|
7110
|
+
jarResult = { status: 0 };
|
|
7111
|
+
} catch (e) {
|
|
7112
|
+
if (DEBUG_MODE) {
|
|
7113
|
+
console.log(`Unable to extract ${jf}. Skipping.`);
|
|
7114
|
+
}
|
|
7115
|
+
jarResult = { status: 1 };
|
|
7116
|
+
}
|
|
7090
7117
|
}
|
|
7091
|
-
if (jarResult.status
|
|
7092
|
-
console.error(jarResult.stdout, jarResult.stderr);
|
|
7093
|
-
} else {
|
|
7118
|
+
if (jarResult.status === 0) {
|
|
7094
7119
|
// When maven descriptor is available take group, name and version from pom.properties
|
|
7095
7120
|
// META-INF/maven/${groupId}/${artifactId}/pom.properties
|
|
7096
7121
|
// see https://maven.apache.org/shared/maven-archiver/index.html
|
|
@@ -7114,7 +7139,7 @@ export const extractJarArchive = async function (
|
|
|
7114
7139
|
const res = await cdxgenAgent.get(searchurl, {
|
|
7115
7140
|
responseType: "json",
|
|
7116
7141
|
timeout: {
|
|
7117
|
-
lookup:
|
|
7142
|
+
lookup: 1000,
|
|
7118
7143
|
connect: 5000,
|
|
7119
7144
|
secureConnect: 5000,
|
|
7120
7145
|
socket: 1000,
|
|
@@ -7132,7 +7157,11 @@ export const extractJarArchive = async function (
|
|
|
7132
7157
|
}
|
|
7133
7158
|
} catch (err) {
|
|
7134
7159
|
if (err && err.message && !err.message.includes("404")) {
|
|
7135
|
-
if (
|
|
7160
|
+
if (err.message.includes("Timeout")) {
|
|
7161
|
+
console.log(
|
|
7162
|
+
"Maven search appears to be unavailable. Search will be skipped for all remaining packages."
|
|
7163
|
+
);
|
|
7164
|
+
} else if (DEBUG_MODE) {
|
|
7136
7165
|
console.log(err);
|
|
7137
7166
|
}
|
|
7138
7167
|
search_maven_org_errors++;
|
|
@@ -7266,20 +7295,23 @@ export const extractJarArchive = async function (
|
|
|
7266
7295
|
console.log(`Ignored jar ${jarname}`, name, version);
|
|
7267
7296
|
}
|
|
7268
7297
|
}
|
|
7269
|
-
|
|
7270
|
-
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
}
|
|
7277
|
-
} catch (err) {
|
|
7278
|
-
// ignore cleanup errors
|
|
7298
|
+
}
|
|
7299
|
+
try {
|
|
7300
|
+
if (rmSync && existsSync(join(tempDir, "META-INF"))) {
|
|
7301
|
+
// Clean up META-INF
|
|
7302
|
+
rmSync(join(tempDir, "META-INF"), {
|
|
7303
|
+
recursive: true,
|
|
7304
|
+
force: true
|
|
7305
|
+
});
|
|
7279
7306
|
}
|
|
7307
|
+
} catch (err) {
|
|
7308
|
+
// ignore cleanup errors
|
|
7280
7309
|
}
|
|
7281
7310
|
} // for
|
|
7282
7311
|
} // if
|
|
7312
|
+
if (jarFiles.length !== pkgList.length) {
|
|
7313
|
+
console.log(`Obtained only ${pkgList.length} from ${jarFiles.length} jars`);
|
|
7314
|
+
}
|
|
7283
7315
|
return pkgList;
|
|
7284
7316
|
};
|
|
7285
7317
|
|
package/utils.test.js
CHANGED
|
@@ -1833,8 +1833,8 @@ test("parsePkgLock v3", async () => {
|
|
|
1833
1833
|
projectName: "cdxgen"
|
|
1834
1834
|
});
|
|
1835
1835
|
deps = parsedList.pkgList;
|
|
1836
|
-
expect(deps.length).toEqual(
|
|
1837
|
-
expect(parsedList.dependenciesList.length).toEqual(
|
|
1836
|
+
expect(deps.length).toEqual(1203);
|
|
1837
|
+
expect(parsedList.dependenciesList.length).toEqual(1203);
|
|
1838
1838
|
});
|
|
1839
1839
|
|
|
1840
1840
|
test("parseBowerJson", async () => {
|