@coana-tech/cli 14.12.176 → 14.12.178

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
@@ -235308,7 +235308,13 @@ var bgWhiteBright = format5(107, 49);
235308
235308
  import { readFile as readFile34 } from "fs/promises";
235309
235309
  import { platform as platform9 } from "process";
235310
235310
  var VM_MAX_MAP_COUNT_PATH = "/proc/sys/vm/max_map_count";
235311
+ function checkNotWindows() {
235312
+ if (platform9 === "win32") {
235313
+ throw new Error("The Coana CLI is not supported on Windows. Please use Linux or macOS, or run in a Docker container or WSL (Windows Subsystem for Linux).");
235314
+ }
235315
+ }
235311
235316
  async function checkSystemRequirements(memoryLimitInMb, socketMode) {
235317
+ checkNotWindows();
235312
235318
  if (platform9 !== "linux" || !socketMode) {
235313
235319
  return;
235314
235320
  }
@@ -251421,7 +251427,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
251421
251427
  }
251422
251428
 
251423
251429
  // dist/version.js
251424
- var version3 = "14.12.176";
251430
+ var version3 = "14.12.178";
251425
251431
 
251426
251432
  // dist/cli-core.js
251427
251433
  var { mapValues, omit, partition, pickBy: pickBy2 } = import_lodash15.default;
