@coana-tech/cli 14.12.110 → 14.12.111
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/cli.mjs +130 -38
- package/package.json +1 -1
- package/reachability-analyzers-cli.mjs +13432 -13171
- package/repos/coana-tech/goana/bin/goana-darwin-amd64.gz +0 -0
- package/repos/coana-tech/goana/bin/goana-darwin-arm64.gz +0 -0
- package/repos/coana-tech/goana/bin/goana-linux-amd64.gz +0 -0
- package/repos/coana-tech/goana/bin/goana-linux-arm64.gz +0 -0
- package/repos/coana-tech/javap-service/javap-service.jar +0 -0
package/cli.mjs
CHANGED
|
@@ -206525,6 +206525,7 @@ var Spinner = class _Spinner {
|
|
|
206525
206525
|
};
|
|
206526
206526
|
|
|
206527
206527
|
// ../utils/src/command-utils.ts
|
|
206528
|
+
var DEFAULT_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
206528
206529
|
async function execAndLogOnFailure(cmd, dir, options, logLevel = "info") {
|
|
206529
206530
|
const result = await execNeverFail(cmd, dir, options);
|
|
206530
206531
|
if (result.error) logCommandOutput(result, cmd, dir, logLevel);
|
|
@@ -206549,10 +206550,11 @@ async function execNeverFail(cmd, dir, options) {
|
|
|
206549
206550
|
return new Promise((resolve45) => {
|
|
206550
206551
|
let args2;
|
|
206551
206552
|
if (typeof cmd !== "string") [cmd, ...args2] = cmd;
|
|
206553
|
+
const timeout = options?.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
206552
206554
|
const childProcess = execFile(
|
|
206553
206555
|
cmd,
|
|
206554
206556
|
args2,
|
|
206555
|
-
{ ...options, cwd: dir, maxBuffer: 1024 * 1024 * 1024, shell: args2 === void 0 },
|
|
206557
|
+
{ ...options, cwd: dir, maxBuffer: 1024 * 1024 * 1024, shell: args2 === void 0, timeout },
|
|
206556
206558
|
(error, stdout, stderr) => {
|
|
206557
206559
|
resolve45({ error, stdout, stderr });
|
|
206558
206560
|
}
|
|
@@ -225413,6 +225415,7 @@ var Spinner2 = class _Spinner {
|
|
|
225413
225415
|
};
|
|
225414
225416
|
|
|
225415
225417
|
// ../utils/dist/command-utils.js
|
|
225418
|
+
var DEFAULT_TIMEOUT_MS2 = 30 * 60 * 1e3;
|
|
225416
225419
|
async function execAndLogOnFailure3(cmd, dir, options, logLevel = "info") {
|
|
225417
225420
|
const result = await execNeverFail3(cmd, dir, options);
|
|
225418
225421
|
if (result.error)
|
|
@@ -225436,7 +225439,8 @@ async function execNeverFail3(cmd, dir, options) {
|
|
|
225436
225439
|
let args2;
|
|
225437
225440
|
if (typeof cmd !== "string")
|
|
225438
225441
|
[cmd, ...args2] = cmd;
|
|
225439
|
-
const
|
|
225442
|
+
const timeout = options?.timeout ?? DEFAULT_TIMEOUT_MS2;
|
|
225443
|
+
const childProcess = execFile2(cmd, args2, { ...options, cwd: dir, maxBuffer: 1024 * 1024 * 1024, shell: args2 === void 0, timeout }, (error, stdout, stderr) => {
|
|
225440
225444
|
resolve45({ error, stdout, stderr });
|
|
225441
225445
|
});
|
|
225442
225446
|
if (options?.pipe) {
|
|
@@ -232202,6 +232206,7 @@ var pullDockerImage = memoize(async (image) => {
|
|
|
232202
232206
|
}
|
|
232203
232207
|
return true;
|
|
232204
232208
|
});
|
|
232209
|
+
var ONE_DAY_IN_MS = 24 * 60 * 60 * 1e3;
|
|
232205
232210
|
var TMP_DIR_IN_DOCKER = "/coana-tmp";
|
|
232206
232211
|
var SOCKET_PATH_IN_DOCKER = "/coana.sock";
|
|
232207
232212
|
var OtherModulesCommunicator = class {
|
|
@@ -232268,7 +232273,7 @@ var OtherModulesCommunicator = class {
|
|
|
232268
232273
|
succeeded = await execPipeAndLogOnFailure2(
|
|
232269
232274
|
[await getNodeExecutable(), PACKAGE_MANAGER_SCRIPT_PATH(), commandName, ...finalArgs],
|
|
232270
232275
|
subprojectPath,
|
|
232271
|
-
{ env }
|
|
232276
|
+
{ env, timeout: ONE_DAY_IN_MS }
|
|
232272
232277
|
);
|
|
232273
232278
|
} else {
|
|
232274
232279
|
finalArgs.push(...extraDockerArgs ?? []);
|
|
@@ -232342,7 +232347,7 @@ var OtherModulesCommunicator = class {
|
|
|
232342
232347
|
succeeded = await execPipeAndLogOnFailure2(
|
|
232343
232348
|
[await getNodeExecutable(), scriptPath, commandName, ...finalArgs],
|
|
232344
232349
|
subprojectPath,
|
|
232345
|
-
{ env }
|
|
232350
|
+
{ env, timeout: ONE_DAY_IN_MS }
|
|
232346
232351
|
);
|
|
232347
232352
|
} else {
|
|
232348
232353
|
const dockerImage = await findReachabilityAnalyzersDockerImage(ecosystem);
|
|
@@ -232387,7 +232392,7 @@ var OtherModulesCommunicator = class {
|
|
|
232387
232392
|
-v=${this.options.coanaSocketPath}:${SOCKET_PATH_IN_DOCKER}
|
|
232388
232393
|
${await getEcosystemSpecificDockerArgs(ecosystem)}
|
|
232389
232394
|
${envArgs} ${image} ${entryPoint} ${commandName} ${args2}`;
|
|
232390
|
-
return execPipeAndLogOnFailure2(cmd, subprojectPath, { env });
|
|
232395
|
+
return execPipeAndLogOnFailure2(cmd, subprojectPath, { env, timeout: ONE_DAY_IN_MS });
|
|
232391
232396
|
}
|
|
232392
232397
|
async getWorkspacePaths(packageManagerName, subprojectPath) {
|
|
232393
232398
|
return this.runPackageManagerCommandWithOutput("getWorkspacePaths", packageManagerName, subprojectPath);
|
|
@@ -235780,7 +235785,7 @@ function toSocketReachabilitySchema(vulnerability) {
|
|
|
235780
235785
|
}
|
|
235781
235786
|
|
|
235782
235787
|
// dist/internal/socket-report-socket-dependency-tree.js
|
|
235783
|
-
function toSocketFactsSocketDependencyTree(artifacts, vulnerabilities, tier1ReachabilityScanId) {
|
|
235788
|
+
function toSocketFactsSocketDependencyTree(artifacts, vulnerabilities, tier1ReachabilityScanId, workspaceDiagnostics) {
|
|
235784
235789
|
const artifactIdToArtifact = Object.fromEntries(artifacts.map((artifact) => [artifact.id, artifact]));
|
|
235785
235790
|
for (const vulnerability of vulnerabilities) {
|
|
235786
235791
|
const component = artifactIdToArtifact[vulnerability.artifactId];
|
|
@@ -235808,7 +235813,8 @@ function toSocketFactsSocketDependencyTree(artifacts, vulnerabilities, tier1Reac
|
|
|
235808
235813
|
}
|
|
235809
235814
|
return {
|
|
235810
235815
|
components: artifacts,
|
|
235811
|
-
tier1ReachabilityScanId
|
|
235816
|
+
tier1ReachabilityScanId,
|
|
235817
|
+
workspaceDiagnostics
|
|
235812
235818
|
};
|
|
235813
235819
|
}
|
|
235814
235820
|
|
|
@@ -250700,7 +250706,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
|
|
|
250700
250706
|
}
|
|
250701
250707
|
|
|
250702
250708
|
// dist/version.js
|
|
250703
|
-
var version3 = "14.12.
|
|
250709
|
+
var version3 = "14.12.111";
|
|
250704
250710
|
|
|
250705
250711
|
// dist/cli-core.js
|
|
250706
250712
|
var { mapValues, omit, partition, pick } = import_lodash15.default;
|
|
@@ -250921,6 +250927,7 @@ var CliCore = class {
|
|
|
250921
250927
|
workspaces.forEach((workspace) => logger.info(bold(` ${workspace}`)));
|
|
250922
250928
|
});
|
|
250923
250929
|
const vulnsWithResults = [];
|
|
250930
|
+
const allWorkspaceDiagnostics = [];
|
|
250924
250931
|
const allEcosystems = Object.entries(ecosystemToWorkspaceToAnalysisData);
|
|
250925
250932
|
const totalEcosystems = allEcosystems.length;
|
|
250926
250933
|
let currentOverallWorkspace = 0;
|
|
@@ -250930,7 +250937,7 @@ var CliCore = class {
|
|
|
250930
250937
|
if (!isEcosystemToAnalyze) {
|
|
250931
250938
|
logger.info(`Skipping reachability analysis for ecosystem ${getPurlType(ecosystem)} since it is not included in the list of ecosystems to analyze.`);
|
|
250932
250939
|
}
|
|
250933
|
-
|
|
250940
|
+
const { vulnerabilities, diagnostics } = await this.runReachabilityAnalysisForWorkspaces(
|
|
250934
250941
|
workspaceToAnalysisData,
|
|
250935
250942
|
ecosystemToWorkspaceToVulnerabilities[ecosystem] ?? {},
|
|
250936
250943
|
{},
|
|
@@ -250943,15 +250950,81 @@ var CliCore = class {
|
|
|
250943
250950
|
currentOverallWorkspace++;
|
|
250944
250951
|
logger.info(bold(`Analyzing ecosystem ${ecosystem} for project ${workspaceName} (${workspaceNumber}/${totalWorkspacesForCurrentEcosystem}) - Overall progress: Project ${currentOverallWorkspace}/${totalWorkspaces}, ecosystem ${ecosystemIndex + 1}/${totalEcosystems}`));
|
|
250945
250952
|
}
|
|
250946
|
-
)
|
|
250953
|
+
);
|
|
250954
|
+
vulnsWithResults.push(...Object.values(vulnerabilities).flat());
|
|
250955
|
+
for (const [workspacePath, workspaceDiagnostics] of Object.entries(diagnostics)) {
|
|
250956
|
+
allWorkspaceDiagnostics.push({
|
|
250957
|
+
subprojectPath: relative19(this.rootWorkingDirectory, workspacePath) || ".",
|
|
250958
|
+
workspacePath: ".",
|
|
250959
|
+
purl_type: getPurlType(ecosystem),
|
|
250960
|
+
diagnostics: workspaceDiagnostics
|
|
250961
|
+
});
|
|
250962
|
+
}
|
|
250947
250963
|
this.sendProgress("RUN_ON_SUBPROJECT", false, this.rootWorkingDirectory);
|
|
250948
250964
|
}
|
|
250965
|
+
this.displayWorkspaceDiagnosticsSummary(allWorkspaceDiagnostics);
|
|
250949
250966
|
await this.shareLogIfAnalysisError(vulnsWithResults);
|
|
250950
|
-
const socketReport = toSocketFactsSocketDependencyTree(artifacts, vulnsWithResults, this.reportId);
|
|
250967
|
+
const socketReport = toSocketFactsSocketDependencyTree(artifacts, vulnsWithResults, this.reportId, allWorkspaceDiagnostics);
|
|
250951
250968
|
const outputFile = resolve43(this.options.socketMode);
|
|
250952
250969
|
await writeFile14(outputFile, JSON.stringify(socketReport, null, 2));
|
|
250953
250970
|
logger.info(kleur_default.green(`Socket report written to: ${outputFile}`));
|
|
250954
250971
|
}
|
|
250972
|
+
displayWorkspaceDiagnosticsSummary(diagnosticsEntries) {
|
|
250973
|
+
const warnings = [];
|
|
250974
|
+
const infos = [];
|
|
250975
|
+
const typeToEntry = /* @__PURE__ */ new Map();
|
|
250976
|
+
for (const entry of diagnosticsEntries) {
|
|
250977
|
+
for (const warning of entry.diagnostics.warnings) {
|
|
250978
|
+
const existing = typeToEntry.get(warning.type);
|
|
250979
|
+
const workspaceLabel = `${entry.subprojectPath} (${entry.purl_type})`;
|
|
250980
|
+
if (existing) {
|
|
250981
|
+
existing.workspaces.push(workspaceLabel);
|
|
250982
|
+
} else {
|
|
250983
|
+
const newEntry = { message: warning.message, workspaces: [workspaceLabel], severity: warning.severity };
|
|
250984
|
+
typeToEntry.set(warning.type, newEntry);
|
|
250985
|
+
if (warning.severity === "warning") {
|
|
250986
|
+
warnings.push(newEntry);
|
|
250987
|
+
} else {
|
|
250988
|
+
infos.push(newEntry);
|
|
250989
|
+
}
|
|
250990
|
+
}
|
|
250991
|
+
}
|
|
250992
|
+
}
|
|
250993
|
+
if (warnings.length === 0 && infos.length === 0) {
|
|
250994
|
+
return;
|
|
250995
|
+
}
|
|
250996
|
+
logger.info("");
|
|
250997
|
+
if (warnings.length > 0) {
|
|
250998
|
+
logger.info(bold(kleur_default.red("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
|
|
250999
|
+
logger.info(bold(kleur_default.red(" REACHABILITY ANALYSIS WARNINGS ")));
|
|
251000
|
+
logger.info(bold(kleur_default.red("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
|
|
251001
|
+
for (const { message: message2, workspaces } of warnings) {
|
|
251002
|
+
logger.info("");
|
|
251003
|
+
logger.info(kleur_default.red(`\u26A0 ${message2}:`));
|
|
251004
|
+
for (const workspace of workspaces) {
|
|
251005
|
+
logger.info(kleur_default.red(` ${workspace}`));
|
|
251006
|
+
}
|
|
251007
|
+
}
|
|
251008
|
+
logger.info("");
|
|
251009
|
+
logger.info(bold(kleur_default.red("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
|
|
251010
|
+
logger.info("");
|
|
251011
|
+
}
|
|
251012
|
+
if (infos.length > 0) {
|
|
251013
|
+
logger.info(bold(kleur_default.cyan("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
|
|
251014
|
+
logger.info(bold(kleur_default.cyan(" REACHABILITY ANALYSIS INFO ")));
|
|
251015
|
+
logger.info(bold(kleur_default.cyan("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
|
|
251016
|
+
for (const { message: message2, workspaces } of infos) {
|
|
251017
|
+
logger.info("");
|
|
251018
|
+
logger.info(kleur_default.cyan(`\u2139 ${message2}:`));
|
|
251019
|
+
for (const workspace of workspaces) {
|
|
251020
|
+
logger.info(kleur_default.cyan(` ${workspace}`));
|
|
251021
|
+
}
|
|
251022
|
+
}
|
|
251023
|
+
logger.info("");
|
|
251024
|
+
logger.info(bold(kleur_default.cyan("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")));
|
|
251025
|
+
logger.info("");
|
|
251026
|
+
}
|
|
251027
|
+
}
|
|
250955
251028
|
async shareLogIfAnalysisError(vulns) {
|
|
250956
251029
|
if (this.dashboardAPI.disableAnalyticsSharing) {
|
|
250957
251030
|
return;
|
|
@@ -251180,7 +251253,7 @@ Subproject: ${subproject}`);
|
|
|
251180
251253
|
const { ecosystem, subprojectPath, workspacePaths } = subProjAndWsPath;
|
|
251181
251254
|
const { projectInfo, workspaceToVulnerabilities } = await this.getDependencyTreeAndVulnerabilities(otherModulesCommunicator, subProjAndWsPath);
|
|
251182
251255
|
const workspacePathToDataForAnalysis = Object.fromEntries(Object.entries(projectInfo).map(([workspacePath, projectInfo2]) => [workspacePath, projectInfo2.dataForAnalysis]));
|
|
251183
|
-
const workspaceToAugmentedVulnerabilities = await this.runReachabilityAnalysisForWorkspaces(workspacePathToDataForAnalysis, workspaceToVulnerabilities, Object.fromEntries(workspacePaths.map((wsPath) => [wsPath, projectInfo[wsPath].dataForAnalysis.directDependenciesMap ?? {}])), otherModulesCommunicator, subprojectPath, ecosystem, reachabilitySupported);
|
|
251256
|
+
const { vulnerabilities: workspaceToAugmentedVulnerabilities } = await this.runReachabilityAnalysisForWorkspaces(workspacePathToDataForAnalysis, workspaceToVulnerabilities, Object.fromEntries(workspacePaths.map((wsPath) => [wsPath, projectInfo[wsPath].dataForAnalysis.directDependenciesMap ?? {}])), otherModulesCommunicator, subprojectPath, ecosystem, reachabilitySupported);
|
|
251184
251257
|
return workspacePaths.filter((workspacePath) => {
|
|
251185
251258
|
return workspaceToAugmentedVulnerabilities[workspacePath] !== void 0;
|
|
251186
251259
|
}).map((workspacePath) => {
|
|
@@ -251204,12 +251277,12 @@ Subproject: ${subproject}`);
|
|
|
251204
251277
|
let npmAnalysisMutex = Promise.resolve();
|
|
251205
251278
|
const workspaceToAugmentedVulnerabilities = Object.fromEntries(await asyncMap(workspaces, async (workspacePath, index2) => {
|
|
251206
251279
|
analysisStarting?.(workspacePath, index2 + 1, totalWorkspaces);
|
|
251207
|
-
const
|
|
251280
|
+
const vulnerabilities2 = workspaceToVulnerabilities[workspacePath] ?? [];
|
|
251208
251281
|
const workspacePrefix = shouldIncludeWorkspaceInLogs ? `[${workspacePath}] ` : "";
|
|
251209
|
-
logger.info(`${workspacePrefix}Process workspace ${workspacePath} with ${
|
|
251282
|
+
logger.info(`${workspacePrefix}Process workspace ${workspacePath} with ${vulnerabilities2.length} ${pluralize(vulnerabilities2.length, "vulnerability")}`);
|
|
251210
251283
|
try {
|
|
251211
251284
|
const dataForAnalysis = workspacePathToDataForAnalysis[workspacePath];
|
|
251212
|
-
const [vulnsSatisfyingThreshold, vulnerabilitiesBelowThreshold] = this.options.minSeverity ? partition(
|
|
251285
|
+
const [vulnsSatisfyingThreshold, vulnerabilitiesBelowThreshold] = this.options.minSeverity ? partition(vulnerabilities2, (v) => !v.severity || shouldAnalyzeBasedOnSeverity(v.severity, this.options.minSeverity)) : [vulnerabilities2, []];
|
|
251213
251286
|
const [vulnsUnreachableFromPrecomputation, vulnerabilitiesToAnalyze] = this.options.useUnreachableFromPrecomputation ? partition(vulnsSatisfyingThreshold, (v) => "precomputedReachabilityResult" in v && v.precomputedReachabilityResult?.type === "unreachable") : [[], vulnsSatisfyingThreshold];
|
|
251214
251287
|
const vulnerabilitiesBelowThresholdWithResults = vulnerabilitiesBelowThreshold.map((v) => ({
|
|
251215
251288
|
...v,
|
|
@@ -251226,25 +251299,33 @@ Subproject: ${subproject}`);
|
|
|
251226
251299
|
}
|
|
251227
251300
|
}));
|
|
251228
251301
|
if (vulnerabilitiesBelowThreshold.length > 0) {
|
|
251229
|
-
logger.info(`${workspacePrefix}Reachability analysis skipped for ${vulnerabilitiesBelowThreshold.length} ${pluralize(
|
|
251302
|
+
logger.info(`${workspacePrefix}Reachability analysis skipped for ${vulnerabilitiesBelowThreshold.length} ${pluralize(vulnerabilities2.length, "vulnerability")} with severity below the min severity threshold: ${this.options.minSeverity}`);
|
|
251230
251303
|
}
|
|
251231
251304
|
if (vulnsUnreachableFromPrecomputation.length > 0) {
|
|
251232
|
-
logger.info(`${workspacePrefix}Reachability analysis skipped for ${vulnsUnreachableFromPrecomputation.length} ${pluralize(
|
|
251305
|
+
logger.info(`${workspacePrefix}Reachability analysis skipped for ${vulnsUnreachableFromPrecomputation.length} ${pluralize(vulnerabilities2.length, "vulnerability")} that ${vulnerabilities2.length !== 1 ? "are" : "is"} already known to be unreachable from precomputed (Tier 2) reachability analysis`);
|
|
251233
251306
|
}
|
|
251234
251307
|
if (vulnerabilitiesToAnalyze.length > 0) {
|
|
251235
|
-
logger.info(`${workspacePrefix}Running reachability analysis for ${vulnerabilitiesToAnalyze.length} ${pluralize(
|
|
251308
|
+
logger.info(`${workspacePrefix}Running reachability analysis for ${vulnerabilitiesToAnalyze.length} ${pluralize(vulnerabilities2.length, "vulnerability")}`);
|
|
251236
251309
|
}
|
|
251237
251310
|
let augmentedVulnerabilitiesToAnalyze;
|
|
251311
|
+
let workspaceDiagnostics = {
|
|
251312
|
+
sourceFilesDetected: "UNKNOWN",
|
|
251313
|
+
preinstalledDependencies: "UNKNOWN",
|
|
251314
|
+
warnings: []
|
|
251315
|
+
};
|
|
251238
251316
|
if (vulnerabilitiesToAnalyze.length === 0) {
|
|
251239
251317
|
augmentedVulnerabilitiesToAnalyze = [];
|
|
251240
251318
|
} else if (reachabilitySupported && !this.shouldExcludeAnalyzingWorkspace(subprojectPath, workspacePath, workspacePrefix)) {
|
|
251319
|
+
let analysisResult;
|
|
251241
251320
|
if (ecosystem === "NPM" && concurrency > 1) {
|
|
251242
|
-
|
|
251321
|
+
analysisResult = await this.runReachabilityAnalysisWithoutConcurrency(async () => npmAnalysisMutex, (mutex) => {
|
|
251243
251322
|
npmAnalysisMutex = mutex;
|
|
251244
251323
|
}, otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilitiesToAnalyze, workspacePrefix);
|
|
251245
251324
|
} else {
|
|
251246
|
-
|
|
251325
|
+
analysisResult = await this.runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilitiesToAnalyze, workspacePrefix);
|
|
251247
251326
|
}
|
|
251327
|
+
augmentedVulnerabilitiesToAnalyze = analysisResult.vulnerabilities;
|
|
251328
|
+
workspaceDiagnostics = analysisResult.diagnostics;
|
|
251248
251329
|
} else {
|
|
251249
251330
|
augmentedVulnerabilitiesToAnalyze = vulnerabilitiesToAnalyze.map((v) => ({
|
|
251250
251331
|
...v,
|
|
@@ -251259,26 +251340,32 @@ Subproject: ${subproject}`);
|
|
|
251259
251340
|
...augmentedVulnerabilitiesToAnalyze,
|
|
251260
251341
|
...vulnerabilitiesBelowThresholdWithResults
|
|
251261
251342
|
];
|
|
251262
|
-
return [workspacePath, augmentedVulnerabilities];
|
|
251343
|
+
return [workspacePath, { vulnerabilities: augmentedVulnerabilities, diagnostics: workspaceDiagnostics }];
|
|
251263
251344
|
} catch (e) {
|
|
251264
251345
|
logger.error(`${workspacePrefix}Reachability analysis failed for workspace ${workspacePath} in subproject ${subprojectPath}: ${e.message}`);
|
|
251265
251346
|
return [
|
|
251266
251347
|
workspacePath,
|
|
251267
|
-
|
|
251268
|
-
|
|
251269
|
-
|
|
251270
|
-
|
|
251271
|
-
|
|
251272
|
-
|
|
251273
|
-
|
|
251348
|
+
{
|
|
251349
|
+
vulnerabilities: vulnerabilities2.map((v) => ({
|
|
251350
|
+
...v,
|
|
251351
|
+
results: {
|
|
251352
|
+
type: "otherError",
|
|
251353
|
+
message: e.message || "Unknown error"
|
|
251354
|
+
}
|
|
251355
|
+
})),
|
|
251356
|
+
diagnostics: { sourceFilesDetected: "UNKNOWN", preinstalledDependencies: "UNKNOWN", warnings: [] }
|
|
251357
|
+
}
|
|
251274
251358
|
];
|
|
251275
251359
|
}
|
|
251276
251360
|
}, concurrency));
|
|
251277
|
-
const
|
|
251361
|
+
const successfulWorkspaceResults = Object.fromEntries(Object.entries(workspaceToAugmentedVulnerabilities).filter(([_, result]) => result !== void 0));
|
|
251362
|
+
const successfulWorkspaceToAugmentedVulnerabilities = mapValues(successfulWorkspaceResults, (result) => result.vulnerabilities);
|
|
251278
251363
|
if (ecosystem === "MAVEN" || ecosystem === "NUGET") {
|
|
251279
251364
|
pruneVulnerablePathsToShortestPathsOnly(ecosystem, successfulWorkspaceToAugmentedVulnerabilities);
|
|
251280
251365
|
}
|
|
251281
|
-
|
|
251366
|
+
const vulnerabilities = mapValues(successfulWorkspaceToAugmentedVulnerabilities, (augmentedVulnerabilities, workspacePath) => this.transformToReportVulnerabilities(augmentedVulnerabilities, workspaceToDirectDependencies[workspacePath] ?? {}, subprojectPath, workspacePath, this.rootWorkingDirectory));
|
|
251367
|
+
const diagnostics = mapValues(successfulWorkspaceResults, (result) => result.diagnostics);
|
|
251368
|
+
return { vulnerabilities, diagnostics };
|
|
251282
251369
|
function pruneVulnerablePathsToShortestPathsOnly(ecosystem2, workspaceToAugmentedVulnerabilities2) {
|
|
251283
251370
|
const vulnerabilityToWorkspaceToStacks = {};
|
|
251284
251371
|
for (const [workspacePath, augmentedVulnerabilities] of Object.entries(workspaceToAugmentedVulnerabilities2))
|
|
@@ -251329,13 +251416,13 @@ Subproject: ${subproject}`);
|
|
|
251329
251416
|
resolveCurrentAnalysis = resolve45;
|
|
251330
251417
|
}));
|
|
251331
251418
|
await previousAnalysis;
|
|
251332
|
-
let
|
|
251419
|
+
let analysisResult;
|
|
251333
251420
|
try {
|
|
251334
|
-
|
|
251421
|
+
analysisResult = await this.runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilitiesToAnalyze, workspacePrefix);
|
|
251335
251422
|
} finally {
|
|
251336
251423
|
resolveCurrentAnalysis();
|
|
251337
251424
|
}
|
|
251338
|
-
return
|
|
251425
|
+
return analysisResult;
|
|
251339
251426
|
}
|
|
251340
251427
|
shouldExcludeAnalyzingWorkspace(subprojectPath, workspacePath, workspacePrefix = "") {
|
|
251341
251428
|
const shouldExcludeWorkspaceForAnalysis = shouldIgnoreDueToExcludeDirsOrChangedFiles({
|
|
@@ -251354,10 +251441,14 @@ Subproject: ${subproject}`);
|
|
|
251354
251441
|
for (const v of result)
|
|
251355
251442
|
v.results = typeof v.vulnerabilityAccessPaths === "string" ? { type: "noAnalysisCheck", message: v.vulnerabilityAccessPaths } : { type: "missingVulnerabilityPattern" };
|
|
251356
251443
|
logger.info(`${workspacePrefix}Reachability analysis not possible for ${result.length} of the ${pluralize(vulnerabilities.length, "vulnerability")}`);
|
|
251357
|
-
if (!vulnsWithActualAPIPatterns.length)
|
|
251358
|
-
return
|
|
251444
|
+
if (!vulnsWithActualAPIPatterns.length) {
|
|
251445
|
+
return {
|
|
251446
|
+
vulnerabilities: result,
|
|
251447
|
+
diagnostics: { sourceFilesDetected: "UNKNOWN", preinstalledDependencies: "UNKNOWN", warnings: [] }
|
|
251448
|
+
};
|
|
251449
|
+
}
|
|
251359
251450
|
this.sendProgress("REACHABILITY_ANALYSIS", true, subprojectPath, workspacePath);
|
|
251360
|
-
|
|
251451
|
+
const analysisResult = await otherModulesCommunicator.runReachabilityAnalysis(subprojectPath, workspacePath, workspaceData, ecosystem, vulnerabilities, {
|
|
251361
251452
|
timeoutSeconds: {
|
|
251362
251453
|
allVulnRuns: this.analysisTimeoutInSeconds,
|
|
251363
251454
|
bucketedRuns: bucketedAnalysisTimeoutInSeconds
|
|
@@ -251371,9 +251462,10 @@ Subproject: ${subproject}`);
|
|
|
251371
251462
|
disableBucketing: !!this.options.disableAnalysisSplitting,
|
|
251372
251463
|
lightweightReachability: this.options.lightweightReachability,
|
|
251373
251464
|
skipCacheUsage: this.options.skipCacheUsage
|
|
251374
|
-
})
|
|
251465
|
+
});
|
|
251466
|
+
result.push(...analysisResult.vulnerabilities);
|
|
251375
251467
|
this.sendProgress("REACHABILITY_ANALYSIS", false, subprojectPath, workspacePath);
|
|
251376
|
-
return result;
|
|
251468
|
+
return { vulnerabilities: result, diagnostics: analysisResult.diagnostics };
|
|
251377
251469
|
}
|
|
251378
251470
|
async sendProgress(type, isStartEvent, subprojectPath, workspacePath) {
|
|
251379
251471
|
await this.dashboardAPI.registerCLIProgress({
|