@contrast/contrast 1.0.1 → 1.0.4
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/.prettierignore +2 -0
- package/README.md +103 -133
- package/dist/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +26 -11
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +62 -234
- package/dist/audit/languageAnalysisEngine/report/models/reportLibraryModel.js +19 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +24 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +10 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +24 -129
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +85 -0
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +3 -1
- package/dist/commands/audit/auditController.js +6 -3
- package/dist/commands/audit/saveFile.js +11 -0
- package/dist/commands/auth/auth.js +19 -1
- package/dist/commands/config/config.js +19 -8
- package/dist/commands/scan/processScan.js +8 -25
- package/dist/common/HTTPClient.js +30 -26
- package/dist/common/errorHandling.js +17 -1
- package/dist/common/versionChecker.js +32 -0
- package/dist/constants/constants.js +4 -2
- package/dist/constants/lambda.js +3 -1
- package/dist/constants/locales.js +41 -18
- package/dist/constants.js +39 -3
- package/dist/index.js +49 -28
- package/dist/lambda/help.js +22 -14
- package/dist/lambda/lambda.js +6 -0
- package/dist/sbom/generateSbom.js +20 -0
- package/dist/scan/help.js +4 -2
- package/dist/scan/models/groupedResultsModel.js +10 -0
- package/dist/scan/models/resultContentModel.js +2 -0
- package/dist/scan/models/scanResultsModel.js +11 -0
- package/dist/scan/populateProjectIdAndProjectName.js +1 -0
- package/dist/scan/saveResults.js +9 -10
- package/dist/scan/scan.js +99 -74
- package/dist/scan/scanConfig.js +20 -1
- package/dist/scan/scanController.js +7 -2
- package/dist/scan/scanResults.js +6 -0
- package/dist/utils/getConfig.js +3 -0
- package/dist/utils/paramsUtil/commandlineParams.js +1 -1
- package/dist/utils/requestUtils.js +1 -1
- package/dist/utils/saveFile.js +19 -0
- package/package.json +2 -2
- package/src/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +33 -15
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +127 -0
- package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +30 -0
- package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +32 -0
- package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +9 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +56 -0
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +110 -0
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +3 -1
- package/src/commands/audit/auditController.ts +12 -3
- package/src/commands/audit/processAudit.ts +0 -1
- package/src/commands/audit/saveFile.ts +6 -0
- package/src/commands/auth/auth.js +25 -1
- package/src/commands/config/config.js +22 -8
- package/src/commands/scan/processScan.js +8 -29
- package/src/common/HTTPClient.js +42 -36
- package/src/common/errorHandling.ts +29 -2
- package/src/common/versionChecker.ts +41 -0
- package/src/constants/constants.js +5 -4
- package/src/constants/lambda.js +3 -1
- package/src/constants/locales.js +51 -19
- package/src/constants.js +44 -3
- package/src/index.ts +63 -31
- package/src/lambda/help.ts +22 -14
- package/src/lambda/lambda.ts +8 -0
- package/src/sbom/generateSbom.ts +17 -0
- package/src/scan/help.js +4 -2
- package/src/scan/models/groupedResultsModel.ts +18 -0
- package/src/scan/models/resultContentModel.ts +86 -0
- package/src/scan/models/scanResultsModel.ts +52 -0
- package/src/scan/populateProjectIdAndProjectName.js +1 -0
- package/src/scan/saveResults.js +8 -9
- package/src/scan/scan.ts +192 -0
- package/src/scan/scanConfig.js +26 -1
- package/src/scan/scanController.js +11 -2
- package/src/scan/scanResults.js +11 -0
- package/src/utils/getConfig.ts +12 -0
- package/src/utils/paramsUtil/commandlineParams.js +1 -1
- package/src/utils/requestUtils.js +1 -1
- package/src/utils/saveFile.js +19 -0
- package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -17
- package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -81
- package/dist/common/findLatestCLIVersion.js +0 -23
- package/dist/lambda/scanDetail.js +0 -30
- package/dist/scan/fileFinder.js +0 -15
- package/dist/utils/fileUtils.js +0 -31
- package/dist/utils/paramsUtil/genericCommandLineParams.js +0 -12
- package/dist/utils/paramsUtil/yamlParams.js +0 -6
- package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +0 -27
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +0 -303
- package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +0 -124
- package/src/audit/languageAnalysisEngine/report/reportingFeature.js +0 -190
- package/src/common/findLatestCLIVersion.ts +0 -27
- package/src/scan/scan.js +0 -162
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReportCVEModel = exports.ReportLibraryModel = void 0;
|
|
4
|
+
class ReportLibraryModel {
|
|
5
|
+
constructor(name, cveArray) {
|
|
6
|
+
this.name = name;
|
|
7
|
+
this.cveArray = cveArray;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.ReportLibraryModel = ReportLibraryModel;
|
|
11
|
+
class ReportCVEModel {
|
|
12
|
+
constructor(name, description, severityCode, cvss3SeverityCode) {
|
|
13
|
+
this.name = name;
|
|
14
|
+
this.description = description;
|
|
15
|
+
this.severityCode = severityCode;
|
|
16
|
+
this.cvss3SeverityCode = cvss3SeverityCode;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.ReportCVEModel = ReportCVEModel;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReportCompositeKey = exports.ReportModelStructure = exports.ReportList = void 0;
|
|
4
|
+
class ReportList {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.reportOutputList = [];
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
exports.ReportList = ReportList;
|
|
10
|
+
class ReportModelStructure {
|
|
11
|
+
constructor(compositeKey, cveArray) {
|
|
12
|
+
this.compositeKey = compositeKey;
|
|
13
|
+
this.cveArray = cveArray;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.ReportModelStructure = ReportModelStructure;
|
|
17
|
+
class ReportCompositeKey {
|
|
18
|
+
constructor(libraryName, libraryVersion, highestSeverity) {
|
|
19
|
+
this.libraryName = libraryName;
|
|
20
|
+
this.libraryVersion = libraryVersion;
|
|
21
|
+
this.highestSeverity = highestSeverity;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.ReportCompositeKey = ReportCompositeKey;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReportSeverityModel = void 0;
|
|
4
|
+
class ReportSeverityModel {
|
|
5
|
+
constructor(severity, priority) {
|
|
6
|
+
this.severity = severity;
|
|
7
|
+
this.priority = priority;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.ReportSeverityModel = ReportSeverityModel;
|
|
@@ -1,133 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
if (config['report']) {
|
|
14
|
-
const reportResponse = await commonReport.getReport(applicationId);
|
|
15
|
-
if (reportResponse !== undefined) {
|
|
16
|
-
const libraryVulnerabilityInput = createLibraryVulnerabilityInput(reportResponse.reports);
|
|
17
|
-
const libraryVulnerabilityResponse = await getLibraryVulnerabilities(libraryVulnerabilityInput, applicationId);
|
|
18
|
-
const severity = config['cve_severity'];
|
|
19
|
-
const id = applicationId;
|
|
20
|
-
const name = config.applicationName;
|
|
21
|
-
const hasSomeVulnerabilitiesReported = formatVulnerabilityOutput(libraryVulnerabilityResponse, severity, id, name, depRiskReportCount, config);
|
|
22
|
-
commonReport.analyseReportOptions(hasSomeVulnerabilitiesReported);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
const createLibraryVulnerabilityInput = report => {
|
|
27
|
-
const language = Object.keys(report[0].report)[0];
|
|
28
|
-
const reportTree = report[0].report[language].dependencyTree;
|
|
29
|
-
const libraries = reportTree[Object.keys(reportTree)[0]];
|
|
30
|
-
let gav = [];
|
|
31
|
-
for (const key of Object.keys(libraries)) {
|
|
32
|
-
gav.push({
|
|
33
|
-
name: libraries[key].name,
|
|
34
|
-
group: libraries[key].group,
|
|
35
|
-
version: libraries[key].resolved
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
return {
|
|
39
|
-
name_group_versions: gav,
|
|
40
|
-
language: language.toUpperCase()
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
|
-
const oldCountSeverity = vulnerableLibraries => {
|
|
44
|
-
const severityCount = {
|
|
45
|
-
critical: 0,
|
|
46
|
-
high: 0,
|
|
47
|
-
medium: 0,
|
|
48
|
-
low: 0
|
|
49
|
-
};
|
|
50
|
-
vulnerableLibraries.forEach(lib => {
|
|
51
|
-
lib.vulns.forEach(vuln => {
|
|
52
|
-
if (vuln.severity_code === 'HIGH') {
|
|
53
|
-
severityCount['high'] += 1;
|
|
54
|
-
}
|
|
55
|
-
else if (vuln.severity_code === 'MEDIUM') {
|
|
56
|
-
severityCount['medium'] += 1;
|
|
57
|
-
}
|
|
58
|
-
else if (vuln.severity_code === 'LOW') {
|
|
59
|
-
severityCount['low'] += 1;
|
|
60
|
-
}
|
|
61
|
-
else if (vuln.severity_code === 'CRITICAL') {
|
|
62
|
-
severityCount['critical'] += 1;
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
return severityCount;
|
|
67
|
-
};
|
|
68
|
-
const parseVulnerabilites = libraryVulnerabilityResponse => {
|
|
69
|
-
let parsedVulnerabilites = {};
|
|
70
|
-
let vulnName = libraryVulnerabilityResponse.libraries;
|
|
71
|
-
for (let x in vulnName) {
|
|
72
|
-
let vuln = vulnName[x].vulns;
|
|
73
|
-
if (vuln.length > 0) {
|
|
74
|
-
let libname = vulnName[x].group +
|
|
75
|
-
'/' +
|
|
76
|
-
vulnName[x].file_name +
|
|
77
|
-
'@' +
|
|
78
|
-
vulnName[x].file_version;
|
|
79
|
-
parsedVulnerabilites[libname] = vulnName[x].vulns;
|
|
80
|
-
}
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatVulnerabilityOutput = exports.vulnerabilityReport = void 0;
|
|
4
|
+
const commonReportingFunctions_1 = require("./commonReportingFunctions");
|
|
5
|
+
const reportUtils_1 = require("./utils/reportUtils");
|
|
6
|
+
async function vulnerabilityReport(analysis, applicationId, reportId) {
|
|
7
|
+
const reportResponse = await (0, commonReportingFunctions_1.getReport)(analysis.config, reportId);
|
|
8
|
+
if (reportResponse !== undefined) {
|
|
9
|
+
const id = applicationId;
|
|
10
|
+
const name = analysis.config.applicationName;
|
|
11
|
+
formatVulnerabilityOutput(reportResponse.vulnerabilities, id, name, analysis.config);
|
|
81
12
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return data.vulns.length > 0;
|
|
87
|
-
});
|
|
13
|
+
}
|
|
14
|
+
exports.vulnerabilityReport = vulnerabilityReport;
|
|
15
|
+
function formatVulnerabilityOutput(libraryVulnerabilityResponse, id, name, config) {
|
|
16
|
+
const vulnerableLibraries = (0, reportUtils_1.convertGenericToTypedLibraries)(libraryVulnerabilityResponse);
|
|
88
17
|
const numberOfVulnerableLibraries = vulnerableLibraries.length;
|
|
89
18
|
let numberOfCves = 0;
|
|
90
|
-
vulnerableLibraries.forEach(lib => (numberOfCves += lib.
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (depRiskReportCount && depRiskReportCount.scopedCount === 0) {
|
|
101
|
-
console.log(' No private libraries that are not scoped detected');
|
|
102
|
-
}
|
|
103
|
-
console.log(' \n Please go to the Contrast UI to view your dependency tree: \n' +
|
|
104
|
-
` \n ${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`);
|
|
105
|
-
return [hasSomeVulnerabilitiesReported, numberOfCves, severityCount];
|
|
106
|
-
};
|
|
107
|
-
const getLibraryVulnerabilities = async (input, applicationId) => {
|
|
108
|
-
const requestBody = input;
|
|
109
|
-
const addParams = agent.getAdditionalParams();
|
|
110
|
-
const userParams = await util.getParams(applicationId);
|
|
111
|
-
const protocol = getValidHost(userParams.host);
|
|
112
|
-
const client = commonApi.getHttpClient(userParams, protocol, addParams);
|
|
113
|
-
return client
|
|
114
|
-
.getLibraryVulnerabilities(requestBody, userParams)
|
|
115
|
-
.then(res => {
|
|
116
|
-
if (res.statusCode === 200) {
|
|
117
|
-
displaySuccessMessageVulnerabilities();
|
|
118
|
-
return res.body;
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
handleResponseErrors(res, 'vulnerabilities');
|
|
122
|
-
}
|
|
123
|
-
})
|
|
124
|
-
.catch(err => {
|
|
125
|
-
console.log(err);
|
|
126
|
-
});
|
|
127
|
-
};
|
|
128
|
-
module.exports = {
|
|
129
|
-
vulnerabilityReport: vulnerabilityReport,
|
|
130
|
-
getLibraryVulnerabilities: getLibraryVulnerabilities,
|
|
131
|
-
formatVulnerabilityOutput: formatVulnerabilityOutput,
|
|
132
|
-
createLibraryVulnerabilityInput: createLibraryVulnerabilityInput
|
|
133
|
-
};
|
|
19
|
+
vulnerableLibraries.forEach(lib => (numberOfCves += lib.cveArray.length));
|
|
20
|
+
(0, commonReportingFunctions_1.createLibraryHeader)(id, numberOfVulnerableLibraries, numberOfCves, name);
|
|
21
|
+
const hasSomeVulnerabilitiesReported = (0, commonReportingFunctions_1.printVulnerabilityResponse)(vulnerableLibraries, config);
|
|
22
|
+
return [
|
|
23
|
+
hasSomeVulnerabilitiesReported,
|
|
24
|
+
numberOfCves,
|
|
25
|
+
(0, reportUtils_1.severityCount)(vulnerableLibraries)
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
exports.formatVulnerabilityOutput = formatVulnerabilityOutput;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.findNameAndVersion = exports.severityCount = exports.convertGenericToTypedLibraries = exports.findHighestSeverityCVE = void 0;
|
|
7
|
+
const reportLibraryModel_1 = require("../models/reportLibraryModel");
|
|
8
|
+
const reportSeverityModel_1 = require("../models/reportSeverityModel");
|
|
9
|
+
const constants_1 = __importDefault(require("../../../languageAnalysisEngine/constants"));
|
|
10
|
+
const { supportedLanguages: { GO } } = constants_1.default;
|
|
11
|
+
function findHighestSeverityCVE(cveArray) {
|
|
12
|
+
if (cveArray.find(cve => cve.cvss3SeverityCode === 'CRITICAL' || cve.severityCode === 'CRITICAL')) {
|
|
13
|
+
return new reportSeverityModel_1.ReportSeverityModel('CRITICAL', 1);
|
|
14
|
+
}
|
|
15
|
+
else if (cveArray.find(cve => cve.cvss3SeverityCode === 'HIGH' || cve.severityCode === 'HIGH')) {
|
|
16
|
+
return new reportSeverityModel_1.ReportSeverityModel('HIGH', 2);
|
|
17
|
+
}
|
|
18
|
+
else if (cveArray.find(cve => cve.cvss3SeverityCode === 'MEDIUM' || cve.severityCode === 'MEDIUM')) {
|
|
19
|
+
return new reportSeverityModel_1.ReportSeverityModel('MEDIUM', 3);
|
|
20
|
+
}
|
|
21
|
+
else if (cveArray.find(cve => cve.cvss3SeverityCode === 'LOW' || cve.severityCode === 'LOW')) {
|
|
22
|
+
return new reportSeverityModel_1.ReportSeverityModel('LOW', 4);
|
|
23
|
+
}
|
|
24
|
+
else if (cveArray.find(cve => cve.cvss3SeverityCode === 'NOTE' || cve.severityCode === 'NOTE')) {
|
|
25
|
+
return new reportSeverityModel_1.ReportSeverityModel('NOTE', 5);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.findHighestSeverityCVE = findHighestSeverityCVE;
|
|
29
|
+
function convertGenericToTypedLibraries(libraries) {
|
|
30
|
+
return Object.entries(libraries).map(([name, cveArray]) => {
|
|
31
|
+
return new reportLibraryModel_1.ReportLibraryModel(name, cveArray);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
exports.convertGenericToTypedLibraries = convertGenericToTypedLibraries;
|
|
35
|
+
function severityCount(vulnerableLibraries) {
|
|
36
|
+
const severityCount = {
|
|
37
|
+
critical: 0,
|
|
38
|
+
high: 0,
|
|
39
|
+
medium: 0,
|
|
40
|
+
low: 0,
|
|
41
|
+
note: 0
|
|
42
|
+
};
|
|
43
|
+
vulnerableLibraries.forEach(lib => {
|
|
44
|
+
lib.cveArray.forEach(cve => {
|
|
45
|
+
if (cve.cvss3SeverityCode === 'CRITICAL' ||
|
|
46
|
+
cve.severityCode === 'CRITICAL') {
|
|
47
|
+
severityCount['critical'] += 1;
|
|
48
|
+
}
|
|
49
|
+
else if (cve.cvss3SeverityCode === 'HIGH' ||
|
|
50
|
+
cve.severityCode === 'HIGH') {
|
|
51
|
+
severityCount['high'] += 1;
|
|
52
|
+
}
|
|
53
|
+
else if (cve.cvss3SeverityCode === 'MEDIUM' ||
|
|
54
|
+
cve.severityCode === 'MEDIUM') {
|
|
55
|
+
severityCount['medium'] += 1;
|
|
56
|
+
}
|
|
57
|
+
else if (cve.cvss3SeverityCode === 'LOW' ||
|
|
58
|
+
cve.severityCode === 'LOW') {
|
|
59
|
+
severityCount['low'] += 1;
|
|
60
|
+
}
|
|
61
|
+
else if (cve.cvss3SeverityCode === 'NOTE' ||
|
|
62
|
+
cve.severityCode === 'NOTE') {
|
|
63
|
+
severityCount['note'] += 1;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
return severityCount;
|
|
68
|
+
}
|
|
69
|
+
exports.severityCount = severityCount;
|
|
70
|
+
function findNameAndVersion(library, config) {
|
|
71
|
+
if (config.language.toUpperCase() === GO) {
|
|
72
|
+
const nameVersion = library.name.split('@');
|
|
73
|
+
const name = nameVersion[0];
|
|
74
|
+
const version = nameVersion[1];
|
|
75
|
+
return { name, version };
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const splitLibraryName = library.name.split('/');
|
|
79
|
+
const nameVersion = splitLibraryName[1].split('@');
|
|
80
|
+
const name = nameVersion[0];
|
|
81
|
+
const version = nameVersion[1];
|
|
82
|
+
return { name, version };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.findNameAndVersion = findNameAndVersion;
|
|
@@ -24,7 +24,9 @@ const newSendSnapShot = async (analysis, applicationId) => {
|
|
|
24
24
|
.sendSnapshot(requestBody, analysis.config)
|
|
25
25
|
.then(res => {
|
|
26
26
|
if (res.statusCode === 201) {
|
|
27
|
-
|
|
27
|
+
if (analysis.config.host !== 'https://ce.contrastsecurity.com/') {
|
|
28
|
+
displaySnapshotSuccessMessage(analysis.config);
|
|
29
|
+
}
|
|
28
30
|
return res.body;
|
|
29
31
|
}
|
|
30
32
|
else {
|
|
@@ -7,7 +7,7 @@ exports.startAudit = void 0;
|
|
|
7
7
|
const catalogueApplication_1 = require("../../audit/catalogueApplication/catalogueApplication");
|
|
8
8
|
const commonApi_1 = __importDefault(require("../../audit/languageAnalysisEngine/commonApi"));
|
|
9
9
|
const identifyLanguageAE = require('./../../audit/languageAnalysisEngine');
|
|
10
|
-
const languageFactory = require('
|
|
10
|
+
const languageFactory = require('../../audit/languageAnalysisEngine/languageAnalysisFactory');
|
|
11
11
|
const dealWithNoAppId = async (config) => {
|
|
12
12
|
let appID;
|
|
13
13
|
try {
|
|
@@ -17,9 +17,12 @@ const dealWithNoAppId = async (config) => {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
catch (e) {
|
|
20
|
-
|
|
20
|
+
if (e.toString().includes('tunneling socket could not be established')) {
|
|
21
|
+
console.log(e.message);
|
|
22
|
+
console.log('There seems to be an issue with your proxy, please check and try again');
|
|
23
|
+
}
|
|
24
|
+
process.exit(1);
|
|
21
25
|
}
|
|
22
|
-
console.log(appID);
|
|
23
26
|
return appID;
|
|
24
27
|
};
|
|
25
28
|
const startAudit = async (config) => {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
function saveFile(config, rawResults) {
|
|
8
|
+
const fileName = `${config.applicationId}-sbom-cyclonedx.json`;
|
|
9
|
+
fs_1.default.writeFileSync(fileName, JSON.stringify(rawResults));
|
|
10
|
+
}
|
|
11
|
+
exports.default = saveFile;
|
|
@@ -7,7 +7,15 @@ const { sleep } = require('../../utils/requestUtils');
|
|
|
7
7
|
const i18n = require('i18n');
|
|
8
8
|
const { returnOra, startSpinner, failSpinner, succeedSpinner } = require('../../utils/oraWrapper');
|
|
9
9
|
const { TIMEOUT, AUTH_UI_URL } = require('../../constants/constants');
|
|
10
|
-
const
|
|
10
|
+
const parsedCLIOptions = require('../../utils/parsedCLIOptions');
|
|
11
|
+
const constants = require('../../constants');
|
|
12
|
+
const commandLineUsage = require('command-line-usage');
|
|
13
|
+
const processAuth = async (argv, config) => {
|
|
14
|
+
let authParams = parsedCLIOptions.getCommandLineArgsCustom(argv, constants.commandLineDefinitions.authOptionDefinitions);
|
|
15
|
+
if (authParams.help) {
|
|
16
|
+
console.log(authUsageGuide);
|
|
17
|
+
process.exit(0);
|
|
18
|
+
}
|
|
11
19
|
const token = uuidv4();
|
|
12
20
|
const url = `${AUTH_UI_URL}/?token=${token}`;
|
|
13
21
|
console.log(i18n.__('redirectAuth', url));
|
|
@@ -56,6 +64,16 @@ const pollAuthResult = async (token, client) => {
|
|
|
56
64
|
console.log(err);
|
|
57
65
|
});
|
|
58
66
|
};
|
|
67
|
+
const authUsageGuide = commandLineUsage([
|
|
68
|
+
{
|
|
69
|
+
header: i18n.__('authHeader'),
|
|
70
|
+
content: [i18n.__('constantsAuthHeaderContents')]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
header: i18n.__('constantsAuthUsageHeader'),
|
|
74
|
+
content: [i18n.__('constantsAuthUsageContents')]
|
|
75
|
+
}
|
|
76
|
+
]);
|
|
59
77
|
module.exports = {
|
|
60
78
|
processAuth: processAuth
|
|
61
79
|
};
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const
|
|
2
|
+
const parsedCLIOptions = require('../../utils/parsedCLIOptions');
|
|
3
|
+
const constants = require('../../constants');
|
|
4
|
+
const commandLineUsage = require('command-line-usage');
|
|
5
|
+
const i18n = require('i18n');
|
|
3
6
|
const processConfig = (argv, config) => {
|
|
4
|
-
const options = [{ name: 'clear', alias: 'c', type: Boolean }];
|
|
5
7
|
try {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
if (
|
|
8
|
+
let configParams = parsedCLIOptions.getCommandLineArgsCustom(argv, constants.commandLineDefinitions.configOptionDefinitions);
|
|
9
|
+
if (configParams.help) {
|
|
10
|
+
console.log(configUsageGuide);
|
|
11
|
+
process.exit(0);
|
|
12
|
+
}
|
|
13
|
+
if (configParams.clear) {
|
|
12
14
|
config.clear();
|
|
13
15
|
}
|
|
14
16
|
else {
|
|
@@ -19,6 +21,15 @@ const processConfig = (argv, config) => {
|
|
|
19
21
|
console.log(e.message.toString());
|
|
20
22
|
}
|
|
21
23
|
};
|
|
24
|
+
const configUsageGuide = commandLineUsage([
|
|
25
|
+
{
|
|
26
|
+
header: i18n.__('configHeader')
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
content: [i18n.__('constantsConfigUsageContents')],
|
|
30
|
+
optionList: constants.commandLineDefinitions.configOptionDefinitions
|
|
31
|
+
}
|
|
32
|
+
]);
|
|
22
33
|
module.exports = {
|
|
23
34
|
processConfig: processConfig
|
|
24
35
|
};
|
|
@@ -1,37 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const { startScan } = require('../../scan/scanController');
|
|
3
|
-
const { formatScanOutput } = require('../../scan/scan');
|
|
4
3
|
const { scanUsageGuide } = require('../../scan/help');
|
|
5
4
|
const scanConfig = require('../../scan/scanConfig');
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
5
|
+
const { saveScanFile } = require('../../utils/saveFile');
|
|
6
|
+
const { ScanResultsModel } = require('../../scan/models/scanResultsModel');
|
|
7
|
+
const { formatScanOutput } = require('../../scan/scan');
|
|
9
8
|
const processScan = async (argvMain) => {
|
|
10
|
-
if (argvMain.indexOf('--help') !== -1) {
|
|
11
|
-
printHelpMessage();
|
|
12
|
-
process.exit(1);
|
|
13
|
-
}
|
|
14
9
|
let config = scanConfig.getScanConfig(argvMain);
|
|
15
|
-
let scanResults = await startScan(config);
|
|
10
|
+
let scanResults = new ScanResultsModel(await startScan(config));
|
|
16
11
|
if (scanResults) {
|
|
17
|
-
formatScanOutput(scanResults
|
|
12
|
+
formatScanOutput(scanResults);
|
|
18
13
|
}
|
|
19
|
-
if (config.save) {
|
|
20
|
-
|
|
21
|
-
const scanId = scanResults.scanDetail.id;
|
|
22
|
-
const client = commonApi.getHttpClient(config);
|
|
23
|
-
const rawResults = await client.getSpecificScanResultSarif(config, scanId);
|
|
24
|
-
saveResults.writeResultsToFile(rawResults?.body);
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
console.log(i18n.__('scanNoFiletypeSpecifiedForSave'));
|
|
28
|
-
}
|
|
14
|
+
if (config.save !== undefined) {
|
|
15
|
+
await saveScanFile(config, scanResults);
|
|
29
16
|
}
|
|
30
17
|
};
|
|
31
|
-
const printHelpMessage = () => {
|
|
32
|
-
console.log(scanUsageGuide);
|
|
33
|
-
};
|
|
34
18
|
module.exports = {
|
|
35
|
-
processScan
|
|
36
|
-
printHelpMessage
|
|
19
|
+
processScan
|
|
37
20
|
};
|
|
@@ -77,7 +77,9 @@ HTTPClient.prototype.getScanId = function getScanId(config, codeArtifactId) {
|
|
|
77
77
|
options.url = url;
|
|
78
78
|
options.body = {
|
|
79
79
|
codeArtifactId: codeArtifactId,
|
|
80
|
-
label:
|
|
80
|
+
label: config.label
|
|
81
|
+
? config.label
|
|
82
|
+
: `Started by CLI tool at ${new Date().toString()}`
|
|
81
83
|
};
|
|
82
84
|
return requestUtils.sendRequest({ method: 'post', options });
|
|
83
85
|
};
|
|
@@ -97,6 +99,9 @@ HTTPClient.prototype.createProjectId = function createProjectId(config) {
|
|
|
97
99
|
name: config.name,
|
|
98
100
|
archived: 'false'
|
|
99
101
|
};
|
|
102
|
+
if (config.language) {
|
|
103
|
+
options.body.language = config.language;
|
|
104
|
+
}
|
|
100
105
|
options.url = createHarmonyProjectsUrl(config);
|
|
101
106
|
return requestUtils.sendRequest({ method: 'post', options });
|
|
102
107
|
};
|
|
@@ -140,28 +145,28 @@ HTTPClient.prototype.catalogueCommand = function catalogueCommand(config) {
|
|
|
140
145
|
return requestUtils.sendRequest({ method: 'post', options });
|
|
141
146
|
};
|
|
142
147
|
HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
|
|
148
|
+
if (config.language.toUpperCase() === 'RUBY') {
|
|
149
|
+
console.log('sendSnapshot requestBody', requestBody.snapshot.ruby);
|
|
150
|
+
}
|
|
143
151
|
const options = _.cloneDeep(this.requestOptions);
|
|
144
152
|
let url = createSnapshotURL(config);
|
|
145
153
|
options.url = url;
|
|
146
154
|
options.body = requestBody;
|
|
147
155
|
return requestUtils.sendRequest({ method: 'post', options });
|
|
148
156
|
};
|
|
149
|
-
HTTPClient.prototype.
|
|
150
|
-
const options = _.cloneDeep(this.requestOptions);
|
|
151
|
-
let url = createReportUrl(config);
|
|
152
|
-
options.url = url;
|
|
153
|
-
return requestUtils.sendRequest({ method: 'get', options });
|
|
154
|
-
};
|
|
155
|
-
HTTPClient.prototype.getSpecificReport = function getSpecificReport(config, reportId) {
|
|
157
|
+
HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
|
|
156
158
|
const options = _.cloneDeep(this.requestOptions);
|
|
157
|
-
|
|
158
|
-
|
|
159
|
+
if (config.ignoreDev) {
|
|
160
|
+
options.url = createSpecificReportWithProdUrl(config, reportId);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
options.url = createSpecificReportUrl(config, reportId);
|
|
164
|
+
}
|
|
159
165
|
return requestUtils.sendRequest({ method: 'get', options });
|
|
160
166
|
};
|
|
161
|
-
HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(
|
|
167
|
+
HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(config, requestBody) {
|
|
162
168
|
const options = _.cloneDeep(this.requestOptions);
|
|
163
|
-
|
|
164
|
-
options.url = url;
|
|
169
|
+
options.url = createLibraryVulnerabilitiesUrl(config);
|
|
165
170
|
options.body = requestBody;
|
|
166
171
|
return requestUtils.sendRequest({ method: 'put', options });
|
|
167
172
|
};
|
|
@@ -171,12 +176,6 @@ HTTPClient.prototype.getAppId = function getAppId(config) {
|
|
|
171
176
|
options.url = url;
|
|
172
177
|
return requestUtils.sendRequest({ method: 'get', options });
|
|
173
178
|
};
|
|
174
|
-
HTTPClient.prototype.getDependencyTree = function getReport(orgUuid, appId, reportId) {
|
|
175
|
-
const options = _.cloneDeep(this.requestOptions);
|
|
176
|
-
let url = createGetDependencyTree(options.uri, orgUuid, appId, reportId);
|
|
177
|
-
options.url = url;
|
|
178
|
-
return requestUtils.sendRequest({ method: 'get', options });
|
|
179
|
-
};
|
|
180
179
|
function getServerlessHost(config = {}) {
|
|
181
180
|
const originalHost = config?.host || config?.get('host');
|
|
182
181
|
const host = originalHost?.endsWith('/')
|
|
@@ -224,6 +223,11 @@ HTTPClient.prototype.checkLibrary = function checkLibrary(data) {
|
|
|
224
223
|
options.body = data;
|
|
225
224
|
return requestUtils.sendRequest({ method: 'post', options });
|
|
226
225
|
};
|
|
226
|
+
HTTPClient.prototype.getSbom = function getSbom(config) {
|
|
227
|
+
const options = _.cloneDeep(this.requestOptions);
|
|
228
|
+
options.url = createSbomCycloneDXUrl(config);
|
|
229
|
+
return requestUtils.sendRequest({ method: 'get', options });
|
|
230
|
+
};
|
|
227
231
|
const createGetScanIdURL = config => {
|
|
228
232
|
return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/`;
|
|
229
233
|
};
|
|
@@ -263,18 +267,18 @@ const createAppNameUrl = config => {
|
|
|
263
267
|
function createLibraryVulnerabilitiesUrl(config) {
|
|
264
268
|
return `${config.host}/Contrast/api/ng/${config.organizationId}/libraries/artifactsByGroupNameVersion`;
|
|
265
269
|
}
|
|
266
|
-
function createReportUrl(config) {
|
|
267
|
-
return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports`;
|
|
268
|
-
}
|
|
269
270
|
function createSpecificReportUrl(config, reportId) {
|
|
270
|
-
return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}
|
|
271
|
+
return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}`;
|
|
272
|
+
}
|
|
273
|
+
function createSpecificReportWithProdUrl(config, reportId) {
|
|
274
|
+
return createSpecificReportUrl(config, reportId).concat(`?nodesToInclude=PROD`);
|
|
271
275
|
}
|
|
272
276
|
function createDataUrl() {
|
|
273
277
|
return `https://ardy.contrastsecurity.com/production`;
|
|
274
278
|
}
|
|
275
|
-
|
|
276
|
-
return `${
|
|
277
|
-
}
|
|
279
|
+
function createSbomCycloneDXUrl(config) {
|
|
280
|
+
return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/cyclonedx`;
|
|
281
|
+
}
|
|
278
282
|
module.exports = HTTPClient;
|
|
279
283
|
module.exports.pollForAuthUrl = pollForAuthUrl;
|
|
280
284
|
module.exports.getServerlessHost = getServerlessHost;
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.libraryAnalysisError = exports.handleResponseErrors = exports.getErrorMessage = exports.generalError = exports.hostWarningError = exports.failOptionError = exports.proxyError = exports.forbiddenError = exports.badRequestError = exports.unauthenticatedError = exports.genericError = void 0;
|
|
6
|
+
exports.findCommandOnError = exports.libraryAnalysisError = exports.handleResponseErrors = exports.getErrorMessage = exports.generalError = exports.hostWarningError = exports.failOptionError = exports.proxyError = exports.forbiddenError = exports.badRequestError = exports.unauthenticatedError = exports.genericError = void 0;
|
|
7
7
|
const i18n_1 = __importDefault(require("i18n"));
|
|
8
8
|
const handleResponseErrors = (res, api) => {
|
|
9
9
|
if (res.statusCode === 400) {
|
|
@@ -71,6 +71,7 @@ const badRequestError = (catalogue) => {
|
|
|
71
71
|
exports.badRequestError = badRequestError;
|
|
72
72
|
const forbiddenError = () => {
|
|
73
73
|
generalError('forbiddenRequestErrorHeader', 'forbiddenRequestErrorMessage');
|
|
74
|
+
process.exit(1);
|
|
74
75
|
};
|
|
75
76
|
exports.forbiddenError = forbiddenError;
|
|
76
77
|
const proxyError = () => {
|
|
@@ -106,3 +107,18 @@ const generalError = (header, message) => {
|
|
|
106
107
|
console.log(finalMessage);
|
|
107
108
|
};
|
|
108
109
|
exports.generalError = generalError;
|
|
110
|
+
const findCommandOnError = (unknownOptions) => {
|
|
111
|
+
const commandKeywords = {
|
|
112
|
+
auth: 'auth',
|
|
113
|
+
audit: 'audit',
|
|
114
|
+
scan: 'scan',
|
|
115
|
+
lambda: 'lambda',
|
|
116
|
+
config: 'config'
|
|
117
|
+
};
|
|
118
|
+
const containsCommandKeyword = unknownOptions.some(command => commandKeywords[command]);
|
|
119
|
+
if (containsCommandKeyword) {
|
|
120
|
+
const foundCommands = unknownOptions.filter(command => commandKeywords[command]);
|
|
121
|
+
return foundCommands[0];
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
exports.findCommandOnError = findCommandOnError;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.isCorrectNodeVersion = exports.findLatestCLIVersion = void 0;
|
|
7
|
+
const latest_version_1 = __importDefault(require("latest-version"));
|
|
8
|
+
const constants_1 = require("../constants/constants");
|
|
9
|
+
const boxen_1 = __importDefault(require("boxen"));
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
+
const semver_1 = __importDefault(require("semver"));
|
|
12
|
+
async function findLatestCLIVersion(updateMessageHidden) {
|
|
13
|
+
if (!updateMessageHidden) {
|
|
14
|
+
const latestCLIVersion = await (0, latest_version_1.default)('@contrast/contrast');
|
|
15
|
+
if (semver_1.default.lt(constants_1.APP_VERSION, latestCLIVersion)) {
|
|
16
|
+
const updateAvailableMessage = `Update available ${chalk_1.default.yellow(constants_1.APP_VERSION)} → ${chalk_1.default.green(latestCLIVersion)}`;
|
|
17
|
+
const npmUpdateAvailableCommand = `Run ${chalk_1.default.cyan('npm i @contrast/contrast -g')} to update via npm`;
|
|
18
|
+
const homebrewUpdateAvailableCommand = `Run ${chalk_1.default.cyan('brew install contrastsecurity/tap/contrast')} to update via brew`;
|
|
19
|
+
console.log((0, boxen_1.default)(`${updateAvailableMessage}\n${npmUpdateAvailableCommand}\n\n${homebrewUpdateAvailableCommand}`, {
|
|
20
|
+
titleAlignment: 'center',
|
|
21
|
+
margin: 1,
|
|
22
|
+
padding: 1,
|
|
23
|
+
align: 'center'
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.findLatestCLIVersion = findLatestCLIVersion;
|
|
29
|
+
async function isCorrectNodeVersion(currentVersion) {
|
|
30
|
+
return semver_1.default.satisfies(currentVersion, '>=16.13.2 <17');
|
|
31
|
+
}
|
|
32
|
+
exports.isCorrectNodeVersion = isCorrectNodeVersion;
|