@cyclonedx/cdxgen 9.9.8 → 9.9.9
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 +1 -0
- package/index.js +3 -3
- package/package.json +1 -1
- package/utils.js +65 -3
package/README.md
CHANGED
|
@@ -371,6 +371,7 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
|
|
|
371
371
|
| GRADLE_DEPENDENCY_TASK | By default cdxgen use the task "dependencies" to collect packages. Set to override the task name. |
|
|
372
372
|
| SBT_CACHE_DIR | Specify sbt cache directory. Useful for class name resolving |
|
|
373
373
|
| FETCH_LICENSE | Set this variable to `true` or `1` to fetch license information from the registry. npm and golang |
|
|
374
|
+
| SEARCH_MAVEN_ORG | If maven metadata is missing in jar file, a search is performed on search.maven.org. Set to `false` or `0` to disable search. |
|
|
374
375
|
| 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 |
|
|
375
376
|
| CDXGEN_TIMEOUT_MS | Default timeout for known execution involving maven, gradle or sbt |
|
|
376
377
|
| CDXGEN_SERVER_TIMEOUT_MS | Default timeout in server mode |
|
package/index.js
CHANGED
|
@@ -1085,7 +1085,7 @@ export const createJarBom = async (path, options) => {
|
|
|
1085
1085
|
if (DEBUG_MODE) {
|
|
1086
1086
|
console.log(`Parsing ${jar}`);
|
|
1087
1087
|
}
|
|
1088
|
-
const dlist = extractJarArchive(jar, tempDir);
|
|
1088
|
+
const dlist = await extractJarArchive(jar, tempDir);
|
|
1089
1089
|
if (dlist && dlist.length) {
|
|
1090
1090
|
pkgList = pkgList.concat(dlist);
|
|
1091
1091
|
}
|
|
@@ -1127,7 +1127,7 @@ export const createJavaBom = async (path, options) => {
|
|
|
1127
1127
|
}
|
|
1128
1128
|
const tempDir = mkdtempSync(join(tmpdir(), "war-deps-"));
|
|
1129
1129
|
jarNSMapping = collectJarNS(tempDir);
|
|
1130
|
-
pkgList = extractJarArchive(path, tempDir, jarNSMapping);
|
|
1130
|
+
pkgList = await extractJarArchive(path, tempDir, jarNSMapping);
|
|
1131
1131
|
if (pkgList.length) {
|
|
1132
1132
|
pkgList = await getMvnMetadata(pkgList);
|
|
1133
1133
|
}
|
|
@@ -3560,7 +3560,7 @@ export const createJenkinsBom = async (path, options) => {
|
|
|
3560
3560
|
if (DEBUG_MODE) {
|
|
3561
3561
|
console.log(`Parsing ${f}`);
|
|
3562
3562
|
}
|
|
3563
|
-
const dlist = extractJarArchive(f, tempDir);
|
|
3563
|
+
const dlist = await extractJarArchive(f, tempDir);
|
|
3564
3564
|
if (dlist && dlist.length) {
|
|
3565
3565
|
pkgList = pkgList.concat(dlist);
|
|
3566
3566
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyclonedx/cdxgen",
|
|
3
|
-
"version": "9.9.
|
|
3
|
+
"version": "9.9.9",
|
|
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>",
|
package/utils.js
CHANGED
|
@@ -19,8 +19,10 @@ import {
|
|
|
19
19
|
readFileSync,
|
|
20
20
|
rmSync,
|
|
21
21
|
unlinkSync,
|
|
22
|
-
writeFileSync
|
|
22
|
+
writeFileSync,
|
|
23
|
+
createReadStream
|
|
23
24
|
} from "node:fs";
|
|
25
|
+
import { createHash } from "node:crypto";
|
|
24
26
|
import got from "got";
|
|
25
27
|
import Arborist from "@npmcli/arborist";
|
|
26
28
|
import path from "node:path";
|
|
@@ -120,6 +122,19 @@ export const FETCH_LICENSE =
|
|
|
120
122
|
process.env.FETCH_LICENSE &&
|
|
121
123
|
["true", "1"].includes(process.env.FETCH_LICENSE);
|
|
122
124
|
|
|
125
|
+
// Wether search.maven.org will be used to identify jars without maven metadata; default, if unset shall be 'true'
|
|
126
|
+
export const SEARCH_MAVEN_ORG =
|
|
127
|
+
!process.env.SEARCH_MAVEN_ORG ||
|
|
128
|
+
["true", "1"].includes(process.env.SEARCH_MAVEN_ORG);
|
|
129
|
+
|
|
130
|
+
// circuit breaker for search maven.org
|
|
131
|
+
let search_maven_org_errors = 0;
|
|
132
|
+
const MAX_SEARCH_MAVEN_ORG_ERRORS = 5;
|
|
133
|
+
|
|
134
|
+
// circuit breaker for get repo license
|
|
135
|
+
let get_repo_license_errors = 0;
|
|
136
|
+
const MAX_GET_REPO_LICENSE_ERRORS = 5;
|
|
137
|
+
|
|
123
138
|
const MAX_LICENSE_ID_LENGTH = 100;
|
|
124
139
|
|
|
125
140
|
let PYTHON_CMD = "python";
|
|
@@ -3353,7 +3368,7 @@ export const toGitHubApiUrl = function (repoUrl, repoMetadata) {
|
|
|
3353
3368
|
export const getRepoLicense = async function (repoUrl, repoMetadata) {
|
|
3354
3369
|
let apiUrl = toGitHubApiUrl(repoUrl, repoMetadata);
|
|
3355
3370
|
// Perform github lookups
|
|
3356
|
-
if (apiUrl) {
|
|
3371
|
+
if (apiUrl && get_repo_license_errors < MAX_GET_REPO_LICENSE_ERRORS) {
|
|
3357
3372
|
let licenseUrl = apiUrl + "/license";
|
|
3358
3373
|
const headers = {};
|
|
3359
3374
|
if (process.env.GITHUB_TOKEN) {
|
|
@@ -3399,8 +3414,10 @@ export const getRepoLicense = async function (repoUrl, repoMetadata) {
|
|
|
3399
3414
|
"Please ensure GITHUB_TOKEN is set as environment variable. " +
|
|
3400
3415
|
"See: https://docs.github.com/en/rest/overview/rate-limits-for-the-rest-api"
|
|
3401
3416
|
);
|
|
3417
|
+
get_repo_license_errors++;
|
|
3402
3418
|
} else if (!err.message.includes("404")) {
|
|
3403
3419
|
console.log(err);
|
|
3420
|
+
get_repo_license_errors++;
|
|
3404
3421
|
}
|
|
3405
3422
|
}
|
|
3406
3423
|
}
|
|
@@ -6775,6 +6792,22 @@ export const getPomPropertiesFromMavenDir = function (mavenDir) {
|
|
|
6775
6792
|
return pomProperties;
|
|
6776
6793
|
};
|
|
6777
6794
|
|
|
6795
|
+
/**
|
|
6796
|
+
*
|
|
6797
|
+
* @param {string} hashName name of hash algorithm
|
|
6798
|
+
* @param {string} path path to file
|
|
6799
|
+
* @returns {Promise<String>} hex value of hash
|
|
6800
|
+
*/
|
|
6801
|
+
async function checksumFile(hashName, path) {
|
|
6802
|
+
return new Promise((resolve, reject) => {
|
|
6803
|
+
const hash = createHash(hashName);
|
|
6804
|
+
const stream = createReadStream(path);
|
|
6805
|
+
stream.on("error", (err) => reject(err));
|
|
6806
|
+
stream.on("data", (chunk) => hash.update(chunk));
|
|
6807
|
+
stream.on("end", () => resolve(hash.digest("hex")));
|
|
6808
|
+
});
|
|
6809
|
+
}
|
|
6810
|
+
|
|
6778
6811
|
/**
|
|
6779
6812
|
* Method to extract a war or ear file
|
|
6780
6813
|
*
|
|
@@ -6784,7 +6817,7 @@ export const getPomPropertiesFromMavenDir = function (mavenDir) {
|
|
|
6784
6817
|
*
|
|
6785
6818
|
* @return pkgList Package list
|
|
6786
6819
|
*/
|
|
6787
|
-
export const extractJarArchive = function (
|
|
6820
|
+
export const extractJarArchive = async function (
|
|
6788
6821
|
jarFile,
|
|
6789
6822
|
tempDir,
|
|
6790
6823
|
jarNSMapping = {}
|
|
@@ -6882,6 +6915,35 @@ export const extractJarArchive = function (
|
|
|
6882
6915
|
version = pomProperties["version"],
|
|
6883
6916
|
confidence = 1,
|
|
6884
6917
|
technique = "manifest-analysis";
|
|
6918
|
+
if (
|
|
6919
|
+
(!group || !name || !version) &&
|
|
6920
|
+
SEARCH_MAVEN_ORG &&
|
|
6921
|
+
search_maven_org_errors < MAX_SEARCH_MAVEN_ORG_ERRORS
|
|
6922
|
+
) {
|
|
6923
|
+
try {
|
|
6924
|
+
const sha = await checksumFile("sha1", jf);
|
|
6925
|
+
const searchurl =
|
|
6926
|
+
"https://search.maven.org/solrsearch/select?q=1:%22" +
|
|
6927
|
+
sha +
|
|
6928
|
+
"%22&rows=20&wt=json";
|
|
6929
|
+
const res = await cdxgenAgent.get(searchurl, {
|
|
6930
|
+
responseType: "json"
|
|
6931
|
+
});
|
|
6932
|
+
const data = res && res.body ? res.body["response"] : undefined;
|
|
6933
|
+
if (data && data["numFound"] == 1) {
|
|
6934
|
+
const jarInfo = data["docs"][0];
|
|
6935
|
+
group = jarInfo["g"];
|
|
6936
|
+
name = jarInfo["a"];
|
|
6937
|
+
version = jarInfo["v"];
|
|
6938
|
+
technique = "hash-comparison";
|
|
6939
|
+
}
|
|
6940
|
+
} catch (err) {
|
|
6941
|
+
if (err && err.message && !err.message.includes("404")) {
|
|
6942
|
+
console.log(err);
|
|
6943
|
+
search_maven_org_errors++;
|
|
6944
|
+
}
|
|
6945
|
+
}
|
|
6946
|
+
}
|
|
6885
6947
|
if ((!group || !name || !version) && existsSync(manifestFile)) {
|
|
6886
6948
|
confidence = 0.8;
|
|
6887
6949
|
const jarMetadata = parseJarManifest(
|