@coana-tech/cli 14.11.18 → 14.12.0

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-wrapper.mjs CHANGED
@@ -5,6 +5,7 @@ import { dirname, join } from 'path';
5
5
  const __filename = fileURLToPath(import.meta.url);
6
6
  const __dirname = dirname(__filename);
7
7
 
8
+ process.env.COANA_ROOT = __dirname;
8
9
  process.env.REPOS_PATH = join(__dirname, 'repos');
9
10
  process.env.COANA_REPOS_PATH = join(__dirname, 'repos', 'coana-tech');
10
11
  process.env.REACHABILITY_ANALYZERS_SCRIPT_PATH = join(
package/cli.mjs CHANGED
@@ -210274,9 +210274,8 @@ async function fetchArtifactsFromSocket(rootWorkingDirectory, manifestsTarHash)
210274
210274
  const base = basename7(file);
210275
210275
  const workspaceDir = dirname8(file) || ".";
210276
210276
  if (base === "pyproject.toml" || base === "setup.py" && await isSetupPySetuptools(file)) {
210277
- const normalizedDir = workspaceDir === "." ? "." : workspaceDir;
210278
- if (!properPythonProjects.includes(normalizedDir)) {
210279
- properPythonProjects.push(normalizedDir);
210277
+ if (!properPythonProjects.includes(workspaceDir)) {
210278
+ properPythonProjects.push(workspaceDir);
210280
210279
  }
210281
210280
  }
210282
210281
  }
@@ -210288,14 +210287,23 @@ async function fetchArtifactsFromSocket(rootWorkingDirectory, manifestsTarHash)
210288
210287
  const ecosystem = getAdvisoryEcosystemFromPurlType(artifact.type);
210289
210288
  if (!ecosystem)
210290
210289
  continue;
210291
- const manifestFiles = artifact.manifestFiles?.map((ref) => ref.file) ?? [];
210292
- const allAncestorIds = getAllToplevelAncestors(artifactMap, artifact.id);
210293
- allAncestorIds.forEach((ancestorId) => {
210294
- const ancestor = artifactMap.get(ancestorId);
210295
- if (ancestor?.manifestFiles) {
210296
- manifestFiles.push(...ancestor.manifestFiles.map((ref) => ref.file));
210290
+ const manifestFiles = [];
210291
+ switch (ecosystem) {
210292
+ case "MAVEN": {
210293
+ manifestFiles.push(...(await getFilesRelative(rootWorkingDirectory)).filter((file) => (0, import_picomatch2.default)("{{*-*.,}pom{.xml,},gradle.lockfile}")(basename7(file))));
210294
+ break;
210297
210295
  }
210298
- });
210296
+ case "NUGET": {
210297
+ manifestFiles.push(...(await getFilesRelative(rootWorkingDirectory)).filter((file) => (0, import_picomatch2.default)("{*.csproj,packages.lock.json}")(basename7(file))));
210298
+ break;
210299
+ }
210300
+ default: {
210301
+ artifact.manifestFiles?.forEach((ref) => manifestFiles.push(ref.file));
210302
+ const allAncestorIds = getAllToplevelAncestors(artifactMap, artifact.id);
210303
+ allAncestorIds.forEach((ancestorId) => artifactMap.get(ancestorId)?.manifestFiles?.forEach((ref) => manifestFiles.push(ref.file)));
210304
+ break;
210305
+ }
210306
+ }
210299
210307
  let manifestAndWorkspace = manifestFiles.map((manifestFile) => [
210300
210308
  manifestFile,
210301
210309
  inferWorkspaceFromManifestPath(ecosystem, manifestFile, properPythonProjects)
@@ -210323,33 +210331,14 @@ async function fetchArtifactsFromSocket(rootWorkingDirectory, manifestsTarHash)
210323
210331
  }
210324
210332
  const workspaceData = ecosystemToWorkspaceToAnalysisData[ecosystem][workspace];
210325
210333
  if (workspaceData.type === "socket") {
210326
- switch (ecosystem) {
210327
- case "MAVEN": {
210328
- if (!workspaceData.data.manifestFiles.length) {
210329
- const allFiles2 = await getFilesRelative(rootWorkingDirectory);
210330
- const manifestFiles2 = allFiles2.filter((file) => (0, import_picomatch2.default)("{{*-*.,}pom{.xml,},gradle.lockfile}")(basename7(file)));
210331
- workspaceData.data.manifestFiles.push(...manifestFiles2);
210332
- }
210333
- break;
210334
- }
210335
- case "NUGET": {
210336
- if (!workspaceData.data.manifestFiles.length) {
210337
- const allFiles2 = await getFilesRelative(rootWorkingDirectory);
210338
- const manifestFiles2 = allFiles2.filter((file) => (0, import_picomatch2.default)("{*.csproj,packages.lock.json}")(basename7(file)));
210339
- workspaceData.data.manifestFiles.push(...manifestFiles2);
210340
- }
210341
- break;
210342
- }
210343
- default: {
210344
- if (!workspaceData.data.manifestFiles.includes(manifestFile)) {
210345
- workspaceData.data.manifestFiles.push(manifestFile);
210346
- }
210347
- break;
210348
- }
210334
+ if (!workspaceData.data.manifestFiles.includes(manifestFile)) {
210335
+ workspaceData.data.manifestFiles.push(manifestFile);
210349
210336
  }
210350
210337
  workspaceData.data.artifacts.push(artifact);
210351
210338
  }
210352
- if (artifact.vulnerabilities && artifact.vulnerabilities.length > 0) {
210339
+ }
210340
+ if (artifact.vulnerabilities && artifact.vulnerabilities.length > 0) {
210341
+ for (const workspace of i5(manifestAndWorkspace.map(([, workspace2]) => workspace2))) {
210353
210342
  for (const vuln of artifact.vulnerabilities) {
210354
210343
  const vulnerability = {
210355
210344
  url: vuln.ghsaId,
@@ -225499,7 +225488,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
225499
225488
  }
225500
225489
 
225501
225490
  // dist/version.js
225502
- var version2 = "14.11.18";
225491
+ var version2 = "14.12.0";
225503
225492
 
225504
225493
  // dist/cli-core.js
225505
225494
  var { mapValues, omit, partition, pick } = import_lodash15.default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coana-tech/cli",
3
- "version": "14.11.18",
3
+ "version": "14.12.0",
4
4
  "description": "Coana CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -74547,7 +74547,7 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
74547
74547
  }
74548
74548
  static initFromDependencyTree(dependencyTree, timeoutInSeconds, statusUpdater) {
74549
74549
  return new _DotnetCodeAwareVulnerabilityScanner({
74550
- [randomUUID()]: {
74550
+ [serializeNugetDependencyToPackageUrl(dependencyTree)]: {
74551
74551
  src: dependencyTree.src,
74552
74552
  bin: dependencyTree.bin,
74553
74553
  ecosystemSpecificPackageInfo: {
@@ -74611,7 +74611,7 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
74611
74611
  try {
74612
74612
  const nugetDependencyChain = await convertDependencyChain(dependencyChain, tmpDir);
74613
74613
  const scanner = new _DotnetCodeAwareVulnerabilityScanner({
74614
- [randomUUID()]: {
74614
+ [serializeNugetDependencyToPackageUrl(nugetDependencyChain[0])]: {
74615
74615
  src: nugetDependencyChain[0].src,
74616
74616
  bin: nugetDependencyChain[0].bin,
74617
74617
  ecosystemSpecificPackageInfo: {
@@ -74653,8 +74653,8 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
74653
74653
  const result = await execNeverFail(cmdt`node ${classGraphAnalysisCliPath} runDotnetDirectDependencyAnalysis -i ${inputFile} -o ${outputFile} --cocoa ${cocoaPath} --tree-sitter-c-sharp ${treeSitterCSharpPath}`);
74654
74654
  if (result.error)
74655
74655
  return void 0;
74656
- const directNodes = JSON.parse(await readFile4(outputFile, "utf-8")).result;
74657
- return directNodes?.filter((node) => !Object.hasOwn(this.apps, node.packageId))?.map((node) => parsePackageUrlToNugetDependency(node.packageId).packageName);
74656
+ const packageIds = JSON.parse(await readFile4(outputFile, "utf-8")).result;
74657
+ return packageIds?.filter((packageId) => !Object.hasOwn(this.apps, packageId))?.map((packageId) => parsePackageUrlToNugetDependency(packageId).packageName);
74658
74658
  });
74659
74659
  }
74660
74660
  async runAnalysis(vulnerabilities, heuristic, _analyzesAllVulns, _experiment) {
@@ -74692,19 +74692,18 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
74692
74692
  diagnostics,
74693
74693
  terminatedEarly: diagnostics.timeout,
74694
74694
  reachedDependencies: true,
74695
- computeDetectedOccurrences: ({ vulnerabilityAccessPaths: vulnerabilityAccessPaths2 }) => _DotnetCodeAwareVulnerabilityScanner.computeDetectedOccurrences(appPackageIds, vulnerablePaths, vulnerabilityAccessPaths2)
74695
+ computeDetectedOccurrences: ({ vulnerabilityAccessPaths: vulnerabilityAccessPaths2 }) => _DotnetCodeAwareVulnerabilityScanner.computeDetectedOccurrences(appPackageIds, vulnerablePaths, i(vulnerabilityAccessPaths2.map((vulnerabilityAccessPath) => vulnerabilityAccessPath.slice(1).split(":")[0])))
74696
74696
  };
74697
74697
  });
74698
74698
  }
74699
- static computeDetectedOccurrences(appPackageIds, vulnerablePaths, vulnerableAccessPaths) {
74699
+ static computeDetectedOccurrences(appPackageIds, vulnerablePaths, vulnerableClasses) {
74700
74700
  const affectedPackages = /* @__PURE__ */ new Set();
74701
74701
  const classStacks = [];
74702
- for (const vulnerableMethod of vulnerableAccessPaths) {
74703
- const classForVulnerableMethod = vulnerableMethod.slice(1).split(":")[0];
74704
- const vulnerablePathsForMethod = vulnerablePaths[classForVulnerableMethod];
74705
- if (!vulnerablePathsForMethod)
74702
+ for (const vulnerableClass of vulnerableClasses) {
74703
+ const vulnerablePathsForClass = vulnerablePaths[vulnerableClass];
74704
+ if (!vulnerablePathsForClass)
74706
74705
  continue;
74707
- classStacks.push(...vulnerablePathsForMethod.map((vulnPath) => {
74706
+ classStacks.push(...vulnerablePathsForClass.map((vulnPath) => {
74708
74707
  if (vulnPath.length < 2)
74709
74708
  throw new Error("The path should always have length at least two.");
74710
74709
  return vulnPath.map(({ fullyQualifiedName, confidence, packageId }) => ({
@@ -74713,7 +74712,7 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
74713
74712
  confidence
74714
74713
  }));
74715
74714
  }));
74716
- vulnerablePathsForMethod.flatMap((vulnPath) => vulnPath.slice(1).map(({ packageId }) => parsePackageUrlToNugetDependency(packageId))).forEach((node) => affectedPackages.add(`${node.packageName}@${node.version}`));
74715
+ vulnerablePathsForClass.flatMap((vulnPath) => vulnPath).filter(({ packageId }) => !appPackageIds.has(packageId)).map(({ packageId }) => parsePackageUrlToNugetDependency(packageId)).forEach((node) => affectedPackages.add(`${node.packageName}@${node.version}`));
74717
74716
  }
74718
74717
  return {
74719
74718
  analysisLevel: "class-level",
@@ -88392,7 +88391,7 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
88392
88391
  }
88393
88392
  static initFromDependencyTree(dependencyTree, timeoutInSeconds, statusUpdater) {
88394
88393
  return new _JavaCodeAwareVulnerabilityScanner({
88395
- [randomUUID2()]: {
88394
+ [serializeMavenDependencyToPackageUrl(dependencyTree)]: {
88396
88395
  src: dependencyTree.src,
88397
88396
  bin: dependencyTree.bin,
88398
88397
  ecosystemSpecificPackageInfo: {
@@ -88456,7 +88455,7 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
88456
88455
  try {
88457
88456
  const mavenDependencyChain = await convertDependencyChain2(dependencyChain, tmpDir);
88458
88457
  const scanner = new _JavaCodeAwareVulnerabilityScanner({
88459
- [randomUUID2()]: {
88458
+ [serializeMavenDependencyToPackageUrl(mavenDependencyChain[0])]: {
88460
88459
  src: mavenDependencyChain[0].src,
88461
88460
  bin: mavenDependencyChain[0].bin,
88462
88461
  ecosystemSpecificPackageInfo: {
@@ -88498,8 +88497,8 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
88498
88497
  const result = await execNeverFail(cmdt`node ${classGraphAnalysisCliPath} runJvmDirectDependencyAnalysis -i ${inputFile} -o ${outputFile} --alucard ${alucardPath} --tree-sitter-java ${treeSitterJavaPath} --tree-sitter-kotlin ${treeSitterKotlinPath} --tree-sitter-scala ${treeSitterScalaPath}`);
88499
88498
  if (result.error)
88500
88499
  return void 0;
88501
- const directNodes = JSON.parse(await readFile5(outputFile, "utf-8")).result;
88502
- return directNodes?.filter((node) => !Object.hasOwn(this.apps, node.packageId))?.map((node) => parsePackageUrlToMavenDependency(node.packageId).packageName);
88500
+ const packageIds = JSON.parse(await readFile5(outputFile, "utf-8")).result;
88501
+ return packageIds?.filter((packageId) => !Object.hasOwn(this.apps, packageId))?.map((packageId) => parsePackageUrlToMavenDependency(packageId).packageName);
88503
88502
  });
88504
88503
  }
88505
88504
  async runAnalysis(vulnerabilities, heuristic, _analyzesAllVulns, _experiment) {
@@ -88537,19 +88536,18 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
88537
88536
  diagnostics,
88538
88537
  terminatedEarly: diagnostics.timeout,
88539
88538
  reachedDependencies: true,
88540
- computeDetectedOccurrences: ({ vulnerabilityAccessPaths: vulnerabilityAccessPaths2 }) => _JavaCodeAwareVulnerabilityScanner.computeDetectedOccurrences(appPackageIds, vulnerablePaths, vulnerabilityAccessPaths2)
88539
+ computeDetectedOccurrences: ({ vulnerabilityAccessPaths: vulnerabilityAccessPaths2 }) => _JavaCodeAwareVulnerabilityScanner.computeDetectedOccurrences(appPackageIds, vulnerablePaths, i(vulnerabilityAccessPaths2.map((vulnerabilityAccessPath) => vulnerabilityAccessPath.slice(1).split(":")[0])))
88541
88540
  };
88542
88541
  });
88543
88542
  }
88544
- static computeDetectedOccurrences(appPackageIds, vulnerablePaths, vulnerableAccessPaths) {
88543
+ static computeDetectedOccurrences(appPackageIds, vulnerablePaths, vulnerableClasses) {
88545
88544
  const affectedPackages = /* @__PURE__ */ new Set();
88546
88545
  const classStacks = [];
88547
- for (const vulnerableMethod of vulnerableAccessPaths) {
88548
- const classForVulnerableMethod = vulnerableMethod.slice(1).split(":")[0];
88549
- const vulnerablePathsForMethod = vulnerablePaths[classForVulnerableMethod];
88550
- if (!vulnerablePathsForMethod)
88546
+ for (const vulnerableClass of vulnerableClasses) {
88547
+ const vulnerablePathsForClass = vulnerablePaths[vulnerableClass];
88548
+ if (!vulnerablePathsForClass)
88551
88549
  continue;
88552
- classStacks.push(...vulnerablePathsForMethod.map((vulnPath) => {
88550
+ classStacks.push(...vulnerablePathsForClass.map((vulnPath) => {
88553
88551
  if (vulnPath.length < 2)
88554
88552
  throw new Error("The path should always have length at least two.");
88555
88553
  return vulnPath.map(({ fullyQualifiedName, confidence, packageId }) => ({
@@ -88558,7 +88556,7 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
88558
88556
  confidence
88559
88557
  }));
88560
88558
  }));
88561
- vulnerablePathsForMethod.flatMap((vulnPath) => vulnPath.slice(1).map(({ packageId }) => parsePackageUrlToMavenDependency(packageId))).forEach((node) => affectedPackages.add(`${node.packageName}@${node.version}`));
88559
+ vulnerablePathsForClass.flatMap((vulnPath) => vulnPath).filter(({ packageId }) => !appPackageIds.has(packageId)).map(({ packageId }) => parsePackageUrlToMavenDependency(packageId)).forEach((node) => affectedPackages.add(`${node.packageName}@${node.version}`));
88562
88560
  }
88563
88561
  return {
88564
88562
  analysisLevel: "class-level",
@@ -95940,7 +95938,7 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
95940
95938
  }
95941
95939
  static initFromDependencyTree(dependencyTree, timeoutInSeconds, statusUpdater) {
95942
95940
  return new _RustCodeAwareVulnerabilityScanner({
95943
- [randomUUID3()]: {
95941
+ [serializeRustDependencyToPackageUrl(dependencyTree)]: {
95944
95942
  src: dependencyTree.src,
95945
95943
  ecosystemSpecificPackageInfo: {
95946
95944
  type: "RUST",
@@ -96004,7 +96002,7 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
96004
96002
  try {
96005
96003
  const rustDependencyChain = await convertDependencyChain3(dependencyChain, tmpDir);
96006
96004
  const scanner = new _RustCodeAwareVulnerabilityScanner({
96007
- [randomUUID3()]: {
96005
+ [serializeRustDependencyToPackageUrl(rustDependencyChain[0])]: {
96008
96006
  src: rustDependencyChain[0].src,
96009
96007
  ecosystemSpecificPackageInfo: {
96010
96008
  type: "RUST",
@@ -96046,8 +96044,8 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
96046
96044
  const result = await execNeverFail(cmdt`node ${classGraphAnalysisCliPath} runRustDirectDependencyAnalysis -i ${inputFile} -o ${outputFile} --tree-sitter-rust ${treeSitterRustPath}`);
96047
96045
  if (result.error)
96048
96046
  return void 0;
96049
- const directNodes = JSON.parse(await readFile8(outputFile, "utf-8")).result;
96050
- return directNodes?.filter((node) => !Object.hasOwn(this.apps, node.packageId))?.map((node) => parsePackageUrlToRustDependency(node.packageId).packageName);
96047
+ const packageIds = JSON.parse(await readFile8(outputFile, "utf-8")).result;
96048
+ return packageIds?.filter((packageId) => !Object.hasOwn(this.apps, packageId))?.map((packageId) => parsePackageUrlToRustDependency(packageId).packageName);
96051
96049
  });
96052
96050
  }
96053
96051
  async runAnalysis(vulnerabilities, heuristic, _analyzesAllVulns) {
@@ -96086,19 +96084,21 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
96086
96084
  diagnostics,
96087
96085
  terminatedEarly: diagnostics.timeout,
96088
96086
  reachedDependencies: true,
96089
- computeDetectedOccurrences: ({ vulnerabilityAccessPaths: vulnerabilityAccessPaths2 }) => _RustCodeAwareVulnerabilityScanner.computeDetectedOccurrences(appPackageIds, vulnerablePaths, vulnerabilityAccessPaths2)
96087
+ computeDetectedOccurrences: ({ vulnerabilityAccessPaths: vulnerabilityAccessPaths2 }) => _RustCodeAwareVulnerabilityScanner.computeDetectedOccurrences(appPackageIds, vulnerablePaths, i(vulnerabilityAccessPaths2.map(
96088
+ // Note, rust uses '::' as path separator, so we need to split on ': ' and not only ':'
96089
+ (vulnerabilityAccessPath) => vulnerabilityAccessPath.slice(1).split(": ")[0]
96090
+ )))
96090
96091
  };
96091
96092
  });
96092
96093
  }
96093
- static computeDetectedOccurrences(appPackageIds, vulnerablePaths, vulnerableAccessPaths) {
96094
+ static computeDetectedOccurrences(appPackageIds, vulnerablePaths, vulnerableClasses) {
96094
96095
  const affectedPackages = /* @__PURE__ */ new Set();
96095
96096
  const classStacks = [];
96096
- for (const vulnerableMethod of vulnerableAccessPaths) {
96097
- const classForVulnerableMethod = vulnerableMethod.slice(1).split(": ")[0];
96098
- const vulnerablePathsForMethod = vulnerablePaths[classForVulnerableMethod];
96099
- if (!vulnerablePathsForMethod)
96097
+ for (const vulnerableClass of vulnerableClasses) {
96098
+ const vulnerablePathsForClass = vulnerablePaths[vulnerableClass];
96099
+ if (!vulnerablePathsForClass)
96100
96100
  continue;
96101
- classStacks.push(...vulnerablePathsForMethod.map((vulnPath) => {
96101
+ classStacks.push(...vulnerablePathsForClass.map((vulnPath) => {
96102
96102
  if (vulnPath.length < 2)
96103
96103
  throw new Error("The path should always have length at least two.");
96104
96104
  return vulnPath.map(({ fullyQualifiedName, confidence, packageId }) => ({
@@ -96107,7 +96107,7 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
96107
96107
  confidence
96108
96108
  }));
96109
96109
  }));
96110
- vulnerablePathsForMethod.flatMap((vulnPath) => vulnPath.slice(1).map(({ packageId }) => parsePackageUrlToRustDependency(packageId))).forEach((node) => affectedPackages.add(`${node.packageName}@${node.version}`));
96110
+ vulnerablePathsForClass.flatMap((vulnPath) => vulnPath).filter(({ packageId }) => !appPackageIds.has(packageId)).map(({ packageId }) => parsePackageUrlToRustDependency(packageId)).forEach((node) => affectedPackages.add(`${node.packageName}@${node.version}`));
96111
96111
  }
96112
96112
  return {
96113
96113
  analysisLevel: "class-level",