@coana-tech/cli 14.12.200 → 15.0.1
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 +342 -58
- package/package.json +1 -1
- package/reachability-analyzers-cli.mjs +361 -97
- 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
|
@@ -79900,6 +79900,16 @@ var ApiUrls = {
|
|
|
79900
79900
|
}
|
|
79901
79901
|
};
|
|
79902
79902
|
|
|
79903
|
+
// ../web-compat-utils/src/analysis-error-keys.ts
|
|
79904
|
+
var FAILED_TO_INSTALL_PACKAGE_KEY = "[UNABLE_TO_INSTALL_PACKAGE_ERROR]: ";
|
|
79905
|
+
var InstallError = class extends Error {
|
|
79906
|
+
constructor(failedPackages) {
|
|
79907
|
+
super(`Failed to install packages: ${failedPackages.join(", ")}`);
|
|
79908
|
+
this.failedPackages = failedPackages;
|
|
79909
|
+
this.name = "InstallError";
|
|
79910
|
+
}
|
|
79911
|
+
};
|
|
79912
|
+
|
|
79903
79913
|
// ../web-compat-utils/src/maven-dependency-utils.ts
|
|
79904
79914
|
function deserializeMavenDependency(s2) {
|
|
79905
79915
|
const [groupId, artifactId, version3] = s2.split(":");
|
|
@@ -88108,9 +88118,6 @@ var PromiseQueue = class {
|
|
|
88108
88118
|
}
|
|
88109
88119
|
};
|
|
88110
88120
|
|
|
88111
|
-
// ../web-compat-utils/src/analysis-error-keys.ts
|
|
88112
|
-
var FAILED_TO_INSTALL_PACKAGE_KEY = "[UNABLE_TO_INSTALL_PACKAGE_ERROR]: ";
|
|
88113
|
-
|
|
88114
88121
|
// ../web-compat-utils/src/ghsa.ts
|
|
88115
88122
|
function extractGHSAIdFromUrl(url2) {
|
|
88116
88123
|
const match2 = url2.match(/(GHSA-[a-z0-9-]+)/);
|
|
@@ -88151,6 +88158,7 @@ function getVulnReachability(c) {
|
|
|
88151
88158
|
// dist/analyzers/pip-analyzer.js
|
|
88152
88159
|
var import_lodash16 = __toESM(require_lodash(), 1);
|
|
88153
88160
|
import assert7 from "assert";
|
|
88161
|
+
import { existsSync as existsSync15 } from "fs";
|
|
88154
88162
|
import { resolve as resolve19 } from "path";
|
|
88155
88163
|
|
|
88156
88164
|
// ../utils/src/pip-utils.ts
|
|
@@ -88571,8 +88579,8 @@ function addPathToTrie(root3, vulnPath) {
|
|
|
88571
88579
|
// dist/whole-program-code-aware-vulnerability-scanner/python/python-code-aware-vulnerability-scanner.js
|
|
88572
88580
|
var import_lodash14 = __toESM(require_lodash(), 1);
|
|
88573
88581
|
import assert6 from "assert";
|
|
88574
|
-
import { existsSync as
|
|
88575
|
-
import { cp as cp7, readdir as
|
|
88582
|
+
import { existsSync as existsSync14 } from "fs";
|
|
88583
|
+
import { cp as cp7, readdir as readdir6, readFile as readFile12, rm as rm5 } from "fs/promises";
|
|
88576
88584
|
var import_semver3 = __toESM(require_semver2(), 1);
|
|
88577
88585
|
import { basename as basename11, dirname as dirname15, join as join17, resolve as resolve17, sep as sep5 } from "path";
|
|
88578
88586
|
import util5 from "util";
|
|
@@ -94244,7 +94252,7 @@ var CocoaHeuristics = {
|
|
|
94244
94252
|
|
|
94245
94253
|
// dist/whole-program-code-aware-vulnerability-scanner/dotnet/dotnet-code-aware-vulnerability-scanner.js
|
|
94246
94254
|
var import_adm_zip = __toESM(require_adm_zip(), 1);
|
|
94247
|
-
import { mkdir as mkdir5, readFile as readFile7, writeFile as writeFile5 } from "fs/promises";
|
|
94255
|
+
import { mkdir as mkdir5, readdir as readdir4, readFile as readFile7, writeFile as writeFile5 } from "fs/promises";
|
|
94248
94256
|
import { randomUUID } from "node:crypto";
|
|
94249
94257
|
|
|
94250
94258
|
// dist/whole-program-code-aware-vulnerability-scanner/dotnet/constants.js
|
|
@@ -95565,7 +95573,7 @@ var prereleaseSpecifierNormalization = {
|
|
|
95565
95573
|
};
|
|
95566
95574
|
var postreleaseSpecifiers = ["post", "rev", "r"];
|
|
95567
95575
|
var devReleaseSpecifiers = ["dev"];
|
|
95568
|
-
var epochRegex = /(\d+)
|
|
95576
|
+
var epochRegex = /(\d+)!/;
|
|
95569
95577
|
var releaseSegmentRegex = /(\d+(?:\.\d+)*)/;
|
|
95570
95578
|
var prereleaseRegex = buildRegexWithSpecifier(prereleaseSpecifiers);
|
|
95571
95579
|
var postreleaseRegex = buildRegexWithSpecifier(postreleaseSpecifiers);
|
|
@@ -96464,7 +96472,13 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
|
|
|
96464
96472
|
const outputFile = resolve9(tmpDir, "output.json");
|
|
96465
96473
|
await writeFile5(inputFile, JSON.stringify(options));
|
|
96466
96474
|
const timeoutMs = Math.max(timeoutInSeconds * 1.5, timeoutInSeconds + 30) * 1e3;
|
|
96467
|
-
const result = await execNeverFail2(cmdt`${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} ${getClassGraphAnalysisCliPath()} runDotnetReachabilityAnalysis -i ${inputFile} -o ${outputFile} --cocoa ${getCocoaPath()} --tree-sitter-c-sharp ${getTreeSitterCSharpPath()}`, void 0, {
|
|
96475
|
+
const result = await execNeverFail2(cmdt`${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} ${getClassGraphAnalysisCliPath()} runDotnetReachabilityAnalysis -i ${inputFile} -o ${outputFile} --cocoa ${getCocoaPath()} --tree-sitter-c-sharp ${getTreeSitterCSharpPath()}`, void 0, {
|
|
96476
|
+
timeout: timeoutMs,
|
|
96477
|
+
killSignal: "SIGKILL",
|
|
96478
|
+
heartbeat: HEARTBEATS.dotnet,
|
|
96479
|
+
telemetryHandler,
|
|
96480
|
+
analyzerTelemetryHandler
|
|
96481
|
+
});
|
|
96468
96482
|
if (result.error)
|
|
96469
96483
|
return { type: "error", message: result.error.message ?? "unknown error" };
|
|
96470
96484
|
const { success, error, analysisDiagnostics: diagnostics, vulnerablePaths, reachablePackageIds } = JSON.parse(await readFile7(outputFile, "utf-8")).result;
|
|
@@ -96555,18 +96569,29 @@ async function downloadAndExtractNugetPackage(packageName, version3, tmpDir) {
|
|
|
96555
96569
|
const packageUrl = getUrlForPackage(packageName, version3);
|
|
96556
96570
|
const success = await downloadFile(packageUrl, packageFile);
|
|
96557
96571
|
if (!success) {
|
|
96558
|
-
|
|
96559
|
-
return void 0;
|
|
96572
|
+
throw new Error(`Failed to download nuget package ${packageName}/${version3}`);
|
|
96560
96573
|
}
|
|
96561
96574
|
}
|
|
96562
96575
|
return extractNugetPackage(packageFile, packageName, version3, tmpDir);
|
|
96563
96576
|
}
|
|
96564
96577
|
async function convertDependencyChain(dependencyChain, tmpDir) {
|
|
96578
|
+
const runtimePaths = await getDotnetRuntimeSharedPaths();
|
|
96579
|
+
const runtimeFileIndex = await buildRuntimeFileIndex(runtimePaths);
|
|
96565
96580
|
const nugetDependencyChain = await asyncMap(dependencyChain, async (dep) => {
|
|
96566
|
-
|
|
96567
|
-
|
|
96568
|
-
|
|
96569
|
-
|
|
96581
|
+
const binFiles = [];
|
|
96582
|
+
if (dep.version) {
|
|
96583
|
+
try {
|
|
96584
|
+
const extracted = await downloadAndExtractNugetPackage(dep.packageName, dep.version, tmpDir);
|
|
96585
|
+
if (extracted)
|
|
96586
|
+
binFiles.push(...extracted);
|
|
96587
|
+
} catch (e) {
|
|
96588
|
+
logger.warn(`${e.message}`);
|
|
96589
|
+
}
|
|
96590
|
+
const runtimeFiles = findStdlibRuntimeFiles(dep.packageName, runtimeFileIndex);
|
|
96591
|
+
if (runtimeFiles)
|
|
96592
|
+
binFiles.push(...runtimeFiles);
|
|
96593
|
+
}
|
|
96594
|
+
return { ...dep, bin: binFiles.length > 0 ? binFiles : void 0 };
|
|
96570
96595
|
}, 4);
|
|
96571
96596
|
return nugetDependencyChain;
|
|
96572
96597
|
}
|
|
@@ -96592,23 +96617,109 @@ async function findNuGetPackageInLocalRepo(repo, packageName, version3, tmpDir)
|
|
|
96592
96617
|
const nupkgFile = allFiles.find((file) => basename7(file).toLowerCase() === targetNupkg);
|
|
96593
96618
|
return nupkgFile ? extractNugetPackage(nupkgFile, packageName, version3, tmpDir) : void 0;
|
|
96594
96619
|
}
|
|
96620
|
+
async function getDotnetRuntimeSharedPaths() {
|
|
96621
|
+
const result = await execNeverFail2(cmdt`dotnet --list-runtimes`);
|
|
96622
|
+
if (result.error ?? !result.stdout)
|
|
96623
|
+
return [];
|
|
96624
|
+
const paths = [];
|
|
96625
|
+
for (const line of result.stdout.split("\n")) {
|
|
96626
|
+
const match2 = line.trim().match(/^(\S+)\s+(\S+)\s+\[(.+)\]$/);
|
|
96627
|
+
if (match2) {
|
|
96628
|
+
const runtimeDir = resolve9(match2[3], match2[2]);
|
|
96629
|
+
if (existsSync7(runtimeDir)) {
|
|
96630
|
+
paths.push(runtimeDir);
|
|
96631
|
+
}
|
|
96632
|
+
}
|
|
96633
|
+
}
|
|
96634
|
+
return paths;
|
|
96635
|
+
}
|
|
96636
|
+
async function buildRuntimeFileIndex(runtimePaths) {
|
|
96637
|
+
const index2 = /* @__PURE__ */ new Map();
|
|
96638
|
+
for (const runtimePath of runtimePaths) {
|
|
96639
|
+
try {
|
|
96640
|
+
const entries = await readdir4(runtimePath, { withFileTypes: true });
|
|
96641
|
+
for (const entry of entries) {
|
|
96642
|
+
if (!entry.isFile())
|
|
96643
|
+
continue;
|
|
96644
|
+
const name2 = entry.name.toLowerCase();
|
|
96645
|
+
const fullPath = resolve9(runtimePath, entry.name);
|
|
96646
|
+
const existing = index2.get(name2);
|
|
96647
|
+
if (existing) {
|
|
96648
|
+
existing.push(fullPath);
|
|
96649
|
+
} else {
|
|
96650
|
+
index2.set(name2, [fullPath]);
|
|
96651
|
+
}
|
|
96652
|
+
}
|
|
96653
|
+
} catch (e) {
|
|
96654
|
+
logger.debug(`Failed to read runtime path ${runtimePath}: ${e.message}`);
|
|
96655
|
+
}
|
|
96656
|
+
}
|
|
96657
|
+
return index2;
|
|
96658
|
+
}
|
|
96659
|
+
function findStdlibRuntimeFiles(packageName, runtimeFileIndex) {
|
|
96660
|
+
if (runtimeFileIndex.size === 0)
|
|
96661
|
+
return void 0;
|
|
96662
|
+
const possibleFileNames = /* @__PURE__ */ new Set();
|
|
96663
|
+
if (packageName.toLowerCase() === "netstandard.library") {
|
|
96664
|
+
possibleFileNames.add("netstandard.dll");
|
|
96665
|
+
} else {
|
|
96666
|
+
const lowerName = packageName.toLowerCase();
|
|
96667
|
+
const componentName = lowerName.startsWith("runtime.native.") ? lowerName.slice("runtime.native.".length) : lowerName;
|
|
96668
|
+
const nameVariants = [componentName, `${componentName}.Native`];
|
|
96669
|
+
const lastDotIndex = componentName.lastIndexOf(".");
|
|
96670
|
+
if (lastDotIndex !== -1) {
|
|
96671
|
+
nameVariants.push(componentName.slice(0, lastDotIndex) + ".Native" + componentName.slice(lastDotIndex));
|
|
96672
|
+
}
|
|
96673
|
+
for (const name2 of nameVariants) {
|
|
96674
|
+
possibleFileNames.add(`${name2}.dll`.toLowerCase());
|
|
96675
|
+
possibleFileNames.add(`lib${name2}.dylib`.toLowerCase());
|
|
96676
|
+
possibleFileNames.add(`lib${name2}.so`.toLowerCase());
|
|
96677
|
+
}
|
|
96678
|
+
}
|
|
96679
|
+
const matchedFiles = [];
|
|
96680
|
+
for (const fileName2 of possibleFileNames) {
|
|
96681
|
+
const files = runtimeFileIndex.get(fileName2);
|
|
96682
|
+
if (files)
|
|
96683
|
+
matchedFiles.push(...files);
|
|
96684
|
+
}
|
|
96685
|
+
return matchedFiles.length > 0 ? matchedFiles : void 0;
|
|
96686
|
+
}
|
|
96595
96687
|
async function convertSocketArtifacts(artifacts, tmpDir) {
|
|
96596
96688
|
const localRepositories = getNuGetLocalRepositoryPaths();
|
|
96689
|
+
const runtimePaths = await getDotnetRuntimeSharedPaths();
|
|
96690
|
+
const runtimeFileIndex = await buildRuntimeFileIndex(runtimePaths);
|
|
96597
96691
|
async function resolveNuGetPackage(packageName, version3) {
|
|
96692
|
+
const binFiles = [];
|
|
96598
96693
|
for (const repo of localRepositories) {
|
|
96599
96694
|
const localPackage = await findNuGetPackageInLocalRepo(repo, packageName, version3, tmpDir);
|
|
96600
|
-
if (localPackage)
|
|
96601
|
-
|
|
96695
|
+
if (localPackage) {
|
|
96696
|
+
binFiles.push(...localPackage);
|
|
96697
|
+
break;
|
|
96698
|
+
}
|
|
96699
|
+
}
|
|
96700
|
+
if (binFiles.length === 0) {
|
|
96701
|
+
const downloaded = await downloadAndExtractNugetPackage(packageName, version3, tmpDir);
|
|
96702
|
+
if (downloaded)
|
|
96703
|
+
binFiles.push(...downloaded);
|
|
96602
96704
|
}
|
|
96603
|
-
|
|
96705
|
+
const runtimeFiles = findStdlibRuntimeFiles(packageName, runtimeFileIndex);
|
|
96706
|
+
if (runtimeFiles)
|
|
96707
|
+
binFiles.push(...runtimeFiles);
|
|
96708
|
+
return binFiles.length > 0 ? binFiles : void 0;
|
|
96604
96709
|
}
|
|
96605
96710
|
const deps = {};
|
|
96606
96711
|
const depIdToPurl = /* @__PURE__ */ new Map();
|
|
96607
96712
|
await asyncForEach(artifacts, async (artifact) => {
|
|
96608
96713
|
depIdToPurl.set(artifact.id, getPurlFromSocketFactArtifact(artifact));
|
|
96609
|
-
|
|
96610
|
-
|
|
96611
|
-
|
|
96714
|
+
let bin;
|
|
96715
|
+
if (artifact.name && artifact.version) {
|
|
96716
|
+
try {
|
|
96717
|
+
bin = await resolveNuGetPackage(artifact.name, artifact.version);
|
|
96718
|
+
} catch (e) {
|
|
96719
|
+
logger.warn(`${e.message}`);
|
|
96720
|
+
}
|
|
96721
|
+
}
|
|
96722
|
+
deps[artifact.id] = { bin };
|
|
96612
96723
|
}, 4);
|
|
96613
96724
|
return { deps, depIdToPurl };
|
|
96614
96725
|
}
|
|
@@ -110405,7 +110516,7 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
|
|
|
110405
110516
|
if (result.error)
|
|
110406
110517
|
return void 0;
|
|
110407
110518
|
const packageIds = JSON.parse(await readFile8(outputFile, "utf-8")).result;
|
|
110408
|
-
return packageIds?.map((packageId) => this.depIdToPurl.get(packageId)).filter((purl) => purl !== void 0).map((purl) => `${purl.namespace}:${purl.name}
|
|
110519
|
+
return packageIds?.map((packageId) => this.depIdToPurl.get(packageId)).filter((purl) => purl !== void 0).map((purl) => `${purl.namespace}:${purl.name}`);
|
|
110409
110520
|
});
|
|
110410
110521
|
}
|
|
110411
110522
|
async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds, _experiment, telemetryHandler, analyzerTelemetryHandler) {
|
|
@@ -110415,7 +110526,7 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
|
|
|
110415
110526
|
const packagesToAnalyzeSet = new Set(packagesToAnalyze);
|
|
110416
110527
|
const filteredDeps = !packagesToAnalyze ? this.deps : Object.fromEntries(Object.entries(this.deps).filter(([packageId]) => {
|
|
110417
110528
|
const purl = this.depIdToPurl.get(packageId);
|
|
110418
|
-
return purl && packagesToAnalyzeSet.has(`${purl.namespace}:${purl.name}
|
|
110529
|
+
return purl && packagesToAnalyzeSet.has(`${purl.namespace}:${purl.name}`);
|
|
110419
110530
|
}));
|
|
110420
110531
|
return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), timeoutInSeconds, filteredDeps, telemetryHandler, analyzerTelemetryHandler);
|
|
110421
110532
|
} catch (e) {
|
|
@@ -110488,7 +110599,7 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
|
|
|
110488
110599
|
};
|
|
110489
110600
|
}
|
|
110490
110601
|
getPackagesExcludedUnrelatedToHeuristic() {
|
|
110491
|
-
return Object.entries(this.deps).filter(([_, { src, bin }]) => !src?.length && (!bin || bin.some((f2) => !existsSync9(f2)))).map(([packageId]) => this.depIdToPurl.get(packageId)).filter((purl) => purl !== void 0).map((purl) => `${purl.namespace}:${purl.name}
|
|
110602
|
+
return Object.entries(this.deps).filter(([_, { src, bin }]) => !src?.length && (!bin || bin.some((f2) => !existsSync9(f2)))).map(([packageId]) => this.depIdToPurl.get(packageId)).filter((purl) => purl !== void 0).map((purl) => `${purl.namespace}:${purl.name}`);
|
|
110492
110603
|
}
|
|
110493
110604
|
};
|
|
110494
110605
|
async function convertDependencyChain2(dependencyChain, tmpDir) {
|
|
@@ -110557,6 +110668,9 @@ async function convertSocketArtifacts2(rootDir, artifacts, tmpDir) {
|
|
|
110557
110668
|
}
|
|
110558
110669
|
}
|
|
110559
110670
|
}
|
|
110671
|
+
const artifactFile = getPathToArtifact(tmpDir, groupId, artifactId, type, classifier, version3);
|
|
110672
|
+
if (existsSync9(artifactFile))
|
|
110673
|
+
return artifactFile;
|
|
110560
110674
|
if (mavenInstalled && pomFile) {
|
|
110561
110675
|
try {
|
|
110562
110676
|
const dependencyGetCmd = cmdt`mvn -f=${basename8(resolve10(rootDir, pomFile))} dependency:get -DgroupId=${groupId} -DartifactId=${artifactId} -Dpackaging=${type} -Dclassifier${classifier} -Dversion=${version3} -Dtransitive=false`;
|
|
@@ -110567,7 +110681,6 @@ async function convertSocketArtifacts2(rootDir, artifacts, tmpDir) {
|
|
|
110567
110681
|
} catch {
|
|
110568
110682
|
}
|
|
110569
110683
|
}
|
|
110570
|
-
const artifactFile = getPathToArtifact(tmpDir, groupId, artifactId, type, classifier, version3);
|
|
110571
110684
|
await mkdir6(dirname11(artifactFile), { recursive: true });
|
|
110572
110685
|
const success = await resolveMavenArtifactFromStandardRepositories(groupId, artifactId, type, classifier, version3, artifactFile);
|
|
110573
110686
|
return success ? artifactFile : void 0;
|
|
@@ -110619,21 +110732,41 @@ import { tmpdir as tmpdir4 } from "os";
|
|
|
110619
110732
|
import { join as join15 } from "path";
|
|
110620
110733
|
|
|
110621
110734
|
// dist/whole-program-code-aware-vulnerability-scanner/js/dependency-preparation.js
|
|
110622
|
-
import { existsSync as
|
|
110735
|
+
import { existsSync as existsSync11 } from "fs";
|
|
110623
110736
|
import { resolve as resolve12 } from "path";
|
|
110624
110737
|
|
|
110625
110738
|
// dist/whole-program-code-aware-vulnerability-scanner/js/setup-npm-dependencies-for-analysis.js
|
|
110626
110739
|
var import_lodash9 = __toESM(require_lodash(), 1);
|
|
110627
|
-
import {
|
|
110740
|
+
import { existsSync as existsSync10 } from "fs";
|
|
110741
|
+
import { link, mkdir as mkdir7, readdir as readdir5 } from "fs/promises";
|
|
110628
110742
|
import { availableParallelism } from "os";
|
|
110629
110743
|
import { dirname as dirname12, join as join14, resolve as resolve11 } from "path";
|
|
110630
110744
|
var { chunk } = import_lodash9.default;
|
|
110631
110745
|
var ROOT_PACKAGE_METADATA_NAME = "UNIQUE_ROOT_PACKAGE_METADATA_NAME";
|
|
110632
|
-
async function setupDependenciesForAnalysis(subprojectDir, workspaceDir, directDependencies, artifactIdToArtifact) {
|
|
110746
|
+
async function setupDependenciesForAnalysis(subprojectDir, workspaceDir, directDependencies, artifactIdToArtifact, preinstallDir) {
|
|
110633
110747
|
return await withTmpDirectory("npm-packages", async (tmpDir) => {
|
|
110634
110748
|
const dirToInstallDependencies = resolve11(subprojectDir, "node_modules", ".jelly");
|
|
110635
|
-
|
|
110636
|
-
|
|
110749
|
+
let installedPackages;
|
|
110750
|
+
let failedPackages;
|
|
110751
|
+
if (preinstallDir && existsSync10(preinstallDir)) {
|
|
110752
|
+
const existingFiles = await readdir5(preinstallDir);
|
|
110753
|
+
installedPackages = [];
|
|
110754
|
+
failedPackages = [];
|
|
110755
|
+
for (const artifact of Object.values(artifactIdToArtifact)) {
|
|
110756
|
+
const tarballName = artifact.name.replace("@", "").replace("/", "-");
|
|
110757
|
+
const expectedFilename = artifact.version ? `${tarballName}-${artifact.version}.tgz` : void 0;
|
|
110758
|
+
const matchingTgz = existingFiles.find((f2) => expectedFilename ? f2 === expectedFilename : f2.endsWith(".tgz") && f2.startsWith(tarballName + "-"));
|
|
110759
|
+
if (matchingTgz) {
|
|
110760
|
+
installedPackages.push({ artifact, tarFileName: resolve11(preinstallDir, matchingTgz) });
|
|
110761
|
+
} else {
|
|
110762
|
+
failedPackages.push(artifact);
|
|
110763
|
+
}
|
|
110764
|
+
}
|
|
110765
|
+
logger.debug(`Reusing ${installedPackages.length} pre-installed tarballs from ${preinstallDir}`);
|
|
110766
|
+
} else {
|
|
110767
|
+
({ installedPackages, failedPackages } = await downloadDependenciesToDir(Object.values(artifactIdToArtifact), tmpDir));
|
|
110768
|
+
}
|
|
110769
|
+
const augmentedInstalledPackages = await extractDownloadedDependenciesToDir(dirToInstallDependencies, preinstallDir ?? tmpDir, installedPackages);
|
|
110637
110770
|
const packageMetadatas = convertToPackageMetadatas(workspaceDir, augmentedInstalledPackages, directDependencies, artifactIdToArtifact);
|
|
110638
110771
|
const packagePlacements = computePackagePlacements(packageMetadatas, resolve11(subprojectDir, "node_modules"));
|
|
110639
110772
|
await hardlinkPackages(packagePlacements);
|
|
@@ -110938,8 +111071,8 @@ function tarjanAndCondensation(packageMetadatas) {
|
|
|
110938
111071
|
}
|
|
110939
111072
|
|
|
110940
111073
|
// dist/whole-program-code-aware-vulnerability-scanner/js/dependency-preparation.js
|
|
110941
|
-
async function prepareNpmDependencies(subprojectDir, workspaceDir, artifactIdToArtifact, directDependencies, packageNamesToInstall) {
|
|
110942
|
-
if (
|
|
111074
|
+
async function prepareNpmDependencies(subprojectDir, workspaceDir, artifactIdToArtifact, directDependencies, packageNamesToInstall, preinstallDir) {
|
|
111075
|
+
if (existsSync11(resolve12(subprojectDir, "node_modules")))
|
|
110943
111076
|
return { failedPackages: [], installedPackages: [] };
|
|
110944
111077
|
const artifactToOriginal = /* @__PURE__ */ new Map();
|
|
110945
111078
|
const transitiveDependenciesToInstall = Object.fromEntries(Object.entries(artifactIdToArtifact).filter(([_, dep]) => packageNamesToInstall.includes(getPackageName(dep))).map(([depId, dep]) => {
|
|
@@ -110947,7 +111080,7 @@ async function prepareNpmDependencies(subprojectDir, workspaceDir, artifactIdToA
|
|
|
110947
111080
|
artifactToOriginal.set(artifact, dep);
|
|
110948
111081
|
return [depId, artifact];
|
|
110949
111082
|
}));
|
|
110950
|
-
const result = await setupDependenciesForAnalysis(subprojectDir, workspaceDir, directDependencies, transitiveDependenciesToInstall);
|
|
111083
|
+
const result = await setupDependenciesForAnalysis(subprojectDir, workspaceDir, directDependencies, transitiveDependenciesToInstall, preinstallDir);
|
|
110951
111084
|
return {
|
|
110952
111085
|
failedPackages: result.failedPackages.map((artifact) => artifactToOriginal.get(artifact)),
|
|
110953
111086
|
installedPackages: result.installedPackages.map((artifact) => artifactToOriginal.get(artifact))
|
|
@@ -110967,6 +111100,11 @@ function convertToArtifactForInstallation(dep) {
|
|
|
110967
111100
|
dependencies: dep.dependencies
|
|
110968
111101
|
};
|
|
110969
111102
|
}
|
|
111103
|
+
async function validateNpmDependencyDownloads(artifactIdToArtifact, packageNamesToInstall, preinstallDir) {
|
|
111104
|
+
const artifacts = Object.entries(artifactIdToArtifact).filter(([_, dep]) => packageNamesToInstall.includes(getPackageName(dep))).map(([_, dep]) => convertToArtifactForInstallation(dep));
|
|
111105
|
+
const { failedPackages } = await downloadDependenciesToDir(artifacts, preinstallDir);
|
|
111106
|
+
return failedPackages.map((p) => p.name);
|
|
111107
|
+
}
|
|
110970
111108
|
|
|
110971
111109
|
// dist/whole-program-code-aware-vulnerability-scanner/js/heuristics.js
|
|
110972
111110
|
var lazyIndirectionBoundOptions = {
|
|
@@ -111230,7 +111368,7 @@ var JSCodeAwareVulnerabilityScanner = class _JSCodeAwareVulnerabilityScanner {
|
|
|
111230
111368
|
...new Set(state.vulnerabilities.flatMap((v) => Object.values(v.vulnChainDetails?.transitiveDependencies ?? {}).filter((d) => d.vulnerable === true).map((d) => d.packageName)))
|
|
111231
111369
|
];
|
|
111232
111370
|
const packagesToInstall = !includePackages ? state.workspaceData.type === "coana" ? Object.values(state.workspaceData.data.dependencyTree.transitiveDependencies).map((dep) => getPackageName(dep)) : state.workspaceData.data.artifacts.map((dep) => getPackageName(dep)) : [.../* @__PURE__ */ new Set([...includePackages, ...vulnerablePackageNames])];
|
|
111233
|
-
const { failedPackages } = await prepareNpmDependencies(state.rootWorkingDir, this.projectDir, state.workspaceData.type === "coana" ? state.workspaceData.data.dependencyTree.transitiveDependencies : Object.fromEntries(state.workspaceData.data.artifacts.map((d) => [d.id, d])), state.workspaceData.type === "coana" ? state.workspaceData.data.dependencyTree.dependencies ?? [] : state.workspaceData.data.artifacts.filter((a2) => a2.direct).map((a2) => a2.id), packagesToInstall);
|
|
111371
|
+
const { failedPackages } = await prepareNpmDependencies(state.rootWorkingDir, this.projectDir, state.workspaceData.type === "coana" ? state.workspaceData.data.dependencyTree.transitiveDependencies : Object.fromEntries(state.workspaceData.data.artifacts.map((d) => [d.id, d])), state.workspaceData.type === "coana" ? state.workspaceData.data.dependencyTree.dependencies ?? [] : state.workspaceData.data.artifacts.filter((a2) => a2.direct).map((a2) => a2.id), packagesToInstall, state.preinstallDir);
|
|
111234
111372
|
this.packagesExcludedUnrelatedToHeuristic = failedPackages.map((p) => getPackageName(p));
|
|
111235
111373
|
}
|
|
111236
111374
|
async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds, experiment, telemetryHandler, analyzerTelemetryHandler) {
|
|
@@ -111384,7 +111522,7 @@ function transformSourceLocations(fileMappings, detectedOccurrences) {
|
|
|
111384
111522
|
// dist/whole-program-code-aware-vulnerability-scanner/go/go-code-aware-vulnerability-scanner.js
|
|
111385
111523
|
var import_lodash11 = __toESM(require_lodash(), 1);
|
|
111386
111524
|
import assert5 from "assert";
|
|
111387
|
-
import { existsSync as
|
|
111525
|
+
import { existsSync as existsSync12, createReadStream as createReadStream2, createWriteStream as createWriteStream4 } from "fs";
|
|
111388
111526
|
import { readFile as readFile10, rm as rm4, cp as cp6 } from "fs/promises";
|
|
111389
111527
|
import zlib2 from "zlib";
|
|
111390
111528
|
import { join as join16, resolve as resolve14, sep as sep3 } from "path";
|
|
@@ -111423,7 +111561,7 @@ var GoCodeAwareVulnerabilityScanner = class {
|
|
|
111423
111561
|
}
|
|
111424
111562
|
async runAnalysis(vulns, heuristic, timeoutInSeconds, _experiment, telemetryHandler, analyzerTelemetryHandler) {
|
|
111425
111563
|
logger.info("Started instantiating Go code-aware analysis");
|
|
111426
|
-
if (!
|
|
111564
|
+
if (!existsSync12(join16(this.projectDir, "go.mod")))
|
|
111427
111565
|
throw new Error("go.mod file not found in the project directory");
|
|
111428
111566
|
const { memoryLimitInMB } = this.options;
|
|
111429
111567
|
const tmpDir = await createTmpDirectory("goana-output");
|
|
@@ -111504,7 +111642,7 @@ ${stderr}`);
|
|
|
111504
111642
|
try {
|
|
111505
111643
|
await cp6(Dir, projectDir, { recursive: true });
|
|
111506
111644
|
const projGoMod = resolve14(projectDir, "go.mod");
|
|
111507
|
-
if (!
|
|
111645
|
+
if (!existsSync12(projGoMod))
|
|
111508
111646
|
await cp6(GoMod, projGoMod);
|
|
111509
111647
|
await exec2(cmdt`chmod --recursive +w ${projectDir}`);
|
|
111510
111648
|
await runGoModTidy(projectDir);
|
|
@@ -111532,7 +111670,7 @@ ${stderr}`);
|
|
|
111532
111670
|
}
|
|
111533
111671
|
static async runOnAlreadyDownloadedPackages(packages, vuln, options) {
|
|
111534
111672
|
for (const pkg of packages)
|
|
111535
|
-
assert5(
|
|
111673
|
+
assert5(existsSync12(join16(pkg, "go.mod")), `${pkg} does not contain a go.mod file`);
|
|
111536
111674
|
const [app, ...dependencies] = packages;
|
|
111537
111675
|
const projectDir = await createTmpDirectory("go-run-on-already-downloaded-packages-");
|
|
111538
111676
|
try {
|
|
@@ -111563,6 +111701,8 @@ ${stderr}`);
|
|
|
111563
111701
|
await rm4(projectDir, { recursive: true, force: true });
|
|
111564
111702
|
}
|
|
111565
111703
|
}
|
|
111704
|
+
// Go dependencies are auto-installed during the reachability analysis process
|
|
111705
|
+
// (e.g. by `go build`), so there are no pre-install failures to track here.
|
|
111566
111706
|
getPackagesExcludedUnrelatedToHeuristic() {
|
|
111567
111707
|
return [];
|
|
111568
111708
|
}
|
|
@@ -111570,7 +111710,7 @@ ${stderr}`);
|
|
|
111570
111710
|
|
|
111571
111711
|
// dist/whole-program-code-aware-vulnerability-scanner/rust/rust-code-aware-vulnerability-scanner.js
|
|
111572
111712
|
var import_lodash12 = __toESM(require_lodash(), 1);
|
|
111573
|
-
import { existsSync as
|
|
111713
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
111574
111714
|
import { readFile as readFile11, writeFile as writeFile9 } from "node:fs/promises";
|
|
111575
111715
|
import { basename as basename10, dirname as dirname14, resolve as resolve15 } from "node:path";
|
|
111576
111716
|
|
|
@@ -111671,7 +111811,7 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
|
|
|
111671
111811
|
let appCrateName;
|
|
111672
111812
|
const appSrc = [];
|
|
111673
111813
|
const dependencies = {};
|
|
111674
|
-
const appCrateInfo =
|
|
111814
|
+
const appCrateInfo = existsSync13(cargoTomlPath) ? await getCrateInfo(cargoTomlPath) : void 0;
|
|
111675
111815
|
if (appCrateInfo?.name) {
|
|
111676
111816
|
appSrc.push(...i([appCrateInfo.lib, ...appCrateInfo.examples ?? [], ...appCrateInfo.tests ?? []]));
|
|
111677
111817
|
appCrateName = appCrateInfo.name.replaceAll("-", "_");
|
|
@@ -111783,7 +111923,7 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
|
|
|
111783
111923
|
const appDependencies = {};
|
|
111784
111924
|
if (rustDependencyChain[0].src && rustDependencyChain[0].src.length > 0) {
|
|
111785
111925
|
const appCargoTomlPath = resolve15(rustDependencyChain[0].src[0], "..", "Cargo.toml");
|
|
111786
|
-
if (
|
|
111926
|
+
if (existsSync13(appCargoTomlPath)) {
|
|
111787
111927
|
const cargoTomlDeps = await extractDependenciesFromCargoToml(appCargoTomlPath);
|
|
111788
111928
|
for (const [packageName, names] of cargoTomlDeps.entries()) {
|
|
111789
111929
|
const depId = packageNameToId.get(packageName);
|
|
@@ -111810,7 +111950,7 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
|
|
|
111810
111950
|
const dependencies = {};
|
|
111811
111951
|
if (dep.src && dep.src.length > 0) {
|
|
111812
111952
|
const depCargoTomlPath = resolve15(dep.src[0], "..", "Cargo.toml");
|
|
111813
|
-
if (
|
|
111953
|
+
if (existsSync13(depCargoTomlPath)) {
|
|
111814
111954
|
const cargoTomlDeps = await extractDependenciesFromCargoToml(depCargoTomlPath);
|
|
111815
111955
|
for (const [packageName, names] of cargoTomlDeps.entries()) {
|
|
111816
111956
|
const transDepId = packageNameToId.get(packageName);
|
|
@@ -111939,7 +112079,7 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
|
|
|
111939
112079
|
};
|
|
111940
112080
|
}
|
|
111941
112081
|
getPackagesExcludedUnrelatedToHeuristic() {
|
|
111942
|
-
return Object.entries(this.deps).filter(([_, { src, bin }]) => !src?.length && (!bin || bin.some((f2) => !
|
|
112082
|
+
return Object.entries(this.deps).filter(([_, { src, bin }]) => !src?.length && (!bin || bin.some((f2) => !existsSync13(f2)))).map(([packageId]) => this.depIdToPurl.get(packageId)?.name).filter((name2) => name2 !== void 0).map((name2) => name2);
|
|
111943
112083
|
}
|
|
111944
112084
|
};
|
|
111945
112085
|
async function convertDependencyChain3(dependencyChain, tmpDir) {
|
|
@@ -111971,7 +112111,7 @@ function getCargoLocalRepositoryPaths() {
|
|
|
111971
112111
|
// Cargo git dependencies
|
|
111972
112112
|
{ path: resolve15(cargoHome, "git", "checkouts"), type: "git" }
|
|
111973
112113
|
];
|
|
111974
|
-
return repositories.filter((repo) =>
|
|
112114
|
+
return repositories.filter((repo) => existsSync13(repo.path));
|
|
111975
112115
|
}
|
|
111976
112116
|
async function findCargoPackageInLocalRepo(repo, packageName, version3, tmpDir) {
|
|
111977
112117
|
try {
|
|
@@ -112011,10 +112151,10 @@ async function findCargoPackageInLocalRepo(repo, packageName, version3, tmpDir)
|
|
|
112011
112151
|
}
|
|
112012
112152
|
async function extractCargoCrate(crateFilePath, packageName, version3, tmpDir) {
|
|
112013
112153
|
const packageDir = resolve15(tmpDir, `${packageName}-${version3}`);
|
|
112014
|
-
if (
|
|
112154
|
+
if (existsSync13(packageDir)) {
|
|
112015
112155
|
try {
|
|
112016
112156
|
const cargoTomlPath = resolve15(packageDir, "Cargo.toml");
|
|
112017
|
-
if (
|
|
112157
|
+
if (existsSync13(cargoTomlPath)) {
|
|
112018
112158
|
const depCrateInfo = await getCrateInfo(cargoTomlPath);
|
|
112019
112159
|
return [depCrateInfo.lib];
|
|
112020
112160
|
}
|
|
@@ -112034,7 +112174,7 @@ async function extractCargoCrate(crateFilePath, packageName, version3, tmpDir) {
|
|
|
112034
112174
|
}
|
|
112035
112175
|
async function downloadAndExtractCargoCrate(packageName, version3, tmpDir) {
|
|
112036
112176
|
const packageFile = resolve15(tmpDir, `${packageName}-${version3}.crate`);
|
|
112037
|
-
if (!
|
|
112177
|
+
if (!existsSync13(packageFile)) {
|
|
112038
112178
|
const packageUrl = getUrlForCrate(packageName, version3);
|
|
112039
112179
|
const success = await downloadFile(packageUrl, packageFile);
|
|
112040
112180
|
if (!success) {
|
|
@@ -112067,7 +112207,7 @@ async function convertSocketArtifacts3(artifacts, tmpDir, artifactNameToId) {
|
|
|
112067
112207
|
const dependencies = {};
|
|
112068
112208
|
if (src && src.length > 0) {
|
|
112069
112209
|
const cargoTomlPath = resolve15(dirname14(src[0]), "Cargo.toml");
|
|
112070
|
-
if (
|
|
112210
|
+
if (existsSync13(cargoTomlPath)) {
|
|
112071
112211
|
const cargoTomlDeps = await extractDependenciesFromCargoToml(cargoTomlPath);
|
|
112072
112212
|
for (const [packageName, names] of cargoTomlDeps.entries()) {
|
|
112073
112213
|
const depArtifactId = artifactNameToId.get(packageName);
|
|
@@ -112340,12 +112480,12 @@ var PythonCodeAwareVulnerabilityScanner = class {
|
|
|
112340
112480
|
this.projectDir = projectDir;
|
|
112341
112481
|
this.vm = new PythonVersionsManager(state.rootWorkingDir);
|
|
112342
112482
|
}
|
|
112343
|
-
async prepareDependencies(preInstalledDepInfos, vulns, heuristic) {
|
|
112483
|
+
async prepareDependencies(preInstalledDepInfos, vulns, heuristic, preinstallDir) {
|
|
112344
112484
|
const packagesToExclude = heuristic.getPackagesToExcludeFromAnalysis?.(vulns);
|
|
112345
112485
|
const packagesToInstall = uniqBy(preInstalledDepInfos.filter((n) => !packagesToExclude?.has(n.packageName)), "packageName");
|
|
112346
|
-
if (!await this.tryUsingPreinstalledVirtualEnv(packagesToInstall)) {
|
|
112486
|
+
if (!await this.tryUsingPreinstalledVirtualEnv(packagesToInstall) && !(preinstallDir && await this.tryUsingVenvFromPreinstallDir(preinstallDir))) {
|
|
112347
112487
|
logger.info(`Setting up virtual environment`);
|
|
112348
|
-
await this.prepareVirtualEnv(packagesToInstall);
|
|
112488
|
+
await this.prepareVirtualEnv(packagesToInstall, preinstallDir);
|
|
112349
112489
|
logger.info("Done setting up virtual environment");
|
|
112350
112490
|
}
|
|
112351
112491
|
}
|
|
@@ -112560,7 +112700,7 @@ ${msg}`;
|
|
|
112560
112700
|
// public for testing only
|
|
112561
112701
|
async tryUsingPreinstalledVirtualEnv(packages) {
|
|
112562
112702
|
const preinstallVirtualEnvPath = resolve17(this.projectDir, ".venv");
|
|
112563
|
-
if (!
|
|
112703
|
+
if (!existsSync14(preinstallVirtualEnvPath))
|
|
112564
112704
|
return false;
|
|
112565
112705
|
logger.info(`Checking preinstalled virtual environment at ${preinstallVirtualEnvPath}`);
|
|
112566
112706
|
try {
|
|
@@ -112581,12 +112721,20 @@ ${msg}`;
|
|
|
112581
112721
|
await this.updateVirtualEnvInfo(this.projectDir);
|
|
112582
112722
|
return true;
|
|
112583
112723
|
}
|
|
112724
|
+
async tryUsingVenvFromPreinstallDir(preinstallDir) {
|
|
112725
|
+
const venvPath = join17(preinstallDir, ".venv");
|
|
112726
|
+
if (!existsSync14(venvPath))
|
|
112727
|
+
return false;
|
|
112728
|
+
logger.info(`Reusing virtual environment from pre-install at ${venvPath}`);
|
|
112729
|
+
await this.updateVirtualEnvInfo(preinstallDir);
|
|
112730
|
+
return true;
|
|
112731
|
+
}
|
|
112584
112732
|
// public for testing only
|
|
112585
|
-
async prepareVirtualEnv(packages) {
|
|
112733
|
+
async prepareVirtualEnv(packages, preinstallDir) {
|
|
112586
112734
|
const uvCommand = getUvCommand();
|
|
112587
112735
|
if (!await hasUv())
|
|
112588
112736
|
throw new Error("uv (https://docs.astral.sh/uv/) is missing, but is required for Python analysis");
|
|
112589
|
-
const tmpDir = await createTmpDirectory("coana-python-analysis-venv");
|
|
112737
|
+
const tmpDir = preinstallDir ?? await createTmpDirectory("coana-python-analysis-venv");
|
|
112590
112738
|
const virtualEnvFolder = join17(tmpDir, ".venv");
|
|
112591
112739
|
const pythonExecutable = await this.vm.getPythonExecutableForWorkspace(this.projectDir, false);
|
|
112592
112740
|
await exec2(cmdt`${uvCommand} venv --python ${pythonExecutable} .venv`, tmpDir);
|
|
@@ -112659,7 +112807,7 @@ ${msg}`;
|
|
|
112659
112807
|
await this.updateVirtualEnvInfo(tmpDir, installStats);
|
|
112660
112808
|
}
|
|
112661
112809
|
async updateVirtualEnvInfo(virtualEnvFolder, packageInstallationStats) {
|
|
112662
|
-
const entries = await
|
|
112810
|
+
const entries = await readdir6(join17(virtualEnvFolder, ".venv", "lib"));
|
|
112663
112811
|
const pydir = entries.find((entry) => entry.startsWith("python"));
|
|
112664
112812
|
assert6(pydir, `No python* directory found in virtual environment: ${util5.inspect(entries)}`);
|
|
112665
112813
|
this.virtualEnvInfo = {
|
|
@@ -112756,7 +112904,7 @@ async function setupMambalade() {
|
|
|
112756
112904
|
logger.debug(`Using Python interpreter: ${python}`);
|
|
112757
112905
|
await exec2(cmdt`${uvCommand} venv --no-project --no-config --python=${python} .`, venvDir);
|
|
112758
112906
|
const mambaladeWheelsPath = ToolPathResolver.mambaladeDistPath;
|
|
112759
|
-
const mambaladeWheels = (await
|
|
112907
|
+
const mambaladeWheels = (await readdir6(mambaladeWheelsPath)).filter((f2) => f2.endsWith(".whl")).map((f2) => join17(mambaladeWheelsPath, f2));
|
|
112760
112908
|
if (!mambaladeWheels.length)
|
|
112761
112909
|
throw new Error(`No mambalade wheel files found in ${mambaladeWheelsPath}`);
|
|
112762
112910
|
logger.debug(`Installing mambalade wheels: ${mambaladeWheels.join(", ")}`);
|
|
@@ -112892,6 +113040,13 @@ async function processProject(projectDir) {
|
|
|
112892
113040
|
}, 4)).flat());
|
|
112893
113041
|
}
|
|
112894
113042
|
|
|
113043
|
+
// dist/analyzers/analyzer.js
|
|
113044
|
+
function checkForInstallErrors(failedPackages, otherAnalysisOptions) {
|
|
113045
|
+
if (failedPackages.length > 0 && otherAnalysisOptions.haltOnInstallErrors) {
|
|
113046
|
+
throw new InstallError(failedPackages);
|
|
113047
|
+
}
|
|
113048
|
+
}
|
|
113049
|
+
|
|
112895
113050
|
// dist/analyzers/pip-analyzer.js
|
|
112896
113051
|
var { once: once4 } = import_lodash16.default;
|
|
112897
113052
|
var PipAnalyzer = class {
|
|
@@ -112910,9 +113065,16 @@ var PipAnalyzer = class {
|
|
|
112910
113065
|
this.heuristic = MambaladeHeuristics.createOnlyVulnPathPackagesHeuristic(this.preInstalledDepInfos);
|
|
112911
113066
|
}
|
|
112912
113067
|
prepareScanner = once4(async () => {
|
|
112913
|
-
await this.scanner.prepareDependencies(this.preInstalledDepInfos, this.state.vulnerabilities.filter((v) => Array.isArray(v.vulnerabilityAccessPaths)), this.heuristic);
|
|
113068
|
+
await this.scanner.prepareDependencies(this.preInstalledDepInfos, this.state.vulnerabilities.filter((v) => Array.isArray(v.vulnerabilityAccessPaths)), this.heuristic, this.state.preinstallDir);
|
|
112914
113069
|
return this.scanner;
|
|
112915
113070
|
});
|
|
113071
|
+
async installDependencies(preinstallDir) {
|
|
113072
|
+
if (existsSync15(resolve19(this.projectDir, ".venv")))
|
|
113073
|
+
return [];
|
|
113074
|
+
const scanner = new PythonCodeAwareVulnerabilityScanner(this.state, this.projectDir);
|
|
113075
|
+
await scanner.prepareDependencies(this.preInstalledDepInfos, this.state.vulnerabilities.filter((v) => Array.isArray(v.vulnerabilityAccessPaths)), this.heuristic, preinstallDir);
|
|
113076
|
+
return scanner.getPackagesExcludedUnrelatedToHeuristic();
|
|
113077
|
+
}
|
|
112916
113078
|
async runPhantomDependencyAnalysis() {
|
|
112917
113079
|
const info = (await this.prepareScanner()).getVirtualEnvInfo();
|
|
112918
113080
|
assert7(info !== void 0);
|
|
@@ -112935,6 +113097,7 @@ var PipAnalyzer = class {
|
|
|
112935
113097
|
};
|
|
112936
113098
|
try {
|
|
112937
113099
|
const scanner = await this.prepareScanner();
|
|
113100
|
+
checkForInstallErrors(scanner.getPackagesExcludedUnrelatedToHeuristic(), this.state.otherAnalysisOptions);
|
|
112938
113101
|
const venvInfo = scanner.getVirtualEnvInfo();
|
|
112939
113102
|
this.preinstalledDependencies = venvInfo !== void 0 && !venvInfo.temporary ? "YES" : "NO";
|
|
112940
113103
|
return await analyzeWithHeuristics(this.state, vulns, [this.heuristic], false, scanner, wrappedCollector, statusUpdater);
|
|
@@ -113411,6 +113574,15 @@ var GoAnalyzer = class {
|
|
|
113411
113574
|
this.state = state;
|
|
113412
113575
|
this.projectDir = projectDir;
|
|
113413
113576
|
}
|
|
113577
|
+
async installDependencies(_preinstallDir) {
|
|
113578
|
+
try {
|
|
113579
|
+
await runCommandResolveStdOut2(cmdt`go build ./...`, this.projectDir);
|
|
113580
|
+
return [];
|
|
113581
|
+
} catch (e) {
|
|
113582
|
+
logger.warn(`go build failed for ${this.projectDir}: ${e instanceof Error ? e.message : String(e)}`);
|
|
113583
|
+
return ["(go build failure)"];
|
|
113584
|
+
}
|
|
113585
|
+
}
|
|
113414
113586
|
async runPhantomDependencyAnalysis() {
|
|
113415
113587
|
return void 0;
|
|
113416
113588
|
}
|
|
@@ -113498,9 +113670,16 @@ var MavenAnalyzer = class {
|
|
|
113498
113670
|
constructor(state) {
|
|
113499
113671
|
this.state = state;
|
|
113500
113672
|
}
|
|
113673
|
+
async createScanner(tmpDir, statusUpdater) {
|
|
113674
|
+
return this.state.workspaceData.type === "coana" ? JavaCodeAwareVulnerabilityScanner.initFromDependencyTree(this.state.workspaceData.data.dependencyTree, tmpDir, statusUpdater) : JavaCodeAwareVulnerabilityScanner.initFromSocketArtifacts(this.state.subprojectDir, this.state.workspaceData.data.artifacts, tmpDir, statusUpdater);
|
|
113675
|
+
}
|
|
113676
|
+
async installDependencies(preinstallDir) {
|
|
113677
|
+
const scanner = await this.createScanner(preinstallDir);
|
|
113678
|
+
return scanner.getPackagesExcludedUnrelatedToHeuristic();
|
|
113679
|
+
}
|
|
113501
113680
|
async runPhantomDependencyAnalysis() {
|
|
113502
113681
|
return withTmpDirectory("maven-phantom-dependency-analysis", async (tmpDir) => {
|
|
113503
|
-
const scanner =
|
|
113682
|
+
const scanner = await this.createScanner(tmpDir);
|
|
113504
113683
|
return scanner.runPhantomDependencyAnalysis(this.state.reachabilityAnalysisOptions.timeoutSeconds.allVulnRuns);
|
|
113505
113684
|
});
|
|
113506
113685
|
}
|
|
@@ -113512,11 +113691,17 @@ var MavenAnalyzer = class {
|
|
|
113512
113691
|
}
|
|
113513
113692
|
analysisMetadataCollector?.(metadata);
|
|
113514
113693
|
};
|
|
113515
|
-
|
|
113516
|
-
|
|
113694
|
+
const preinstallDir = this.state.preinstallDir;
|
|
113695
|
+
const runWithTmpDir = async (tmpDir) => {
|
|
113696
|
+
const scanner = await this.createScanner(tmpDir, statusUpdater);
|
|
113697
|
+
checkForInstallErrors(scanner.getPackagesExcludedUnrelatedToHeuristic(), this.state.otherAnalysisOptions);
|
|
113517
113698
|
const heuristicsInOrder = [AlucardHeuristics.ALL_PACKAGES];
|
|
113518
113699
|
return await analyzeWithHeuristics(this.state, vulns, heuristicsInOrder, false, scanner, wrappedCollector, statusUpdater);
|
|
113519
|
-
}
|
|
113700
|
+
};
|
|
113701
|
+
if (preinstallDir) {
|
|
113702
|
+
return runWithTmpDir(preinstallDir);
|
|
113703
|
+
}
|
|
113704
|
+
return withTmpDirectory("maven-reachability-analysis", runWithTmpDir);
|
|
113520
113705
|
}
|
|
113521
113706
|
async getWorkspaceDiagnostics() {
|
|
113522
113707
|
let sourceFilesDetected;
|
|
@@ -113545,7 +113730,7 @@ var MavenAnalyzer = class {
|
|
|
113545
113730
|
// dist/analyzers/npm-analyzer.js
|
|
113546
113731
|
var import_lodash19 = __toESM(require_lodash(), 1);
|
|
113547
113732
|
var import_picomatch4 = __toESM(require_picomatch2(), 1);
|
|
113548
|
-
import { existsSync as
|
|
113733
|
+
import { existsSync as existsSync16 } from "fs";
|
|
113549
113734
|
import { rm as rm6 } from "fs/promises";
|
|
113550
113735
|
import { relative as relative8, resolve as resolve20 } from "path";
|
|
113551
113736
|
|
|
@@ -113572,6 +113757,17 @@ var NpmAnalyzer = class {
|
|
|
113572
113757
|
this.state = state;
|
|
113573
113758
|
this.projectDir = projectDir;
|
|
113574
113759
|
}
|
|
113760
|
+
async installDependencies(preinstallDir) {
|
|
113761
|
+
if (existsSync16(resolve20(this.state.subprojectDir, "node_modules")))
|
|
113762
|
+
return [];
|
|
113763
|
+
const artifactIdToArtifact = this.state.workspaceData.type === "coana" ? this.state.workspaceData.data.dependencyTree.transitiveDependencies : Object.fromEntries(this.state.workspaceData.data.artifacts.map((d) => [d.id, d]));
|
|
113764
|
+
const vulnPathPackages = computePackagesOnVulnPath(this.state.vulnerabilities);
|
|
113765
|
+
const vulnerablePackageNames = [
|
|
113766
|
+
...new Set(this.state.vulnerabilities.flatMap((v) => Object.values(v.vulnChainDetails?.transitiveDependencies ?? {}).filter((d) => d.vulnerable === true).map((d) => d.packageName)))
|
|
113767
|
+
];
|
|
113768
|
+
const packagesToInstall = [.../* @__PURE__ */ new Set([...vulnPathPackages, ...vulnerablePackageNames])];
|
|
113769
|
+
return validateNpmDependencyDownloads(artifactIdToArtifact, packagesToInstall, preinstallDir);
|
|
113770
|
+
}
|
|
113575
113771
|
async runPhantomDependencyAnalysis() {
|
|
113576
113772
|
try {
|
|
113577
113773
|
return (await runJellyPhantomDependencyAnalysis(this.projectDir, this.state.reachabilityAnalysisOptions)).map((r) => r.name);
|
|
@@ -113581,7 +113777,7 @@ var NpmAnalyzer = class {
|
|
|
113581
113777
|
}
|
|
113582
113778
|
async runReachabilityAnalysis(vulns, analysisMetadataCollector, statusUpdater) {
|
|
113583
113779
|
const heuristicsInOrder = this.state.otherAnalysisOptions.lightweightReachability ? [heuristics.IGNORE_DEPENDENCIES_AND_MAX_ROUNDS_3] : [heuristics.ONLY_VULN_PATH_PACKAGES_EXCEPT_VULNERABLE_PACKAGE];
|
|
113584
|
-
const nodeModulesAlreadyExisted =
|
|
113780
|
+
const nodeModulesAlreadyExisted = existsSync16(resolve20(this.state.subprojectDir, "node_modules"));
|
|
113585
113781
|
this.preinstalledDependencies = nodeModulesAlreadyExisted ? "YES" : "NO";
|
|
113586
113782
|
const wrappedCollector = (metadata) => {
|
|
113587
113783
|
const jellyDiagnostics = metadata.analysisDiagnostics;
|
|
@@ -113593,6 +113789,7 @@ var NpmAnalyzer = class {
|
|
|
113593
113789
|
try {
|
|
113594
113790
|
const vulnerabilityScanner = new JSCodeAwareVulnerabilityScanner(this.state.rootWorkingDir, this.projectDir, this.state.reachabilityAnalysisOptions);
|
|
113595
113791
|
await vulnerabilityScanner.prepareDependencies(this.state, heuristicsInOrder[0]);
|
|
113792
|
+
checkForInstallErrors(vulnerabilityScanner.getPackagesExcludedUnrelatedToHeuristic(), this.state.otherAnalysisOptions);
|
|
113596
113793
|
logger.info(`Running import reachability analysis for ${vulns.length} ${pluralize(vulns.length, "vulnerability")}`);
|
|
113597
113794
|
let reachable;
|
|
113598
113795
|
const ghsaIds = extractGhsaIdsFromVulnUrls(vulns.map((v) => v.url));
|
|
@@ -113706,9 +113903,9 @@ ${e.stack}` : String(e),
|
|
|
113706
113903
|
return res;
|
|
113707
113904
|
} finally {
|
|
113708
113905
|
if (!nodeModulesAlreadyExisted) {
|
|
113709
|
-
if (
|
|
113906
|
+
if (existsSync16(resolve20(this.state.subprojectDir, "node_modules")))
|
|
113710
113907
|
await rm6(resolve20(this.state.subprojectDir, "node_modules"), { recursive: true });
|
|
113711
|
-
if (
|
|
113908
|
+
if (existsSync16(resolve20(this.projectDir, "node_modules")))
|
|
113712
113909
|
await rm6(resolve20(this.projectDir, "node_modules"), { recursive: true });
|
|
113713
113910
|
}
|
|
113714
113911
|
}
|
|
@@ -113749,9 +113946,16 @@ var NugetAnalyzer = class {
|
|
|
113749
113946
|
constructor(state) {
|
|
113750
113947
|
this.state = state;
|
|
113751
113948
|
}
|
|
113949
|
+
async createScanner(tmpDir, statusUpdater) {
|
|
113950
|
+
return this.state.workspaceData.type === "coana" ? DotnetCodeAwareVulnerabilityScanner.initFromDependencyTree(this.state.workspaceData.data.dependencyTree, statusUpdater) : DotnetCodeAwareVulnerabilityScanner.initFromSocketArtifacts(this.state.subprojectDir, this.state.workspaceData.data.manifestFiles, this.state.workspaceData.data.artifacts, tmpDir, statusUpdater);
|
|
113951
|
+
}
|
|
113952
|
+
async installDependencies(preinstallDir) {
|
|
113953
|
+
const scanner = await this.createScanner(preinstallDir);
|
|
113954
|
+
return scanner.getPackagesExcludedUnrelatedToHeuristic();
|
|
113955
|
+
}
|
|
113752
113956
|
async runPhantomDependencyAnalysis() {
|
|
113753
113957
|
return withTmpDirectory("nuget-phantom-dependency-analysis", async (tmpDir) => {
|
|
113754
|
-
const scanner =
|
|
113958
|
+
const scanner = await this.createScanner(tmpDir);
|
|
113755
113959
|
return scanner.runPhantomDependencyAnalysis(this.state.reachabilityAnalysisOptions.timeoutSeconds.allVulnRuns);
|
|
113756
113960
|
});
|
|
113757
113961
|
}
|
|
@@ -113763,11 +113967,17 @@ var NugetAnalyzer = class {
|
|
|
113763
113967
|
}
|
|
113764
113968
|
analysisMetadataCollector?.(metadata);
|
|
113765
113969
|
};
|
|
113766
|
-
|
|
113767
|
-
|
|
113970
|
+
const preinstallDir = this.state.preinstallDir;
|
|
113971
|
+
const runWithTmpDir = async (tmpDir) => {
|
|
113972
|
+
const scanner = await this.createScanner(tmpDir, statusUpdater);
|
|
113973
|
+
checkForInstallErrors(scanner.getPackagesExcludedUnrelatedToHeuristic(), this.state.otherAnalysisOptions);
|
|
113768
113974
|
const heuristicsInOrder = [CocoaHeuristics.ALL_PACKAGES];
|
|
113769
113975
|
return await analyzeWithHeuristics(this.state, vulns, heuristicsInOrder, false, scanner, wrappedCollector, statusUpdater);
|
|
113770
|
-
}
|
|
113976
|
+
};
|
|
113977
|
+
if (preinstallDir) {
|
|
113978
|
+
return runWithTmpDir(preinstallDir);
|
|
113979
|
+
}
|
|
113980
|
+
return withTmpDirectory("nuget-reachability-analysis", runWithTmpDir);
|
|
113771
113981
|
}
|
|
113772
113982
|
async getWorkspaceDiagnostics() {
|
|
113773
113983
|
let sourceFilesDetected;
|
|
@@ -113795,13 +114005,13 @@ var NugetAnalyzer = class {
|
|
|
113795
114005
|
|
|
113796
114006
|
// dist/analyzers/ruby-analyzer.js
|
|
113797
114007
|
var import_lodash21 = __toESM(require_lodash(), 1);
|
|
113798
|
-
import { existsSync as
|
|
114008
|
+
import { existsSync as existsSync18 } from "fs";
|
|
113799
114009
|
import { resolve as resolve21 } from "path";
|
|
113800
114010
|
|
|
113801
114011
|
// dist/whole-program-code-aware-vulnerability-scanner/ruby/ruby-code-aware-vulnerability-scanner.js
|
|
113802
114012
|
var import_lodash20 = __toESM(require_lodash(), 1);
|
|
113803
|
-
import { createWriteStream as createWriteStream5, existsSync as
|
|
113804
|
-
import { mkdir as mkdir9, readdir as
|
|
114013
|
+
import { createWriteStream as createWriteStream5, existsSync as existsSync17 } from "fs";
|
|
114014
|
+
import { mkdir as mkdir9, readdir as readdir7, readFile as readFile13, rm as rm7 } from "fs/promises";
|
|
113805
114015
|
import { join as join18, relative as relative9 } from "path";
|
|
113806
114016
|
import { pipeline as pipeline3 } from "stream/promises";
|
|
113807
114017
|
var PRINT_ANALYSIS_COMMAND = false;
|
|
@@ -113818,12 +114028,12 @@ var RubyCodeAwareVulnerabilityScanner = class {
|
|
|
113818
114028
|
this.projectDir = projectDir;
|
|
113819
114029
|
this.options = options;
|
|
113820
114030
|
}
|
|
113821
|
-
async prepareDependencies(preInstalledDepInfos, vulns, heuristic) {
|
|
113822
|
-
const vendorDir = join18(this.projectDir, "vendor");
|
|
113823
|
-
if (
|
|
114031
|
+
async prepareDependencies(preInstalledDepInfos, vulns, heuristic, preinstallDir) {
|
|
114032
|
+
const vendorDir = preinstallDir ?? join18(this.projectDir, "vendor");
|
|
114033
|
+
if (existsSync17(vendorDir)) {
|
|
113824
114034
|
logger.info(`Vendor directory already exists at ${vendorDir}, skipping gem installation`);
|
|
113825
114035
|
this.vendorDir = vendorDir;
|
|
113826
|
-
this.vendorDirWasCreated =
|
|
114036
|
+
this.vendorDirWasCreated = !preinstallDir;
|
|
113827
114037
|
return;
|
|
113828
114038
|
}
|
|
113829
114039
|
const packagesToIncludeNames = heuristic.getPackagesToIncludeInAnalysis?.(vulns)?.map((p) => p.packageName);
|
|
@@ -113854,7 +114064,7 @@ var RubyCodeAwareVulnerabilityScanner = class {
|
|
|
113854
114064
|
if (!this.vendorDir)
|
|
113855
114065
|
throw new Error("Assertion error: The vendor directory is not correctly initialized");
|
|
113856
114066
|
const analyzerPath = ToolPathResolver.callgraphReachabilityAnalyzersCliPath;
|
|
113857
|
-
if (!
|
|
114067
|
+
if (!existsSync17(analyzerPath))
|
|
113858
114068
|
throw new Error(`callgraph-reachability-analyzers CLI not found at ${analyzerPath}`);
|
|
113859
114069
|
const vulnAccPaths = sortedUniq2(vulns.flatMap((v) => v.vulnerabilityAccessPaths).sort());
|
|
113860
114070
|
const vulnsOutputFile = join18(tmpDir, "vulns.json");
|
|
@@ -113865,12 +114075,12 @@ var RubyCodeAwareVulnerabilityScanner = class {
|
|
|
113865
114075
|
const loadPaths = Array.from(loadPathsToPackageNames.keys());
|
|
113866
114076
|
if (failedToFindLoadPath.length > 0) {
|
|
113867
114077
|
this.packagesExcludedUnrelatedToHeuristic.push(...failedToFindLoadPath.map((p) => p.packageName));
|
|
113868
|
-
logger.
|
|
114078
|
+
logger.debug(`Failed to find package installation path for ${failedToFindLoadPath.map((p) => p.packageName).join(", ")}`);
|
|
113869
114079
|
}
|
|
113870
114080
|
if (loadPaths.length === 0) {
|
|
113871
114081
|
return {
|
|
113872
114082
|
type: "error",
|
|
113873
|
-
message:
|
|
114083
|
+
message: `${FAILED_TO_INSTALL_PACKAGE_KEY}No load paths found for the packages to analyze`
|
|
113874
114084
|
};
|
|
113875
114085
|
}
|
|
113876
114086
|
const cmd = cmdt`
|
|
@@ -113929,7 +114139,7 @@ var RubyCodeAwareVulnerabilityScanner = class {
|
|
|
113929
114139
|
return this.packagesExcludedUnrelatedToHeuristic;
|
|
113930
114140
|
}
|
|
113931
114141
|
async cleanup() {
|
|
113932
|
-
if (this.vendorDirWasCreated && this.vendorDir &&
|
|
114142
|
+
if (this.vendorDirWasCreated && this.vendorDir && existsSync17(this.vendorDir)) {
|
|
113933
114143
|
logger.info(`Deleting auto-generated vendor directory at ${this.vendorDir}`);
|
|
113934
114144
|
await rm7(this.vendorDir, { recursive: true, force: true }).catch(() => {
|
|
113935
114145
|
});
|
|
@@ -113945,7 +114155,7 @@ var RubyCodeAwareVulnerabilityScanner = class {
|
|
|
113945
114155
|
if (this.vendorDirWasCreated) {
|
|
113946
114156
|
for (const pkg of packagesToAnalyze) {
|
|
113947
114157
|
const libPath = join18(this.vendorDir, `${pkg.packageName}-${pkg.version}`, "lib");
|
|
113948
|
-
if (
|
|
114158
|
+
if (existsSync17(libPath))
|
|
113949
114159
|
loadPathsToPackageNames.set(libPath, `${pkg.packageName}@${pkg.version}`);
|
|
113950
114160
|
else
|
|
113951
114161
|
failedToFindLoadPath.push(pkg);
|
|
@@ -113953,13 +114163,13 @@ var RubyCodeAwareVulnerabilityScanner = class {
|
|
|
113953
114163
|
return { loadPathsToPackageNames, failedToFindLoadPath };
|
|
113954
114164
|
}
|
|
113955
114165
|
const bundlerGemsDir = join18(this.vendorDir, "bundle", "ruby");
|
|
113956
|
-
if (
|
|
113957
|
-
const rubyVersions = await
|
|
114166
|
+
if (existsSync17(bundlerGemsDir)) {
|
|
114167
|
+
const rubyVersions = await readdir7(bundlerGemsDir);
|
|
113958
114168
|
for (const rubyVersion of rubyVersions) {
|
|
113959
114169
|
const gemsDir = join18(bundlerGemsDir, rubyVersion, "gems");
|
|
113960
|
-
if (
|
|
114170
|
+
if (existsSync17(gemsDir)) {
|
|
113961
114171
|
const nameToEntry = /* @__PURE__ */ new Map();
|
|
113962
|
-
for (const entry of await
|
|
114172
|
+
for (const entry of await readdir7(gemsDir, { withFileTypes: true }))
|
|
113963
114173
|
if (entry.isDirectory()) {
|
|
113964
114174
|
const match2 = entry.name.match(/^([\w-_]+)-(\d+\.\d+\.\d+)/);
|
|
113965
114175
|
if (match2)
|
|
@@ -113970,7 +114180,7 @@ var RubyCodeAwareVulnerabilityScanner = class {
|
|
|
113970
114180
|
if (!entry)
|
|
113971
114181
|
continue;
|
|
113972
114182
|
const libDir = join18(gemsDir, entry, "lib");
|
|
113973
|
-
if (
|
|
114183
|
+
if (existsSync17(libDir))
|
|
113974
114184
|
loadPathsToPackageNames.set(libDir, `${pkg.packageName}@${pkg.version}`);
|
|
113975
114185
|
else
|
|
113976
114186
|
failedToFindLoadPath.push(pkg);
|
|
@@ -113980,7 +114190,7 @@ var RubyCodeAwareVulnerabilityScanner = class {
|
|
|
113980
114190
|
} else
|
|
113981
114191
|
for (const pkg of packagesToAnalyze) {
|
|
113982
114192
|
const libPath = join18(this.vendorDir, `${pkg.packageName}-${pkg.version}`, "lib");
|
|
113983
|
-
if (
|
|
114193
|
+
if (existsSync17(libPath))
|
|
113984
114194
|
loadPathsToPackageNames.set(libPath, `${pkg.packageName}@${pkg.version}`);
|
|
113985
114195
|
else
|
|
113986
114196
|
failedToFindLoadPath.push(pkg);
|
|
@@ -113990,7 +114200,7 @@ var RubyCodeAwareVulnerabilityScanner = class {
|
|
|
113990
114200
|
};
|
|
113991
114201
|
async function downloadAndExtractGem(gemName, version3, vendorDir) {
|
|
113992
114202
|
const gemDir = join18(vendorDir, `${gemName}-${version3}`);
|
|
113993
|
-
if (
|
|
114203
|
+
if (existsSync17(gemDir)) {
|
|
113994
114204
|
logger.debug(`Gem ${gemName}@${version3} already extracted`);
|
|
113995
114205
|
return;
|
|
113996
114206
|
}
|
|
@@ -114043,9 +114253,16 @@ var RubyGemsAnalyzer = class {
|
|
|
114043
114253
|
this.scanner = new RubyCodeAwareVulnerabilityScanner(state, projectDir);
|
|
114044
114254
|
}
|
|
114045
114255
|
prepareScanner = once5(async () => {
|
|
114046
|
-
await this.scanner.prepareDependencies(this.preInstalledDepInfos, this.state.vulnerabilities.filter((v) => Array.isArray(v.vulnerabilityAccessPaths)), RubyHeuristics.ONLY_VULN_PATH_PACKAGES);
|
|
114256
|
+
await this.scanner.prepareDependencies(this.preInstalledDepInfos, this.state.vulnerabilities.filter((v) => Array.isArray(v.vulnerabilityAccessPaths)), RubyHeuristics.ONLY_VULN_PATH_PACKAGES, this.state.preinstallDir);
|
|
114047
114257
|
return this.scanner;
|
|
114048
114258
|
});
|
|
114259
|
+
async installDependencies(preinstallDir) {
|
|
114260
|
+
if (existsSync18(resolve21(this.projectDir, "vendor")))
|
|
114261
|
+
return [];
|
|
114262
|
+
const scanner = new RubyCodeAwareVulnerabilityScanner(this.state, this.projectDir);
|
|
114263
|
+
await scanner.prepareDependencies(this.preInstalledDepInfos, this.state.vulnerabilities.filter((v) => Array.isArray(v.vulnerabilityAccessPaths)), RubyHeuristics.ONLY_VULN_PATH_PACKAGES, preinstallDir);
|
|
114264
|
+
return scanner.getPackagesExcludedUnrelatedToHeuristic();
|
|
114265
|
+
}
|
|
114049
114266
|
async runPhantomDependencyAnalysis() {
|
|
114050
114267
|
return void 0;
|
|
114051
114268
|
}
|
|
@@ -114057,9 +114274,11 @@ var RubyGemsAnalyzer = class {
|
|
|
114057
114274
|
}
|
|
114058
114275
|
analysisMetadataCollector?.(metadata);
|
|
114059
114276
|
};
|
|
114060
|
-
this.preinstalledDependencies =
|
|
114277
|
+
this.preinstalledDependencies = existsSync18(resolve21(this.projectDir, "vendor")) ? "YES" : "NO";
|
|
114061
114278
|
try {
|
|
114062
|
-
|
|
114279
|
+
const scanner = await this.prepareScanner();
|
|
114280
|
+
checkForInstallErrors(scanner.getPackagesExcludedUnrelatedToHeuristic(), this.state.otherAnalysisOptions);
|
|
114281
|
+
return await analyzeWithHeuristics(this.state, vulns, [RubyHeuristics.ONLY_VULN_PATH_PACKAGES], false, scanner, wrappedCollector, statusUpdater);
|
|
114063
114282
|
} finally {
|
|
114064
114283
|
await this.scanner.cleanup();
|
|
114065
114284
|
}
|
|
@@ -114117,9 +114336,16 @@ var RustAnalyzer = class {
|
|
|
114117
114336
|
constructor(state) {
|
|
114118
114337
|
this.state = state;
|
|
114119
114338
|
}
|
|
114339
|
+
async createScanner(tmpDir, statusUpdater) {
|
|
114340
|
+
return this.state.workspaceData.type === "coana" ? RustCodeAwareVulnerabilityScanner.initFromDependencyTree(this.state.workspaceData.data.dependencyTree, statusUpdater) : RustCodeAwareVulnerabilityScanner.initFromSocketArtifacts(this.state.subprojectDir, this.state.workspacePath, this.state.workspaceData.data.artifacts, tmpDir, statusUpdater);
|
|
114341
|
+
}
|
|
114342
|
+
async installDependencies(preinstallDir) {
|
|
114343
|
+
const scanner = await this.createScanner(preinstallDir);
|
|
114344
|
+
return scanner.getPackagesExcludedUnrelatedToHeuristic();
|
|
114345
|
+
}
|
|
114120
114346
|
async runPhantomDependencyAnalysis() {
|
|
114121
114347
|
return withTmpDirectory("cargo-phantom-dependency-analysis", async (tmpDir) => {
|
|
114122
|
-
const scanner =
|
|
114348
|
+
const scanner = await this.createScanner(tmpDir);
|
|
114123
114349
|
return scanner.runPhantomDependencyAnalysis(this.state.reachabilityAnalysisOptions.timeoutSeconds.allVulnRuns);
|
|
114124
114350
|
});
|
|
114125
114351
|
}
|
|
@@ -114131,11 +114357,17 @@ var RustAnalyzer = class {
|
|
|
114131
114357
|
}
|
|
114132
114358
|
analysisMetadataCollector?.(metadata);
|
|
114133
114359
|
};
|
|
114134
|
-
|
|
114135
|
-
|
|
114360
|
+
const preinstallDir = this.state.preinstallDir;
|
|
114361
|
+
const runWithTmpDir = async (tmpDir) => {
|
|
114362
|
+
const scanner = await this.createScanner(tmpDir, statusUpdater);
|
|
114363
|
+
checkForInstallErrors(scanner.getPackagesExcludedUnrelatedToHeuristic(), this.state.otherAnalysisOptions);
|
|
114136
114364
|
const heuristicsInOrder = [RusticaHeuristics.ALL_PACKAGES];
|
|
114137
114365
|
return await analyzeWithHeuristics(this.state, vulns, heuristicsInOrder, false, scanner, wrappedCollector, statusUpdater);
|
|
114138
|
-
}
|
|
114366
|
+
};
|
|
114367
|
+
if (preinstallDir) {
|
|
114368
|
+
return runWithTmpDir(preinstallDir);
|
|
114369
|
+
}
|
|
114370
|
+
return withTmpDirectory("cargo-reachability-analysis", runWithTmpDir);
|
|
114139
114371
|
}
|
|
114140
114372
|
async getWorkspaceDiagnostics() {
|
|
114141
114373
|
let sourceFilesDetected;
|
|
@@ -114174,6 +114406,17 @@ var ecosystemAnalyzer = {
|
|
|
114174
114406
|
};
|
|
114175
114407
|
var apiKey2 = COANA_API_KEY ? { type: "present", value: COANA_API_KEY } : { type: "missing" };
|
|
114176
114408
|
var dashboardAPI3 = new DashboardAPI(process.env.SOCKET_MODE === "true", process.env.DISABLE_ANALYTICS_SHARING === "true");
|
|
114409
|
+
async function installDependenciesForAnalysis(state, preinstallDir) {
|
|
114410
|
+
const projectDir = resolve22(state.subprojectDir, state.workspacePath);
|
|
114411
|
+
const ecosystem = state.workspaceData.data.type;
|
|
114412
|
+
logger.info(`Pre-installing dependencies for project at "${relative10(state.rootWorkingDir, projectDir) || "."}" (${ecosystem})`);
|
|
114413
|
+
const constructor = ecosystemAnalyzer[ecosystem];
|
|
114414
|
+
if (!constructor)
|
|
114415
|
+
throw Error(`No analyzer associated with ecosystem ${ecosystem}`);
|
|
114416
|
+
const analyzer = new constructor(state, projectDir);
|
|
114417
|
+
const failedPackages = await analyzer.installDependencies(preinstallDir);
|
|
114418
|
+
return { failedPackages };
|
|
114419
|
+
}
|
|
114177
114420
|
async function runReachabilityAnalysis(state) {
|
|
114178
114421
|
const projectDir = resolve22(state.subprojectDir, state.workspacePath);
|
|
114179
114422
|
const ecosystem = state.workspaceData.data.type;
|
|
@@ -114205,9 +114448,30 @@ async function getReachabilityAnalyzersStateFromInput(rootWorkingDir, subproject
|
|
|
114205
114448
|
}
|
|
114206
114449
|
|
|
114207
114450
|
// dist/reachability-analyzers-cli.js
|
|
114208
|
-
var runReachabilityAnalysisCmd = new Command().name("runReachabilityAnalysis").argument("<rootWorkingDir>", "Directory where Coana is run").argument("<subprojectDir>", "Project root of directory being analyzed").argument("<workspacePath>", "Path to directory to analyze relative to subprojectDir").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("--coana-socket-path <socketPath>", "Coana socket path").option("--silent-spinner", "Silence spinner", "CI" in process.env || !process.stdin.isTTY).requiredOption("-i, --input-file <inputFile>", "Input file for data and vulnerabilities").requiredOption("-o, --output-file <outputFile>", "Output file for the results").configureHelp({ sortSubcommands: true, sortOptions: true }).action(async (rootWorkingDir, subprojectDir, workspacePath, options) => withLoggerAndSpinner("Coana Reachability Analyzers", options, async () => {
|
|
114451
|
+
var runReachabilityAnalysisCmd = new Command().name("runReachabilityAnalysis").argument("<rootWorkingDir>", "Directory where Coana is run").argument("<subprojectDir>", "Project root of directory being analyzed").argument("<workspacePath>", "Path to directory to analyze relative to subprojectDir").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("--coana-socket-path <socketPath>", "Coana socket path").option("--silent-spinner", "Silence spinner", "CI" in process.env || !process.stdin.isTTY).option("--preinstall-dir <preinstallDir>", "Directory with pre-installed dependencies").requiredOption("-i, --input-file <inputFile>", "Input file for data and vulnerabilities").requiredOption("-o, --output-file <outputFile>", "Output file for the results").configureHelp({ sortSubcommands: true, sortOptions: true }).action(async (rootWorkingDir, subprojectDir, workspacePath, options) => withLoggerAndSpinner("Coana Reachability Analyzers", options, async () => {
|
|
114452
|
+
try {
|
|
114453
|
+
const state = await getReachabilityAnalyzersStateFromInput(rootWorkingDir, subprojectDir, workspacePath, options.inputFile);
|
|
114454
|
+
if (options.preinstallDir) {
|
|
114455
|
+
state.preinstallDir = options.preinstallDir;
|
|
114456
|
+
}
|
|
114457
|
+
const result = await runReachabilityAnalysis(state);
|
|
114458
|
+
if (options.outputFile) {
|
|
114459
|
+
logger.debug("Writing result to file", options.outputFile);
|
|
114460
|
+
await writeFile10(options.outputFile, JSON.stringify({ result }));
|
|
114461
|
+
} else {
|
|
114462
|
+
logger.info("Result:", JSON.stringify(result, null, 2));
|
|
114463
|
+
}
|
|
114464
|
+
} catch (e) {
|
|
114465
|
+
if (e instanceof InstallError && options.outputFile) {
|
|
114466
|
+
await writeFile10(options.outputFile, JSON.stringify({ error: { type: "InstallError", failedPackages: e.failedPackages } }));
|
|
114467
|
+
return;
|
|
114468
|
+
}
|
|
114469
|
+
throw e;
|
|
114470
|
+
}
|
|
114471
|
+
}, "reachability-analyzer"));
|
|
114472
|
+
var installDependenciesCmd = new Command().name("installDependencies").argument("<rootWorkingDir>", "Directory where Coana is run").argument("<subprojectDir>", "Project root of directory being analyzed").argument("<workspacePath>", "Path to directory to analyze relative to subprojectDir").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("--coana-socket-path <socketPath>", "Coana socket path").option("--silent-spinner", "Silence spinner", "CI" in process.env || !process.stdin.isTTY).requiredOption("-i, --input-file <inputFile>", "Input file for data and vulnerabilities").requiredOption("-o, --output-file <outputFile>", "Output file for the results").requiredOption("--preinstall-dir <preinstallDir>", "Directory to install dependencies into").configureHelp({ sortSubcommands: true, sortOptions: true }).action(async (rootWorkingDir, subprojectDir, workspacePath, options) => withLoggerAndSpinner("Coana Reachability Analyzers - Install Dependencies", options, async () => {
|
|
114209
114473
|
const state = await getReachabilityAnalyzersStateFromInput(rootWorkingDir, subprojectDir, workspacePath, options.inputFile);
|
|
114210
|
-
const result = await
|
|
114474
|
+
const result = await installDependenciesForAnalysis(state, options.preinstallDir);
|
|
114211
114475
|
if (options.outputFile) {
|
|
114212
114476
|
logger.debug("Writing result to file", options.outputFile);
|
|
114213
114477
|
await writeFile10(options.outputFile, JSON.stringify({ result }));
|
|
@@ -114263,7 +114527,7 @@ var runOnPackageRegistryPackageCmd = new Command().name("runOnPackageRegistryPac
|
|
|
114263
114527
|
}
|
|
114264
114528
|
}, "reachability-analyzer");
|
|
114265
114529
|
});
|
|
114266
|
-
new Command().addCommand(runReachabilityAnalysisCmd, { isDefault: true }).addCommand(runOnDependencyChainCmd).addCommand(runOnPackageRegistryPackageCmd).parseAsync();
|
|
114530
|
+
new Command().addCommand(runReachabilityAnalysisCmd, { isDefault: true }).addCommand(installDependenciesCmd).addCommand(runOnDependencyChainCmd).addCommand(runOnPackageRegistryPackageCmd).parseAsync();
|
|
114267
114531
|
/*! Bundled license information:
|
|
114268
114532
|
|
|
114269
114533
|
safe-buffer/index.js:
|