@coana-tech/cli 14.11.8 → 14.11.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/cli.mjs
CHANGED
|
@@ -209443,7 +209443,7 @@ function shouldIgnoreDir(dir) {
|
|
|
209443
209443
|
return dirsToIgnore.includes(dir);
|
|
209444
209444
|
}
|
|
209445
209445
|
function shouldIgnoreDueToExcludeDirsOrChangedFiles({ mainProjectDir, excludeDirs, changedFiles }, fullPath) {
|
|
209446
|
-
const relativeToProjectDir = relative9(mainProjectDir, fullPath);
|
|
209446
|
+
const relativeToProjectDir = relative9(mainProjectDir, fullPath) || ".";
|
|
209447
209447
|
return !!(isMatch3(relativeToProjectDir, excludeDirs) || changedFiles && !changedFiles.some((changedFile) => changedFile.startsWith(relativeToProjectDir)));
|
|
209448
209448
|
}
|
|
209449
209449
|
|
|
@@ -210096,7 +210096,7 @@ function inferWorkspaceFromManifestPath(ecosystem, manifestPath, properPythonPro
|
|
|
210096
210096
|
return dirname8(manifestPath) || ".";
|
|
210097
210097
|
}
|
|
210098
210098
|
default: {
|
|
210099
|
-
return
|
|
210099
|
+
return ".";
|
|
210100
210100
|
}
|
|
210101
210101
|
}
|
|
210102
210102
|
}
|
|
@@ -210384,6 +210384,8 @@ function toSocketReachabilitySchema(vulnerability) {
|
|
|
210384
210384
|
return { type: "error", error: vulnerability.codeAwareScanResult.message };
|
|
210385
210385
|
}
|
|
210386
210386
|
if (vulnerability.codeAwareScanResult.type === "otherError") {
|
|
210387
|
+
if (vulnerability.codeAwareScanResult.message.includes("Reachability analysis for languages using"))
|
|
210388
|
+
return { type: "unknown" };
|
|
210387
210389
|
return { type: "error", error: vulnerability.codeAwareScanResult.message };
|
|
210388
210390
|
}
|
|
210389
210391
|
if (vulnerability.codeAwareScanResult.type === "success") {
|
|
@@ -225338,7 +225340,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
|
|
|
225338
225340
|
}
|
|
225339
225341
|
|
|
225340
225342
|
// dist/version.js
|
|
225341
|
-
var version2 = "14.11.
|
|
225343
|
+
var version2 = "14.11.9";
|
|
225342
225344
|
|
|
225343
225345
|
// dist/cli-core.js
|
|
225344
225346
|
var { mapValues, omit, partition, pick } = import_lodash15.default;
|
|
@@ -225423,9 +225425,18 @@ var CliCore = class {
|
|
|
225423
225425
|
if (this.options.ecosystems)
|
|
225424
225426
|
this.options.ecosystems.forEach((ecosystem) => {
|
|
225425
225427
|
if (!ECOSYSTEMS_WITH_TRADITIONAL_SCA_SUPPORT.includes(ecosystem)) {
|
|
225426
|
-
throw new Error(`Invalid ecosystem: ${ecosystem}
|
|
225428
|
+
throw new Error(`Invalid ecosystem: ${ecosystem}. Supported ecosystems are: ${ECOSYSTEMS_WITH_TRADITIONAL_SCA_SUPPORT.join(", ")}`);
|
|
225427
225429
|
}
|
|
225428
225430
|
});
|
|
225431
|
+
if (this.options.purlTypes) {
|
|
225432
|
+
this.options.purlTypes.forEach((purlType) => {
|
|
225433
|
+
try {
|
|
225434
|
+
getAdvisoryEcosystemFromPurlType(purlType);
|
|
225435
|
+
} catch (e) {
|
|
225436
|
+
throw new Error(`Invalid purl type: ${purlType}. Supported purl types are: ${ECOSYSTEMS_WITH_TRADITIONAL_SCA_SUPPORT.map((ecosystem) => getPurlType(ecosystem)).join(", ")}`);
|
|
225437
|
+
}
|
|
225438
|
+
});
|
|
225439
|
+
}
|
|
225429
225440
|
if (this.options.manifestsTarHash && !this.options.socketMode) {
|
|
225430
225441
|
throw new Error("The --manifests-tar-hash option is only supported when using --socket-mode");
|
|
225431
225442
|
}
|
|
@@ -225494,6 +225505,10 @@ var CliCore = class {
|
|
|
225494
225505
|
const vulnsWithResults = [];
|
|
225495
225506
|
for (const [ecosystem, workspaceToAnalysisData] of Object.entries(ecosystemToWorkspaceToAnalysisData)) {
|
|
225496
225507
|
this.sendProgress("RUN_ON_SUBPROJECT", true, this.rootWorkingDirectory);
|
|
225508
|
+
const isEcosystemToAnalyze = !this.options.purlTypes || this.options.purlTypes.some((purlType) => getAdvisoryEcosystemFromPurlType(purlType) === ecosystem);
|
|
225509
|
+
if (!isEcosystemToAnalyze) {
|
|
225510
|
+
logger.info(`Skipping reachability analysis for ecosystem ${getPurlType(ecosystem)} due to it not being included in the list of ecosystems to analyze.`);
|
|
225511
|
+
}
|
|
225497
225512
|
vulnsWithResults.push(...Object.values(await this.runReachabilityAnalysisForWorkspaces(
|
|
225498
225513
|
workspaceToAnalysisData,
|
|
225499
225514
|
ecosystemToWorkspaceToVulnerabilities[ecosystem] ?? {},
|
|
@@ -225502,7 +225517,7 @@ var CliCore = class {
|
|
|
225502
225517
|
otherModulesCommunicator,
|
|
225503
225518
|
this.rootWorkingDirectory,
|
|
225504
225519
|
ecosystem,
|
|
225505
|
-
|
|
225520
|
+
["NPM", "PIP"].includes(ecosystem) && isEcosystemToAnalyze
|
|
225506
225521
|
)).flat());
|
|
225507
225522
|
this.sendProgress("RUN_ON_SUBPROJECT", false, this.rootWorkingDirectory);
|
|
225508
225523
|
}
|
|
@@ -225760,10 +225775,10 @@ Subproject: ${subproject}`);
|
|
|
225760
225775
|
}
|
|
225761
225776
|
async runReachabilityAnalysisForWorkspaces(workspacePathToDataForAnalysis, workspaceToVulnerabilities, workspaceToDirectDependencies, otherModulesCommunicator, subprojectPath, ecosystem, reachabilitySupported) {
|
|
225762
225777
|
const workspaceToAugmentedVulnerabilities = Object.fromEntries(await asyncMap(Object.keys(workspacePathToDataForAnalysis), async (workspacePath) => {
|
|
225778
|
+
const vulnerabilities = workspaceToVulnerabilities[workspacePath];
|
|
225763
225779
|
try {
|
|
225764
225780
|
const dataForAnalysis = workspacePathToDataForAnalysis[workspacePath];
|
|
225765
|
-
const
|
|
225766
|
-
const augmentedVulnerabilities = reachabilitySupported ? await this.runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilities) : vulnerabilities.map((v) => ({
|
|
225781
|
+
const augmentedVulnerabilities = reachabilitySupported && !this.shouldExcludeAnalyzingWorkspace(subprojectPath, workspacePath) ? await this.runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilities) : vulnerabilities.map((v) => ({
|
|
225767
225782
|
...v,
|
|
225768
225783
|
results: {
|
|
225769
225784
|
type: "otherError",
|
|
@@ -225773,17 +225788,16 @@ Subproject: ${subproject}`);
|
|
|
225773
225788
|
return [workspacePath, augmentedVulnerabilities];
|
|
225774
225789
|
} catch (e) {
|
|
225775
225790
|
logger.error(`Reachability analysis failed for workspace ${workspacePath} in subproject ${subprojectPath}: ${e.message}`);
|
|
225776
|
-
|
|
225777
|
-
|
|
225778
|
-
|
|
225779
|
-
|
|
225780
|
-
|
|
225781
|
-
|
|
225782
|
-
|
|
225783
|
-
|
|
225784
|
-
|
|
225785
|
-
|
|
225786
|
-
throw e;
|
|
225791
|
+
return [
|
|
225792
|
+
workspacePath,
|
|
225793
|
+
vulnerabilities.map((v) => ({
|
|
225794
|
+
...v,
|
|
225795
|
+
results: {
|
|
225796
|
+
type: "otherError",
|
|
225797
|
+
message: e.message || "Unknown error"
|
|
225798
|
+
}
|
|
225799
|
+
}))
|
|
225800
|
+
];
|
|
225787
225801
|
}
|
|
225788
225802
|
}));
|
|
225789
225803
|
const successfulWorkspaceToAugmentedVulnerabilities = Object.fromEntries(Object.entries(workspaceToAugmentedVulnerabilities).filter(([_, vulns]) => vulns !== void 0));
|
|
@@ -225838,6 +225852,18 @@ Subproject: ${subproject}`);
|
|
|
225838
225852
|
}
|
|
225839
225853
|
}
|
|
225840
225854
|
}
|
|
225855
|
+
shouldExcludeAnalyzingWorkspace(subprojectPath, workspacePath) {
|
|
225856
|
+
const shouldExcludeWorkspaceForAnalysis = shouldIgnoreDueToExcludeDirsOrChangedFiles({
|
|
225857
|
+
mainProjectDir: this.rootWorkingDirectory,
|
|
225858
|
+
excludeDirs: this.options.excludeDirs ?? [],
|
|
225859
|
+
changedFiles: this.options.changedFiles,
|
|
225860
|
+
includeDirs: this.options.includeDirs ?? []
|
|
225861
|
+
}, resolve25(subprojectPath, workspacePath));
|
|
225862
|
+
if (shouldExcludeWorkspaceForAnalysis) {
|
|
225863
|
+
logger.info(`Skipping reachability analysis for workspace ${workspacePath} due to it being excluded.`);
|
|
225864
|
+
}
|
|
225865
|
+
return shouldExcludeWorkspaceForAnalysis;
|
|
225866
|
+
}
|
|
225841
225867
|
async runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, workspaceData, ecosystem, vulnerabilities) {
|
|
225842
225868
|
const [vulnsWithActualAPIPatterns, result] = partition(vulnerabilities, (v) => Array.isArray(v.vulnerabilityAccessPaths));
|
|
225843
225869
|
for (const v of result)
|
|
@@ -226255,9 +226281,10 @@ function computeSBOMTaskArtifacts(dependencyTrees) {
|
|
|
226255
226281
|
// dist/index.js
|
|
226256
226282
|
var program2 = new Command();
|
|
226257
226283
|
var run2 = new Command();
|
|
226258
|
-
run2.name("run").argument("<path>", "File system path to folder containing the project").option("-o, --output-dir <path>", "Write json report to <path>/coana-report.json").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("-p, --print-report", "Print the report to the console", false).option("--offline-database <path>", "Path to a coana-offline-db.json file for running the CLI without internet connectivity", void 0).option("-t, --timeout <timeout>", "Set API <timeout> in milliseconds to Coana backend.", "300000").option("-a, --analysis-timeout <timeout>", "Set <timeout> in seconds for each reachability analysis run").option("--memory-limit <memoryInMB>", "Set memory limit for analysis to <memoryInMB> megabytes of memory.", "8192").option("-c, --concurrency <concurrency>", "Set the maximum number of concurrent reachability analysis runs. It's recommended to choose a concurrency level that ensures that each analysis run has at least the --memory-limit amount of memory available.", "1").option("--api-key <key>", "Set the Coana dashboard API key. By setting you also enable the dashboard integration.").addOption(new Option("--write-report-to-file", "Write the report dashboard-compatible report to dashboard-report.json. This report may help the Coana team debug issues with the report insertion mechanism.").default(false).hideHelp()).option("--project-name <repoName>", "Set the name of the repository. Used for dashboard integration.").option("--repo-url <repoUrl>", "Set the URL of the repository. Used for dashboard integration.").option("--include-dirs <relativeDirs...>", "globs for directories to include from the detection of subprojects (space-separated)(use relative paths from the project root). Notice, projects that are not included may still be scanned if they are referenced from included projects.").option("--exclude-dirs <relativeDirs...>", "globs for directories to exclude from the detection of subprojects (space-separated)(use relative paths from the project root). Notice, excluded projects may still be scanned if they are referenced from non-excluded projects.").option("--disable-analysis-splitting", "Limits Coana to at most 1 reachability analysis run per workspace").option("--print-analysis-log-file", "Store log output from the JavaScript/TypeScript reachability analysis in the file js-analysis.log file in the root of each workspace", false).option("--entry-points <entryPoints...>", "List of files to analyze for root workspace. The reachability analysis automatically analyzes all files used by the entry points. If not provided, all JavaScript and TypeScript files are considered entry points. For non-root workspaces, all JavaScript and TypeScript files are analyzed as well.").option("--include-projects-with-no-reachability-support", "Also runs Coana on projects where we support traditional SCA, but does not yet support reachability analysis.", false).option("--ecosystems <ecosystems...>", "List of ecosystems to analyze (space-separated). Currently NPM, PIP, MAVEN, NUGET and GO are supported. Default is all supported ecosystems.").option("--changed-files <files...>", "List of files that have changed. If provided, Coana only analyzes workspaces and modules that contain changed files.").option("--disable-report-submission", "Disable the submission of the report to the Coana dashboard. Used by the pipeline blocking feature.", false).option("--disable-analytics-sharing", "Disable analytics sharing.", false).option("--provider-project <path>", "File system path to folder containing the provider project (Only supported for Maven, Gradle, and SBT)").option("--provider-workspaces <dirs...>", "List of workspaces that build the provided runtime environment (Only supported for Maven, Gradle, and SBT)", (paths) => paths.split(" ")).option("--lightweight-reachability", "Runs Coana in lightweight mode. This increases analysis speed but also raises the risk of Coana misclassifying the reachability of certain complex vulnerabilities. Recommended only for use with Coana Guardrail mode.", false).addOption(new Option("--run-without-docker", "Run package managers and reachability analyzers without using docker").default(process.env.RUN_WITHOUT_DOCKER === "true").hideHelp()).addOption(new Option("--run-env <env>", "Specifies the environment in which the CLI is run. So far only MANAGED_SCAN and UNKNOWN are supported.").default("UNKNOWN").choices(["UNKNOWN", "MANAGED_SCAN"]).hideHelp()).addOption(new Option("--guardrail-mode", "Run Coana in guardrail mode. This mode is used to prevent new reachable vulnerabilities from being introduced into the codebase. Usually run as a CI check when pushing new commits to a pull request.")).option("--ignore-failing-workspaces", "Continue processing when a workspace fails instead of exiting. Failed workspaces will be logged at termination.", false).addOption(new Option("--socket-mode <output-file>", "Run Coana in socket mode and write report to <output-file>").hideHelp()).addOption(new Option("--manifests-tar-hash <hash>", "Hash of the tarball containing all manifest files already uploaded to Socket. If provided, Socket will be used for computing dependency trees.").hideHelp()).version(version2).configureHelp({ sortOptions: true }).action(async (path2, options) => {
|
|
226284
|
+
run2.name("run").argument("<path>", "File system path to folder containing the project").option("-o, --output-dir <path>", "Write json report to <path>/coana-report.json").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("-p, --print-report", "Print the report to the console", false).option("--offline-database <path>", "Path to a coana-offline-db.json file for running the CLI without internet connectivity", void 0).option("-t, --timeout <timeout>", "Set API <timeout> in milliseconds to Coana backend.", "300000").option("-a, --analysis-timeout <timeout>", "Set <timeout> in seconds for each reachability analysis run").option("--memory-limit <memoryInMB>", "Set memory limit for analysis to <memoryInMB> megabytes of memory.", "8192").option("-c, --concurrency <concurrency>", "Set the maximum number of concurrent reachability analysis runs. It's recommended to choose a concurrency level that ensures that each analysis run has at least the --memory-limit amount of memory available.", "1").option("--api-key <key>", "Set the Coana dashboard API key. By setting you also enable the dashboard integration.").addOption(new Option("--write-report-to-file", "Write the report dashboard-compatible report to dashboard-report.json. This report may help the Coana team debug issues with the report insertion mechanism.").default(false).hideHelp()).option("--project-name <repoName>", "Set the name of the repository. Used for dashboard integration.").option("--repo-url <repoUrl>", "Set the URL of the repository. Used for dashboard integration.").option("--include-dirs <relativeDirs...>", "globs for directories to include from the detection of subprojects (space-separated)(use relative paths from the project root). Notice, projects that are not included may still be scanned if they are referenced from included projects.").option("--exclude-dirs <relativeDirs...>", "globs for directories to exclude from the detection of subprojects (space-separated)(use relative paths from the project root). Notice, excluded projects may still be scanned if they are referenced from non-excluded projects.").option("--disable-analysis-splitting", "Limits Coana to at most 1 reachability analysis run per workspace").option("--print-analysis-log-file", "Store log output from the JavaScript/TypeScript reachability analysis in the file js-analysis.log file in the root of each workspace", false).option("--entry-points <entryPoints...>", "List of files to analyze for root workspace. The reachability analysis automatically analyzes all files used by the entry points. If not provided, all JavaScript and TypeScript files are considered entry points. For non-root workspaces, all JavaScript and TypeScript files are analyzed as well.").option("--include-projects-with-no-reachability-support", "Also runs Coana on projects where we support traditional SCA, but does not yet support reachability analysis.", false).option("--ecosystems <ecosystems...>", "List of ecosystems to analyze (space-separated). Currently NPM, PIP, MAVEN, NUGET and GO are supported. Default is all supported ecosystems.").addOption(new Option("--purl-types <purlTypes...>", "List of PURL types to analyze (space-separated). Currently npm, pypi, maven, nuget, golang and cargo are supported. Default is all supported purl types.").hideHelp()).option("--changed-files <files...>", "List of files that have changed. If provided, Coana only analyzes workspaces and modules that contain changed files.").option("--disable-report-submission", "Disable the submission of the report to the Coana dashboard. Used by the pipeline blocking feature.", false).option("--disable-analytics-sharing", "Disable analytics sharing.", false).option("--provider-project <path>", "File system path to folder containing the provider project (Only supported for Maven, Gradle, and SBT)").option("--provider-workspaces <dirs...>", "List of workspaces that build the provided runtime environment (Only supported for Maven, Gradle, and SBT)", (paths) => paths.split(" ")).option("--lightweight-reachability", "Runs Coana in lightweight mode. This increases analysis speed but also raises the risk of Coana misclassifying the reachability of certain complex vulnerabilities. Recommended only for use with Coana Guardrail mode.", false).addOption(new Option("--run-without-docker", "Run package managers and reachability analyzers without using docker").default(process.env.RUN_WITHOUT_DOCKER === "true").hideHelp()).addOption(new Option("--run-env <env>", "Specifies the environment in which the CLI is run. So far only MANAGED_SCAN and UNKNOWN are supported.").default("UNKNOWN").choices(["UNKNOWN", "MANAGED_SCAN"]).hideHelp()).addOption(new Option("--guardrail-mode", "Run Coana in guardrail mode. This mode is used to prevent new reachable vulnerabilities from being introduced into the codebase. Usually run as a CI check when pushing new commits to a pull request.")).option("--ignore-failing-workspaces", "Continue processing when a workspace fails instead of exiting. Failed workspaces will be logged at termination.", false).addOption(new Option("--socket-mode <output-file>", "Run Coana in socket mode and write report to <output-file>").hideHelp()).addOption(new Option("--manifests-tar-hash <hash>", "Hash of the tarball containing all manifest files already uploaded to Socket. If provided, Socket will be used for computing dependency trees.").hideHelp()).version(version2).configureHelp({ sortOptions: true }).action(async (path2, options) => {
|
|
226259
226285
|
process.env.DOCKER_IMAGE_TAG ??= version2;
|
|
226260
226286
|
options.ecosystems = options.ecosystems?.map((e) => e.toUpperCase());
|
|
226287
|
+
options.purlTypes = options.purlTypes?.map((e) => e.toLowerCase());
|
|
226261
226288
|
await new CliCore(path2, options).main();
|
|
226262
226289
|
});
|
|
226263
226290
|
var applyFixes = new Command();
|
|
Binary file
|