@@ -252429,7 +252435,7 @@ async function writeAnalysisDebugInfo(outputFilePath, ecosystemToWorkspaceToVuln
252429
252435
  handleNexeBinaryMode();
252430
252436
  var program2 = new Command();
252431
252437
  var run2 = new Command();
252432
- 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("--silent-spinner", "Silence spinner", "CI" in process.env || !process.stdin.isTTY).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. NPM reachability analysis does not support concurrent execution, so the concurrency level is ignored for NPM.", "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()).option("--skip-cache-usage", "Do not attempt to use cached analysis configuration from previous runs", false).option("--lazy-mode", "Enable lazy analysis mode for JavaScript/TypeScript. This can significantly speed up analysis by only analyzing code that is actually relevant for the vulnerabilities being analyzed.", false).addOption(new Option("--min-severity <severity>", "Set the minimum severity of vulnerabilities to analyze. Supported severities are info, low, moderate, high and critical.").choices(["info", "INFO", "low", "LOW", "moderate", "MODERATE", "high", "HIGH", "critical", "CRITICAL"])).option("--use-unreachable-from-precomputation", "Skip the reachability analysis for vulnerabilities that are already known to be unreachable from the precomputed reachability analysis (Tier 2).", false).addOption(new Option("--use-only-pregenerated-sboms", "Only include artifacts that have CDX or SPDX files in their manifest files.").default(false).hideHelp()).version(version3).configureHelp({ sortOptions: true }).action(async (path9, options) => {
252438
+ 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("--silent-spinner", "Silence spinner", "CI" in process.env || !process.stdin.isTTY).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. NPM reachability analysis does not support concurrent execution, so the concurrency level is ignored for NPM.", "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()).option("--skip-cache-usage", "Do not attempt to use cached analysis configuration from previous runs", false).addOption(new Option("--lazy-mode", "Enable lazy analysis mode for JavaScript/TypeScript. This can significantly speed up analysis by only analyzing code that is actually relevant for the vulnerabilities being analyzed.").default(false).hideHelp()).addOption(new Option("--min-severity <severity>", "Set the minimum severity of vulnerabilities to analyze. Supported severities are info, low, moderate, high and critical.").choices(["info", "INFO", "low", "LOW", "moderate", "MODERATE", "high", "HIGH", "critical", "CRITICAL"])).option("--use-unreachable-from-precomputation", "Skip the reachability analysis for vulnerabilities that are already known to be unreachable from the precomputed reachability analysis (Tier 2).", false).addOption(new Option("--use-only-pregenerated-sboms", "Only include artifacts that have CDX or SPDX files in their manifest files.").default(false).hideHelp()).version(version3).configureHelp({ sortOptions: true }).action(async (path9, options) => {
252433
252439
  process.env.DOCKER_IMAGE_TAG ??= version3;
252434
252440
  options.ecosystems = options.ecosystems?.map((e) => e.toUpperCase());
252435
252441
  options.minSeverity = options.minSeverity?.toUpperCase();
@@ -252438,11 +252444,13 @@ run2.name("run").argument("<path>", "File system path to folder containing the p
252438
252444
  });
252439
252445
  var applyFixes = new Command();
252440
252446
  applyFixes.name("apply-fixes").argument("<path>", "File system path to the folder containing the project").argument("<fixIds...>", "Apply the fixes associated with the fixIds of the form fix_UUID").option("-r, --recompute-outdated", "Look for a new fix solution when the old solution is outdated", false).option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("--silent-spinner", "Silence spinner", "CI" in process.env || !process.stdin.isTTY).addOption(new Option("--run-without-docker", "Run package managers without using docker").default(process.env.RUN_WITHOUT_DOCKER === "true").hideHelp()).version(version3).action(async (path9, fixIds, options) => {
252447
+ checkNotWindows();
252441
252448
  process.env.DOCKER_IMAGE_TAG ??= version3;
252442
252449
  await applyFix(path9, fixIds, options);
252443
252450
  }).configureHelp({ sortOptions: true });
252444
252451
  var computeFixesAndUpgradePurlsCmd = new Command();
252445
252452
  computeFixesAndUpgradePurlsCmd.name("compute-fixes-and-upgrade-purls").argument("<path>", "File system path to the folder containing the project").option("-a, --apply-fixes-to <ghsas...>", 'GHSA IDs to compute fixes for. Use "all" to compute fixes for all vulnerabilities.', []).option("--dry-run", "Show what changes would be made without actually making them", false).option("-i, --include <patterns...>", "Glob patterns to include workspaces").option("-e, --exclude <patterns...>", "Glob patterns to exclude workspaces").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("--silent-spinner", "Silence spinner", "CI" in process.env || !process.stdin.isTTY).option("--range-style <style>", 'Range style to use for the output. Currently only "pin" is supported and it only works for npm.').option("--disable-major-updates", "Do not suggest major updates. If only major update are available, the fix will not be applied.", false).option("-o, --output-file <file>", "Writes output to a JSON file").option("--minimum-release-age <minimumReleaseAge>", "Do not allow upgrades to package versions that are newer than minimumReleaseAge. Format is 2m, 5h, 3d or 1w").option("--show-affected-direct-dependencies", "Show the affected direct dependencies for each vulnerability and what upgrades could fix them - does not apply the upgrades.", false).option("--purl-types <purlTypes...>", "List of PURL types to filter artifacts by (space-separated). Only vulnerabilities from artifacts matching these types will be included.").addOption(new Option("--run-without-docker", "Run package managers without using docker").default(process.env.RUN_WITHOUT_DOCKER === "true").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(version3).action(async (path9, options) => {
252453
+ checkNotWindows();
252446
252454
  process.env.DOCKER_IMAGE_TAG ??= version3;
252447
252455
  if (options.outputFile && !options.outputFile.endsWith(".json")) {
252448
252456
  throw new Error("Output file must have a .json extension");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coana-tech/cli",
3
- "version": "14.12.176",
3
+ "version": "14.12.178",
4
4
  "description": "Coana CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -110952,13 +110952,13 @@ function convertToArtifactForInstallation(dep) {
110952
110952
  }
110953
110953
 
110954
110954
  // dist/whole-program-code-aware-vulnerability-scanner/js/heuristics.js
110955
- var largeIndirectionBoundOptions = {
110956
- maxIndirections: 1024
110955
+ var lazyIndirectionBoundOptions = {
110956
+ maxIndirections: 5
110957
110957
  };
110958
110958
  var AllPackagesHeuristic = {
110959
110959
  // Analyzing all packages disregarding what vulnerabilities affect the project being analyzed
110960
110960
  name: "ALL_PACKAGES",
110961
- getOptions: () => largeIndirectionBoundOptions,
110961
+ getOptions: () => lazyIndirectionBoundOptions,
110962
110962
  splitAnalysisInBuckets: false
110963
110963
  };
110964
110964
  var OnlyVulnPathPackagesExceptVulnerablePackageHeuristic = {
@@ -110996,7 +110996,7 @@ function getMaxIndirectionsHeuristicOptions(maxIndirections) {
110996
110996
  }
110997
110997
  function getOnlyPackagesInVulnPathsWithoutLeafPackagesHeuristicOptions(vulnerabilities) {
110998
110998
  return {
110999
- ...largeIndirectionBoundOptions,
110999
+ ...lazyIndirectionBoundOptions,
111000
111000
  includePackages: computePackagesOnVulnPath(vulnerabilities)
111001
111001
  };
111002
111002
  }
@@ -111035,8 +111035,8 @@ async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reac
111035
111035
  const affectedPackagesFile = resolve13(tmpFolder, "affected-packages.json");
111036
111036
  const logFile = reachabilityAnalysisOptions.printLogFile ? resolve13(projectRoot, "js-analysis.log") : void 0;
111037
111037
  await writeFile7(vulnerabilitiesFile, JSON.stringify(vulnerabilitiesInJellyFormat));
111038
- const useLazy = experiment === "LAZY_EXPERIMENT" || reachabilityAnalysisOptions.lazy;
111039
111038
  const { includePackages } = jellyOptions;
111039
+ const veryLazy = reachabilityAnalysisOptions.lazy;
111040
111040
  const jellyCmd = cmdt`
111041
111041
  ${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)}
111042
111042
  --max-old-space-size=${reachabilityAnalysisOptions.memoryLimitInMB ?? 8192}
@@ -111046,11 +111046,11 @@ async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reac
111046
111046
  --basedir ${mainProjectRoot}
111047
111047
  --timeout ${timeoutInSeconds}
111048
111048
  --vulnerabilities ${vulnerabilitiesFile}
111049
- ${useLazy && ["--lazy", "--lazy-cleanup", "--lazy-soft-assert", "--reparse", "--memory", "0.85"]}
111049
+ --lazy --lazy-cleanup --lazy-soft-assert --reparse --memory=0.9
111050
111050
  --reachable-json ${affectedPackagesFile}
111051
111051
  ${getExcludes(mainProjectRoot, projectRoot, reachabilityAnalysisOptions)}
111052
111052
  --diagnostics-json ${diagnosticsFile}
111053
- --max-indirections=${useLazy ? 2 : jellyOptions.maxIndirections}
111053
+ --max-indirections=${veryLazy ? 2 : jellyOptions.maxIndirections}
111054
111054
  ${!!includePackages && (includePackages.length ? ["--include-packages", ...includePackages] : ["--ignore-dependencies"])}
111055
111055
  ${jellyOptions.approx && "--approx"}
111056
111056
  --callstacks-json ${callStackFile}
@@ -111082,6 +111082,8 @@ async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reac
111082
111082
  if (reachabilityAnalysisOptions.printLogFile)
111083
111083
  logger.info("JS analysis log file:", logFile);
111084
111084
  const analysisDiagnostics = JSON.parse(await readFile9(diagnosticsFile, "utf-8"));
111085
+ if (analysisDiagnostics.lazyErrors)
111086
+ logger.debug(`Jelly --lazy errors: %O`, analysisDiagnostics.lazyErrors);
111085
111087
  const callStacks = JSON.parse(await readFile9(callStackFile, "utf-8"));
111086
111088
  const matches = {};
111087
111089
  const realProjectRoot = await realpath2(projectRoot);
@@ -111216,10 +111218,11 @@ var JSCodeAwareVulnerabilityScanner = class _JSCodeAwareVulnerabilityScanner {
111216
111218
  diagnostics,
111217
111219
  terminatedEarly,
111218
111220
  reachedDependencies: diagnostics.packages > 0,
111221
+ // XXX: Always true
111219
111222
  affectedPurls: analysisRes.affectedPurls,
111220
- // A round of 0 or 1 indicates that at most 1 level of indirections in the calls was resolved,
111221
- // which is too few for us to confidently trust the results.
111222
- lowConfidence: diagnostics.round < 2 && terminatedEarly,
111223
+ // A round of 0 or 1 indicates that at we did not have enough time to finish analysis of modules that directly
111224
+ // import modules with vulnerable APIs, which is too few for us to confidently trust the results.
111225
+ lowConfidence: diagnostics.analyzerRounds < 2 && terminatedEarly,
111223
111226
  computeDetectedOccurrences: ({ url: url2 }) => this.transformSourceLocations(matches[url2] ?? { analysisLevel: "function-level", affectedPackages: [], stacks: [] })
111224
111227
  };
111225
111228
  } catch (e) {