@coana-tech/cli 14.11.7 → 14.11.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.mjs +46 -19
- package/coana-repos/mambalade/dist/mambalade-0.3.11-py3-none-any.whl +0 -0
- package/coana-repos/mambalade/dist/networkx-3.5-py3-none-any.whl +0 -0
- package/coana-repos/mambalade/dist/typing_extensions-4.14.1-py3-none-any.whl +0 -0
- package/package.json +1 -1
- package/reachability-analyzers-cli.mjs +55 -18
package/cli.mjs
CHANGED
|
@@ -209443,7 +209443,7 @@ function shouldIgnoreDir(dir) {
|
|
|
209443
209443
|
return dirsToIgnore.includes(dir);
|
|
209444
209444
|
}
|
|
209445
209445
|
function shouldIgnoreDueToExcludeDirsOrChangedFiles({ mainProjectDir, excludeDirs, changedFiles }, fullPath) {
|
|
209446
|
-
const relativeToProjectDir = relative9(mainProjectDir, fullPath);
|
|
209446
|
+
const relativeToProjectDir = relative9(mainProjectDir, fullPath) || ".";
|
|
209447
209447
|
return !!(isMatch3(relativeToProjectDir, excludeDirs) || changedFiles && !changedFiles.some((changedFile) => changedFile.startsWith(relativeToProjectDir)));
|
|
209448
209448
|
}
|
|
209449
209449
|
|
|
@@ -210096,7 +210096,7 @@ function inferWorkspaceFromManifestPath(ecosystem, manifestPath, properPythonPro
|
|
|
210096
210096
|
return dirname8(manifestPath) || ".";
|
|
210097
210097
|
}
|
|
210098
210098
|
default: {
|
|
210099
|
-
return
|
|
210099
|
+
return ".";
|
|
210100
210100
|
}
|
|
210101
210101
|
}
|
|
210102
210102
|
}
|
|
@@ -210384,6 +210384,8 @@ function toSocketReachabilitySchema(vulnerability) {
|
|
|
210384
210384
|
return { type: "error", error: vulnerability.codeAwareScanResult.message };
|
|
210385
210385
|
}
|
|
210386
210386
|
if (vulnerability.codeAwareScanResult.type === "otherError") {
|
|
210387
|
+
if (vulnerability.codeAwareScanResult.message.includes("Reachability analysis for languages using"))
|
|
210388
|
+
return { type: "unknown" };
|
|
210387
210389
|
return { type: "error", error: vulnerability.codeAwareScanResult.message };
|
|
210388
210390
|
}
|
|
210389
210391
|
if (vulnerability.codeAwareScanResult.type === "success") {
|
|
@@ -225338,7 +225340,7 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
|
|
|
225338
225340
|
}
|
|
225339
225341
|
|
|
225340
225342
|
// dist/version.js
|
|
225341
|
-
var version2 = "14.11.
|
|
225343
|
+
var version2 = "14.11.9";
|
|
225342
225344
|
|
|
225343
225345
|
// dist/cli-core.js
|
|
225344
225346
|
var { mapValues, omit, partition, pick } = import_lodash15.default;
|
|
@@ -225423,9 +225425,18 @@ var CliCore = class {
|
|
|
225423
225425
|
if (this.options.ecosystems)
|
|
225424
225426
|
this.options.ecosystems.forEach((ecosystem) => {
|
|
225425
225427
|
if (!ECOSYSTEMS_WITH_TRADITIONAL_SCA_SUPPORT.includes(ecosystem)) {
|
|
225426
|
-
throw new Error(`Invalid ecosystem: ${ecosystem}
|
|
225428
|
+
throw new Error(`Invalid ecosystem: ${ecosystem}. Supported ecosystems are: ${ECOSYSTEMS_WITH_TRADITIONAL_SCA_SUPPORT.join(", ")}`);
|
|
225427
225429
|
}
|
|
225428
225430
|
});
|
|
225431
|
+
if (this.options.purlTypes) {
|
|
225432
|
+
this.options.purlTypes.forEach((purlType) => {
|
|
225433
|
+
try {
|
|
225434
|
+
getAdvisoryEcosystemFromPurlType(purlType);
|
|
225435
|
+
} catch (e) {
|
|
225436
|
+
throw new Error(`Invalid purl type: ${purlType}. Supported purl types are: ${ECOSYSTEMS_WITH_TRADITIONAL_SCA_SUPPORT.map((ecosystem) => getPurlType(ecosystem)).join(", ")}`);
|
|
225437
|
+
}
|
|
225438
|
+
});
|
|
225439
|
+
}
|
|
225429
225440
|
if (this.options.manifestsTarHash && !this.options.socketMode) {
|
|
225430
225441
|
throw new Error("The --manifests-tar-hash option is only supported when using --socket-mode");
|
|
225431
225442
|
}
|
|
@@ -225494,6 +225505,10 @@ var CliCore = class {
|
|
|
225494
225505
|
const vulnsWithResults = [];
|
|
225495
225506
|
for (const [ecosystem, workspaceToAnalysisData] of Object.entries(ecosystemToWorkspaceToAnalysisData)) {
|
|
225496
225507
|
this.sendProgress("RUN_ON_SUBPROJECT", true, this.rootWorkingDirectory);
|
|
225508
|
+
const isEcosystemToAnalyze = !this.options.purlTypes || this.options.purlTypes.some((purlType) => getAdvisoryEcosystemFromPurlType(purlType) === ecosystem);
|
|
225509
|
+
if (!isEcosystemToAnalyze) {
|
|
225510
|
+
logger.info(`Skipping reachability analysis for ecosystem ${getPurlType(ecosystem)} due to it not being included in the list of ecosystems to analyze.`);
|
|
225511
|
+
}
|
|
225497
225512
|
vulnsWithResults.push(...Object.values(await this.runReachabilityAnalysisForWorkspaces(
|
|
225498
225513
|
workspaceToAnalysisData,
|
|
225499
225514
|
ecosystemToWorkspaceToVulnerabilities[ecosystem] ?? {},
|
|
@@ -225502,7 +225517,7 @@ var CliCore = class {
|
|
|
225502
225517
|
otherModulesCommunicator,
|
|
225503
225518
|
this.rootWorkingDirectory,
|
|
225504
225519
|
ecosystem,
|
|
225505
|
-
|
|
225520
|
+
["NPM", "PIP"].includes(ecosystem) && isEcosystemToAnalyze
|
|
225506
225521
|
)).flat());
|
|
225507
225522
|
this.sendProgress("RUN_ON_SUBPROJECT", false, this.rootWorkingDirectory);
|
|
225508
225523
|
}
|
|
@@ -225760,10 +225775,10 @@ Subproject: ${subproject}`);
|
|
|
225760
225775
|
}
|
|
225761
225776
|
async runReachabilityAnalysisForWorkspaces(workspacePathToDataForAnalysis, workspaceToVulnerabilities, workspaceToDirectDependencies, otherModulesCommunicator, subprojectPath, ecosystem, reachabilitySupported) {
|
|
225762
225777
|
const workspaceToAugmentedVulnerabilities = Object.fromEntries(await asyncMap(Object.keys(workspacePathToDataForAnalysis), async (workspacePath) => {
|
|
225778
|
+
const vulnerabilities = workspaceToVulnerabilities[workspacePath];
|
|
225763
225779
|
try {
|
|
225764
225780
|
const dataForAnalysis = workspacePathToDataForAnalysis[workspacePath];
|
|
225765
|
-
const
|
|
225766
|
-
const augmentedVulnerabilities = reachabilitySupported ? await this.runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilities) : vulnerabilities.map((v) => ({
|
|
225781
|
+
const augmentedVulnerabilities = reachabilitySupported && !this.shouldExcludeAnalyzingWorkspace(subprojectPath, workspacePath) ? await this.runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, dataForAnalysis, ecosystem, vulnerabilities) : vulnerabilities.map((v) => ({
|
|
225767
225782
|
...v,
|
|
225768
225783
|
results: {
|
|
225769
225784
|
type: "otherError",
|
|
@@ -225773,17 +225788,16 @@ Subproject: ${subproject}`);
|
|
|
225773
225788
|
return [workspacePath, augmentedVulnerabilities];
|
|
225774
225789
|
} catch (e) {
|
|
225775
225790
|
logger.error(`Reachability analysis failed for workspace ${workspacePath} in subproject ${subprojectPath}: ${e.message}`);
|
|
225776
|
-
|
|
225777
|
-
|
|
225778
|
-
|
|
225779
|
-
|
|
225780
|
-
|
|
225781
|
-
|
|
225782
|
-
|
|
225783
|
-
|
|
225784
|
-
|
|
225785
|
-
|
|
225786
|
-
throw e;
|
|
225791
|
+
return [
|
|
225792
|
+
workspacePath,
|
|
225793
|
+
vulnerabilities.map((v) => ({
|
|
225794
|
+
...v,
|
|
225795
|
+
results: {
|
|
225796
|
+
type: "otherError",
|
|
225797
|
+
message: e.message || "Unknown error"
|
|
225798
|
+
}
|
|
225799
|
+
}))
|
|
225800
|
+
];
|
|
225787
225801
|
}
|
|
225788
225802
|
}));
|
|
225789
225803
|
const successfulWorkspaceToAugmentedVulnerabilities = Object.fromEntries(Object.entries(workspaceToAugmentedVulnerabilities).filter(([_, vulns]) => vulns !== void 0));
|
|
@@ -225838,6 +225852,18 @@ Subproject: ${subproject}`);
|
|
|
225838
225852
|
}
|
|
225839
225853
|
}
|
|
225840
225854
|
}
|
|
225855
|
+
shouldExcludeAnalyzingWorkspace(subprojectPath, workspacePath) {
|
|
225856
|
+
const shouldExcludeWorkspaceForAnalysis = shouldIgnoreDueToExcludeDirsOrChangedFiles({
|
|
225857
|
+
mainProjectDir: this.rootWorkingDirectory,
|
|
225858
|
+
excludeDirs: this.options.excludeDirs ?? [],
|
|
225859
|
+
changedFiles: this.options.changedFiles,
|
|
225860
|
+
includeDirs: this.options.includeDirs ?? []
|
|
225861
|
+
}, resolve25(subprojectPath, workspacePath));
|
|
225862
|
+
if (shouldExcludeWorkspaceForAnalysis) {
|
|
225863
|
+
logger.info(`Skipping reachability analysis for workspace ${workspacePath} due to it being excluded.`);
|
|
225864
|
+
}
|
|
225865
|
+
return shouldExcludeWorkspaceForAnalysis;
|
|
225866
|
+
}
|
|
225841
225867
|
async runReachabilityAnalysis(otherModulesCommunicator, subprojectPath, workspacePath, workspaceData, ecosystem, vulnerabilities) {
|
|
225842
225868
|
const [vulnsWithActualAPIPatterns, result] = partition(vulnerabilities, (v) => Array.isArray(v.vulnerabilityAccessPaths));
|
|
225843
225869
|
for (const v of result)
|
|
@@ -226255,9 +226281,10 @@ function computeSBOMTaskArtifacts(dependencyTrees) {
|
|
|
226255
226281
|
// dist/index.js
|
|
226256
226282
|
var program2 = new Command();
|
|
226257
226283
|
var run2 = new Command();
|
|
226258
|
-
run2.name("run").argument("<path>", "File system path to folder containing the project").option("-o, --output-dir <path>", "Write json report to <path>/coana-report.json").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("-p, --print-report", "Print the report to the console", false).option("--offline-database <path>", "Path to a coana-offline-db.json file for running the CLI without internet connectivity", void 0).option("-t, --timeout <timeout>", "Set API <timeout> in milliseconds to Coana backend.", "300000").option("-a, --analysis-timeout <timeout>", "Set <timeout> in seconds for each reachability analysis run").option("--memory-limit <memoryInMB>", "Set memory limit for analysis to <memoryInMB> megabytes of memory.", "8192").option("-c, --concurrency <concurrency>", "Set the maximum number of concurrent reachability analysis runs. It's recommended to choose a concurrency level that ensures that each analysis run has at least the --memory-limit amount of memory available.", "1").option("--api-key <key>", "Set the Coana dashboard API key. By setting you also enable the dashboard integration.").addOption(new Option("--write-report-to-file", "Write the report dashboard-compatible report to dashboard-report.json. This report may help the Coana team debug issues with the report insertion mechanism.").default(false).hideHelp()).option("--project-name <repoName>", "Set the name of the repository. Used for dashboard integration.").option("--repo-url <repoUrl>", "Set the URL of the repository. Used for dashboard integration.").option("--include-dirs <relativeDirs...>", "globs for directories to include from the detection of subprojects (space-separated)(use relative paths from the project root). Notice, projects that are not included may still be scanned if they are referenced from included projects.").option("--exclude-dirs <relativeDirs...>", "globs for directories to exclude from the detection of subprojects (space-separated)(use relative paths from the project root). Notice, excluded projects may still be scanned if they are referenced from non-excluded projects.").option("--disable-analysis-splitting", "Limits Coana to at most 1 reachability analysis run per workspace").option("--print-analysis-log-file", "Store log output from the JavaScript/TypeScript reachability analysis in the file js-analysis.log file in the root of each workspace", false).option("--entry-points <entryPoints...>", "List of files to analyze for root workspace. The reachability analysis automatically analyzes all files used by the entry points. If not provided, all JavaScript and TypeScript files are considered entry points. For non-root workspaces, all JavaScript and TypeScript files are analyzed as well.").option("--include-projects-with-no-reachability-support", "Also runs Coana on projects where we support traditional SCA, but does not yet support reachability analysis.", false).option("--ecosystems <ecosystems...>", "List of ecosystems to analyze (space-separated). Currently NPM, PIP, MAVEN, NUGET and GO are supported. Default is all supported ecosystems.").option("--changed-files <files...>", "List of files that have changed. If provided, Coana only analyzes workspaces and modules that contain changed files.").option("--disable-report-submission", "Disable the submission of the report to the Coana dashboard. Used by the pipeline blocking feature.", false).option("--disable-analytics-sharing", "Disable analytics sharing.", false).option("--provider-project <path>", "File system path to folder containing the provider project (Only supported for Maven, Gradle, and SBT)").option("--provider-workspaces <dirs...>", "List of workspaces that build the provided runtime environment (Only supported for Maven, Gradle, and SBT)", (paths) => paths.split(" ")).option("--lightweight-reachability", "Runs Coana in lightweight mode. This increases analysis speed but also raises the risk of Coana misclassifying the reachability of certain complex vulnerabilities. Recommended only for use with Coana Guardrail mode.", false).addOption(new Option("--run-without-docker", "Run package managers and reachability analyzers without using docker").default(process.env.RUN_WITHOUT_DOCKER === "true").hideHelp()).addOption(new Option("--run-env <env>", "Specifies the environment in which the CLI is run. So far only MANAGED_SCAN and UNKNOWN are supported.").default("UNKNOWN").choices(["UNKNOWN", "MANAGED_SCAN"]).hideHelp()).addOption(new Option("--guardrail-mode", "Run Coana in guardrail mode. This mode is used to prevent new reachable vulnerabilities from being introduced into the codebase. Usually run as a CI check when pushing new commits to a pull request.")).option("--ignore-failing-workspaces", "Continue processing when a workspace fails instead of exiting. Failed workspaces will be logged at termination.", false).addOption(new Option("--socket-mode <output-file>", "Run Coana in socket mode and write report to <output-file>").hideHelp()).addOption(new Option("--manifests-tar-hash <hash>", "Hash of the tarball containing all manifest files already uploaded to Socket. If provided, Socket will be used for computing dependency trees.").hideHelp()).version(version2).configureHelp({ sortOptions: true }).action(async (path2, options) => {
|
|
226284
|
+
run2.name("run").argument("<path>", "File system path to folder containing the project").option("-o, --output-dir <path>", "Write json report to <path>/coana-report.json").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("-p, --print-report", "Print the report to the console", false).option("--offline-database <path>", "Path to a coana-offline-db.json file for running the CLI without internet connectivity", void 0).option("-t, --timeout <timeout>", "Set API <timeout> in milliseconds to Coana backend.", "300000").option("-a, --analysis-timeout <timeout>", "Set <timeout> in seconds for each reachability analysis run").option("--memory-limit <memoryInMB>", "Set memory limit for analysis to <memoryInMB> megabytes of memory.", "8192").option("-c, --concurrency <concurrency>", "Set the maximum number of concurrent reachability analysis runs. It's recommended to choose a concurrency level that ensures that each analysis run has at least the --memory-limit amount of memory available.", "1").option("--api-key <key>", "Set the Coana dashboard API key. By setting you also enable the dashboard integration.").addOption(new Option("--write-report-to-file", "Write the report dashboard-compatible report to dashboard-report.json. This report may help the Coana team debug issues with the report insertion mechanism.").default(false).hideHelp()).option("--project-name <repoName>", "Set the name of the repository. Used for dashboard integration.").option("--repo-url <repoUrl>", "Set the URL of the repository. Used for dashboard integration.").option("--include-dirs <relativeDirs...>", "globs for directories to include from the detection of subprojects (space-separated)(use relative paths from the project root). Notice, projects that are not included may still be scanned if they are referenced from included projects.").option("--exclude-dirs <relativeDirs...>", "globs for directories to exclude from the detection of subprojects (space-separated)(use relative paths from the project root). Notice, excluded projects may still be scanned if they are referenced from non-excluded projects.").option("--disable-analysis-splitting", "Limits Coana to at most 1 reachability analysis run per workspace").option("--print-analysis-log-file", "Store log output from the JavaScript/TypeScript reachability analysis in the file js-analysis.log file in the root of each workspace", false).option("--entry-points <entryPoints...>", "List of files to analyze for root workspace. The reachability analysis automatically analyzes all files used by the entry points. If not provided, all JavaScript and TypeScript files are considered entry points. For non-root workspaces, all JavaScript and TypeScript files are analyzed as well.").option("--include-projects-with-no-reachability-support", "Also runs Coana on projects where we support traditional SCA, but does not yet support reachability analysis.", false).option("--ecosystems <ecosystems...>", "List of ecosystems to analyze (space-separated). Currently NPM, PIP, MAVEN, NUGET and GO are supported. Default is all supported ecosystems.").addOption(new Option("--purl-types <purlTypes...>", "List of PURL types to analyze (space-separated). Currently npm, pypi, maven, nuget, golang and cargo are supported. Default is all supported purl types.").hideHelp()).option("--changed-files <files...>", "List of files that have changed. If provided, Coana only analyzes workspaces and modules that contain changed files.").option("--disable-report-submission", "Disable the submission of the report to the Coana dashboard. Used by the pipeline blocking feature.", false).option("--disable-analytics-sharing", "Disable analytics sharing.", false).option("--provider-project <path>", "File system path to folder containing the provider project (Only supported for Maven, Gradle, and SBT)").option("--provider-workspaces <dirs...>", "List of workspaces that build the provided runtime environment (Only supported for Maven, Gradle, and SBT)", (paths) => paths.split(" ")).option("--lightweight-reachability", "Runs Coana in lightweight mode. This increases analysis speed but also raises the risk of Coana misclassifying the reachability of certain complex vulnerabilities. Recommended only for use with Coana Guardrail mode.", false).addOption(new Option("--run-without-docker", "Run package managers and reachability analyzers without using docker").default(process.env.RUN_WITHOUT_DOCKER === "true").hideHelp()).addOption(new Option("--run-env <env>", "Specifies the environment in which the CLI is run. So far only MANAGED_SCAN and UNKNOWN are supported.").default("UNKNOWN").choices(["UNKNOWN", "MANAGED_SCAN"]).hideHelp()).addOption(new Option("--guardrail-mode", "Run Coana in guardrail mode. This mode is used to prevent new reachable vulnerabilities from being introduced into the codebase. Usually run as a CI check when pushing new commits to a pull request.")).option("--ignore-failing-workspaces", "Continue processing when a workspace fails instead of exiting. Failed workspaces will be logged at termination.", false).addOption(new Option("--socket-mode <output-file>", "Run Coana in socket mode and write report to <output-file>").hideHelp()).addOption(new Option("--manifests-tar-hash <hash>", "Hash of the tarball containing all manifest files already uploaded to Socket. If provided, Socket will be used for computing dependency trees.").hideHelp()).version(version2).configureHelp({ sortOptions: true }).action(async (path2, options) => {
|
|
226259
226285
|
process.env.DOCKER_IMAGE_TAG ??= version2;
|
|
226260
226286
|
options.ecosystems = options.ecosystems?.map((e) => e.toUpperCase());
|
|
226287
|
+
options.purlTypes = options.purlTypes?.map((e) => e.toLowerCase());
|
|
226261
226288
|
await new CliCore(path2, options).main();
|
|
226262
226289
|
});
|
|
226263
226290
|
var applyFixes = new Command();
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -64950,7 +64950,7 @@ var require_comparator = __commonJS({
|
|
|
64950
64950
|
var require_satisfies = __commonJS({
|
|
64951
64951
|
"../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/functions/satisfies.js"(exports, module) {
|
|
64952
64952
|
var Range = require_range2();
|
|
64953
|
-
var
|
|
64953
|
+
var satisfies3 = (version3, range, options) => {
|
|
64954
64954
|
try {
|
|
64955
64955
|
range = new Range(range, options);
|
|
64956
64956
|
} catch (er) {
|
|
@@ -64958,7 +64958,7 @@ var require_satisfies = __commonJS({
|
|
|
64958
64958
|
}
|
|
64959
64959
|
return range.test(version3);
|
|
64960
64960
|
};
|
|
64961
|
-
module.exports =
|
|
64961
|
+
module.exports = satisfies3;
|
|
64962
64962
|
}
|
|
64963
64963
|
});
|
|
64964
64964
|
|
|
@@ -65107,7 +65107,7 @@ var require_outside = __commonJS({
|
|
|
65107
65107
|
var Comparator = require_comparator();
|
|
65108
65108
|
var { ANY } = Comparator;
|
|
65109
65109
|
var Range = require_range2();
|
|
65110
|
-
var
|
|
65110
|
+
var satisfies3 = require_satisfies();
|
|
65111
65111
|
var gt = require_gt();
|
|
65112
65112
|
var lt2 = require_lt();
|
|
65113
65113
|
var lte = require_lte();
|
|
@@ -65134,7 +65134,7 @@ var require_outside = __commonJS({
|
|
|
65134
65134
|
default:
|
|
65135
65135
|
throw new TypeError('Must provide a hilo val of "<" or ">"');
|
|
65136
65136
|
}
|
|
65137
|
-
if (
|
|
65137
|
+
if (satisfies3(version3, range, options)) {
|
|
65138
65138
|
return false;
|
|
65139
65139
|
}
|
|
65140
65140
|
for (let i2 = 0; i2 < range.set.length; ++i2) {
|
|
@@ -65202,7 +65202,7 @@ var require_intersects = __commonJS({
|
|
|
65202
65202
|
// ../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/ranges/simplify.js
|
|
65203
65203
|
var require_simplify = __commonJS({
|
|
65204
65204
|
"../../node_modules/.pnpm/semver@7.7.1/node_modules/semver/ranges/simplify.js"(exports, module) {
|
|
65205
|
-
var
|
|
65205
|
+
var satisfies3 = require_satisfies();
|
|
65206
65206
|
var compare = require_compare();
|
|
65207
65207
|
module.exports = (versions, range, options) => {
|
|
65208
65208
|
const set = [];
|
|
@@ -65210,7 +65210,7 @@ var require_simplify = __commonJS({
|
|
|
65210
65210
|
let prev2 = null;
|
|
65211
65211
|
const v = versions.sort((a2, b) => compare(a2, b, options));
|
|
65212
65212
|
for (const version3 of v) {
|
|
65213
|
-
const included =
|
|
65213
|
+
const included = satisfies3(version3, range, options);
|
|
65214
65214
|
if (included) {
|
|
65215
65215
|
prev2 = version3;
|
|
65216
65216
|
if (!first2) {
|
|
@@ -65254,7 +65254,7 @@ var require_subset = __commonJS({
|
|
|
65254
65254
|
var Range = require_range2();
|
|
65255
65255
|
var Comparator = require_comparator();
|
|
65256
65256
|
var { ANY } = Comparator;
|
|
65257
|
-
var
|
|
65257
|
+
var satisfies3 = require_satisfies();
|
|
65258
65258
|
var compare = require_compare();
|
|
65259
65259
|
var subset = (sub, dom, options = {}) => {
|
|
65260
65260
|
if (sub === dom) {
|
|
@@ -65323,14 +65323,14 @@ var require_subset = __commonJS({
|
|
|
65323
65323
|
}
|
|
65324
65324
|
}
|
|
65325
65325
|
for (const eq2 of eqSet) {
|
|
65326
|
-
if (gt && !
|
|
65326
|
+
if (gt && !satisfies3(eq2, String(gt), options)) {
|
|
65327
65327
|
return null;
|
|
65328
65328
|
}
|
|
65329
|
-
if (lt2 && !
|
|
65329
|
+
if (lt2 && !satisfies3(eq2, String(lt2), options)) {
|
|
65330
65330
|
return null;
|
|
65331
65331
|
}
|
|
65332
65332
|
for (const c of dom) {
|
|
65333
|
-
if (!
|
|
65333
|
+
if (!satisfies3(eq2, String(c), options)) {
|
|
65334
65334
|
return false;
|
|
65335
65335
|
}
|
|
65336
65336
|
}
|
|
@@ -65357,7 +65357,7 @@ var require_subset = __commonJS({
|
|
|
65357
65357
|
if (higher === c && higher !== gt) {
|
|
65358
65358
|
return false;
|
|
65359
65359
|
}
|
|
65360
|
-
} else if (gt.operator === ">=" && !
|
|
65360
|
+
} else if (gt.operator === ">=" && !satisfies3(gt.semver, String(c), options)) {
|
|
65361
65361
|
return false;
|
|
65362
65362
|
}
|
|
65363
65363
|
}
|
|
@@ -65372,7 +65372,7 @@ var require_subset = __commonJS({
|
|
|
65372
65372
|
if (lower === c && lower !== lt2) {
|
|
65373
65373
|
return false;
|
|
65374
65374
|
}
|
|
65375
|
-
} else if (lt2.operator === "<=" && !
|
|
65375
|
+
} else if (lt2.operator === "<=" && !satisfies3(lt2.semver, String(c), options)) {
|
|
65376
65376
|
return false;
|
|
65377
65377
|
}
|
|
65378
65378
|
}
|
|
@@ -65441,7 +65441,7 @@ var require_semver2 = __commonJS({
|
|
|
65441
65441
|
var coerce = require_coerce();
|
|
65442
65442
|
var Comparator = require_comparator();
|
|
65443
65443
|
var Range = require_range2();
|
|
65444
|
-
var
|
|
65444
|
+
var satisfies3 = require_satisfies();
|
|
65445
65445
|
var toComparators = require_to_comparators();
|
|
65446
65446
|
var maxSatisfying = require_max_satisfying();
|
|
65447
65447
|
var minSatisfying = require_min_satisfying();
|
|
@@ -65479,7 +65479,7 @@ var require_semver2 = __commonJS({
|
|
|
65479
65479
|
coerce,
|
|
65480
65480
|
Comparator,
|
|
65481
65481
|
Range,
|
|
65482
|
-
satisfies:
|
|
65482
|
+
satisfies: satisfies3,
|
|
65483
65483
|
toComparators,
|
|
65484
65484
|
maxSatisfying,
|
|
65485
65485
|
minSatisfying,
|
|
@@ -73697,7 +73697,7 @@ ${error.message}`);
|
|
|
73697
73697
|
|
|
73698
73698
|
// dist/whole-program-code-aware-vulnerability-scanner/analyze-in-buckets.js
|
|
73699
73699
|
var import_lodash17 = __toESM(require_lodash(), 1);
|
|
73700
|
-
var
|
|
73700
|
+
var import_semver3 = __toESM(require_semver2(), 1);
|
|
73701
73701
|
import assert8 from "assert";
|
|
73702
73702
|
import { relative as relative5 } from "path";
|
|
73703
73703
|
|
|
@@ -96268,6 +96268,7 @@ async function getVersion(analysisName) {
|
|
|
96268
96268
|
}
|
|
96269
96269
|
|
|
96270
96270
|
// dist/whole-program-code-aware-vulnerability-scanner/python/python-code-aware-vulnerability-scanner.js
|
|
96271
|
+
var import_semver2 = __toESM(require_semver2(), 1);
|
|
96271
96272
|
var { omit, once: once3, pick, sortedUniq, uniqBy } = import_lodash14.default;
|
|
96272
96273
|
var PythonCodeAwareVulnerabilityScanner = class _PythonCodeAwareVulnerabilityScanner {
|
|
96273
96274
|
state;
|
|
@@ -96276,6 +96277,7 @@ var PythonCodeAwareVulnerabilityScanner = class _PythonCodeAwareVulnerabilitySca
|
|
|
96276
96277
|
numberAnalysesRun = 0;
|
|
96277
96278
|
virtualEnvInfo;
|
|
96278
96279
|
vm;
|
|
96280
|
+
mambaladeVenvPath;
|
|
96279
96281
|
constructor(state, projectDir, _statusUpdater) {
|
|
96280
96282
|
this.state = state;
|
|
96281
96283
|
this.projectDir = projectDir;
|
|
@@ -96293,6 +96295,9 @@ var PythonCodeAwareVulnerabilityScanner = class _PythonCodeAwareVulnerabilitySca
|
|
|
96293
96295
|
async runAnalysis(vulns, heuristic, analyzesAllVulns) {
|
|
96294
96296
|
if (!this.virtualEnvInfo)
|
|
96295
96297
|
throw new Error("Virtual environment not set up");
|
|
96298
|
+
if (!this.mambaladeVenvPath) {
|
|
96299
|
+
await this.setupMambalade();
|
|
96300
|
+
}
|
|
96296
96301
|
logger.info("Started instantiating Python code-aware analysis");
|
|
96297
96302
|
logger.debug(`Trying to find files to analyze from projectDir: ${this.projectDir}`);
|
|
96298
96303
|
const { rootWorkingDir, reachabilityAnalysisOptions } = this.state;
|
|
@@ -96326,7 +96331,7 @@ runpy.run_module("mambalade", alter_sys=True)
|
|
|
96326
96331
|
const excludeDistributionsOption = packagesToExclude?.size ? ["--exclude-distributions", ...packagesToExclude] : [];
|
|
96327
96332
|
const timeout = reachabilityAnalysisOptions.timeoutInSeconds ?? // 10 minutes for the first analysis, 1 minute for subsequent analyses
|
|
96328
96333
|
(analyzesAllVulns ? 60 * 10 : 60);
|
|
96329
|
-
const pythonExecutable =
|
|
96334
|
+
const pythonExecutable = join15(this.mambaladeVenvPath, "bin", "python");
|
|
96330
96335
|
const mambaladeArgs = [
|
|
96331
96336
|
pythonExecutable,
|
|
96332
96337
|
wrapperPath,
|
|
@@ -96603,12 +96608,34 @@ ${msg}`;
|
|
|
96603
96608
|
getVirtualEnvInfo() {
|
|
96604
96609
|
return this.virtualEnvInfo;
|
|
96605
96610
|
}
|
|
96611
|
+
async setupMambalade() {
|
|
96612
|
+
const venvDir = await createTmpDirectory("mambalade-venv");
|
|
96613
|
+
logger.info("Creating Mambalade virtual environment");
|
|
96614
|
+
const pythonInterpreter = await getPythonInterpreter();
|
|
96615
|
+
await exec(cmdt`${pythonInterpreter} -SIm venv ${venvDir}`);
|
|
96616
|
+
const mambaladeWheelsPath = join15(COANA_REPOS_PATH(), "mambalade", "dist");
|
|
96617
|
+
const wheelFiles = await readdir3(mambaladeWheelsPath);
|
|
96618
|
+
const mambaladeWheels = wheelFiles.filter((f2) => f2.endsWith(".whl")).map((f2) => join15(mambaladeWheelsPath, f2));
|
|
96619
|
+
if (mambaladeWheels.length === 0) {
|
|
96620
|
+
throw new Error(`No mambalade wheel files found in ${mambaladeWheelsPath}`);
|
|
96621
|
+
}
|
|
96622
|
+
logger.info(`Installing mambalade wheels: ${mambaladeWheels.join(", ")}`);
|
|
96623
|
+
await exec(cmdt`${venvDir}/bin/pip install --no-deps ${mambaladeWheels}`);
|
|
96624
|
+
this.mambaladeVenvPath = venvDir;
|
|
96625
|
+
logger.info("Mambalade virtual environment setup complete");
|
|
96626
|
+
}
|
|
96606
96627
|
// async [Symbol.asyncDispose]() {
|
|
96607
96628
|
async cleanup() {
|
|
96608
96629
|
if (this.virtualEnvInfo?.temporary) {
|
|
96609
|
-
await rm5(this.virtualEnvInfo.virtualEnvFolder, { recursive: true, force: true })
|
|
96630
|
+
await rm5(this.virtualEnvInfo.virtualEnvFolder, { recursive: true, force: true }).catch(() => {
|
|
96631
|
+
});
|
|
96610
96632
|
this.virtualEnvInfo = void 0;
|
|
96611
96633
|
}
|
|
96634
|
+
if (this.mambaladeVenvPath) {
|
|
96635
|
+
await rm5(this.mambaladeVenvPath, { recursive: true, force: true }).catch(() => {
|
|
96636
|
+
});
|
|
96637
|
+
this.mambaladeVenvPath = void 0;
|
|
96638
|
+
}
|
|
96612
96639
|
}
|
|
96613
96640
|
};
|
|
96614
96641
|
async function findFilesToAnalyze(projectDir) {
|
|
@@ -96647,6 +96674,16 @@ function transformSourceLocations2(appPath, fileMappings, detectedOccurrences) {
|
|
|
96647
96674
|
}
|
|
96648
96675
|
return detectedOccurrences;
|
|
96649
96676
|
}
|
|
96677
|
+
async function getPythonInterpreter() {
|
|
96678
|
+
const pythonVersionRequired = ">=3.11.0";
|
|
96679
|
+
const pypyVersion = await getPythonVersion("pypy3").catch(() => void 0);
|
|
96680
|
+
if (pypyVersion && (0, import_semver2.satisfies)(pypyVersion, pythonVersionRequired))
|
|
96681
|
+
return "pypy3";
|
|
96682
|
+
const pythonVersion = await getPythonVersion("python3").catch(() => void 0);
|
|
96683
|
+
if (pythonVersion && (0, import_semver2.satisfies)(pythonVersion, pythonVersionRequired))
|
|
96684
|
+
return "python3";
|
|
96685
|
+
throw new Error(`No Python ${pythonVersionRequired} interpreter found`);
|
|
96686
|
+
}
|
|
96650
96687
|
|
|
96651
96688
|
// dist/whole-program-code-aware-vulnerability-scanner/python/phantom-deps.js
|
|
96652
96689
|
var { uniq: uniq8 } = import_lodash15.default;
|
|
@@ -96890,7 +96927,7 @@ async function analyzeWithHeuristics(state, vulns, heuristicsInOrder, doNotRecom
|
|
|
96890
96927
|
if (bucketsFromLastAnalysis.some((b) => b.heuristicName === heuristics.IGNORE_DEPENDENCIES_AND_MAX_ROUNDS_3.name))
|
|
96891
96928
|
return;
|
|
96892
96929
|
try {
|
|
96893
|
-
if ((0,
|
|
96930
|
+
if ((0, import_semver3.lt)(cliVersion, CLI_VERSION_TO_USE_CACHING_FROM[ecosystem] ?? CLI_VERSION_TO_USE_CACHING_FROM_DEFAULT))
|
|
96894
96931
|
return void 0;
|
|
96895
96932
|
} catch (e) {
|
|
96896
96933
|
return void 0;
|