@contrast/contrast 1.0.2 → 1.0.5
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 +4 -0
- package/README.md +24 -16
- package/dist/audit/autodetection/autoDetectLanguage.js +32 -0
- package/dist/audit/catalogueApplication/catalogueApplication.js +2 -11
- package/dist/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +30 -13
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +25 -0
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +51 -237
- 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 +2 -14
- package/dist/commands/audit/auditConfig.js +8 -2
- package/dist/commands/audit/auditController.js +14 -5
- 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 +13 -27
- package/dist/commands/scan/sca/scaAnalysis.js +44 -0
- package/dist/common/HTTPClient.js +29 -26
- package/dist/common/errorHandling.js +15 -39
- package/dist/common/versionChecker.js +32 -0
- package/dist/constants/constants.js +16 -2
- package/dist/constants/lambda.js +3 -1
- package/dist/constants/locales.js +58 -48
- package/dist/constants.js +59 -3
- package/dist/index.js +48 -30
- package/dist/lambda/help.js +22 -14
- package/dist/lambda/lambda.js +6 -0
- package/dist/sbom/generateSbom.js +20 -0
- package/dist/scaAnalysis/common/formatMessage.js +11 -0
- package/dist/scaAnalysis/common/treeUpload.js +30 -0
- package/dist/scaAnalysis/java/analysis.js +116 -0
- package/dist/scaAnalysis/java/index.js +18 -0
- package/dist/scaAnalysis/java/javaBuildDepsParser.js +326 -0
- package/dist/scan/autoDetection.js +46 -1
- package/dist/scan/fileUtils.js +73 -1
- package/dist/scan/formatScanOutput.js +212 -0
- package/dist/scan/help.js +6 -2
- package/dist/scan/models/groupedResultsModel.js +11 -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 +26 -101
- package/dist/scan/scanConfig.js +20 -1
- package/dist/scan/scanController.js +8 -4
- package/dist/scan/scanResults.js +8 -17
- package/dist/utils/getConfig.js +3 -0
- package/dist/utils/requestUtils.js +1 -1
- package/dist/utils/saveFile.js +19 -0
- package/package.json +3 -2
- package/src/audit/autodetection/autoDetectLanguage.ts +40 -0
- package/src/audit/catalogueApplication/catalogueApplication.js +4 -16
- package/src/audit/languageAnalysisEngine/{langugageAnalysisFactory.js → languageAnalysisFactory.js} +41 -19
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +71 -0
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +105 -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 +2 -22
- package/src/commands/audit/auditConfig.ts +12 -3
- package/src/commands/audit/auditController.ts +21 -5
- package/src/commands/audit/processAudit.ts +3 -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 +15 -31
- package/src/commands/scan/sca/scaAnalysis.js +73 -0
- package/src/common/HTTPClient.js +42 -36
- package/src/common/errorHandling.ts +17 -48
- package/src/common/versionChecker.ts +41 -0
- package/src/constants/constants.js +17 -4
- package/src/constants/lambda.js +3 -1
- package/src/constants/locales.js +69 -63
- package/src/constants.js +66 -3
- package/src/index.ts +62 -36
- package/src/lambda/help.ts +22 -14
- package/src/lambda/lambda.ts +8 -0
- package/src/sbom/generateSbom.ts +17 -0
- package/src/scaAnalysis/common/formatMessage.js +10 -0
- package/src/scaAnalysis/common/treeUpload.js +34 -0
- package/src/scaAnalysis/java/analysis.js +159 -0
- package/src/scaAnalysis/java/index.js +21 -0
- package/src/scaAnalysis/java/javaBuildDepsParser.js +391 -0
- package/src/scan/autoDetection.js +54 -1
- package/src/scan/fileUtils.js +91 -1
- package/src/scan/formatScanOutput.ts +241 -0
- package/src/scan/help.js +6 -2
- package/src/scan/models/groupedResultsModel.ts +20 -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 +62 -0
- package/src/scan/scanConfig.js +26 -1
- package/src/scan/scanController.js +12 -4
- package/src/scan/scanResults.js +19 -17
- package/src/utils/getConfig.ts +12 -0
- 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/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 -167
|
@@ -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);
|
|
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;
|
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const prettyjson = require('prettyjson');
|
|
3
|
-
const i18n = require('i18n');
|
|
4
2
|
const { getHttpClient } = require('../../utils/commonApi');
|
|
5
3
|
const { handleResponseErrors } = require('../../common/errorHandling');
|
|
6
4
|
const { APP_VERSION } = require('../../constants/constants');
|
|
7
|
-
|
|
8
|
-
console.log('\n **************************' +
|
|
9
|
-
i18n.__('successHeader') +
|
|
10
|
-
'************************** ');
|
|
11
|
-
console.log('\n' + i18n.__('snapshotSuccessMessage') + '\n');
|
|
12
|
-
console.log(` ${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`);
|
|
13
|
-
console.log('\n ***********************************************************');
|
|
14
|
-
}
|
|
15
|
-
const newSendSnapShot = async (analysis, applicationId) => {
|
|
5
|
+
const newSendSnapShot = async (analysis) => {
|
|
16
6
|
const analysisLanguage = analysis.config.language.toLowerCase();
|
|
17
7
|
const requestBody = {
|
|
18
8
|
appID: analysis.config.applicationId,
|
|
@@ -24,7 +14,6 @@ const newSendSnapShot = async (analysis, applicationId) => {
|
|
|
24
14
|
.sendSnapshot(requestBody, analysis.config)
|
|
25
15
|
.then(res => {
|
|
26
16
|
if (res.statusCode === 201) {
|
|
27
|
-
displaySnapshotSuccessMessage(analysis.config);
|
|
28
17
|
return res.body;
|
|
29
18
|
}
|
|
30
19
|
else {
|
|
@@ -36,6 +25,5 @@ const newSendSnapShot = async (analysis, applicationId) => {
|
|
|
36
25
|
});
|
|
37
26
|
};
|
|
38
27
|
module.exports = {
|
|
39
|
-
newSendSnapShot: newSendSnapShot
|
|
40
|
-
displaySnapshotSuccessMessage: displaySnapshotSuccessMessage
|
|
28
|
+
newSendSnapShot: newSendSnapShot
|
|
41
29
|
};
|
|
@@ -8,14 +8,20 @@ const paramHandler_1 = __importDefault(require("../../utils/paramsUtil/paramHand
|
|
|
8
8
|
const constants_1 = __importDefault(require("../../constants"));
|
|
9
9
|
const parsedCLIOptions_1 = __importDefault(require("../../utils/parsedCLIOptions"));
|
|
10
10
|
const constants_2 = __importDefault(require("../../audit/languageAnalysisEngine/constants"));
|
|
11
|
+
const autoDetectLanguage_1 = require("../../audit/autodetection/autoDetectLanguage");
|
|
11
12
|
const { supportedLanguages: { NODE, JAVASCRIPT } } = constants_2.default;
|
|
12
13
|
const getAuditConfig = (argv) => {
|
|
13
14
|
const auditParameters = parsedCLIOptions_1.default.getCommandLineArgsCustom(argv, constants_1.default.commandLineDefinitions.auditOptionDefinitions);
|
|
14
15
|
const paramsAuth = paramHandler_1.default.getAuth(auditParameters);
|
|
15
16
|
if (auditParameters.language === undefined ||
|
|
16
17
|
auditParameters.language === null) {
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
try {
|
|
19
|
+
auditParameters.language = (0, autoDetectLanguage_1.determineProjectLanguage)((0, autoDetectLanguage_1.identifyLanguages)(auditParameters));
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
console.log(err.message);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
19
25
|
}
|
|
20
26
|
else if (auditParameters.language.toUpperCase() === JAVASCRIPT) {
|
|
21
27
|
auditParameters.language = NODE.toLowerCase();
|
|
@@ -3,11 +3,12 @@ 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.startAudit = void 0;
|
|
6
|
+
exports.startAudit = exports.dealWithNoAppId = 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
|
+
const { v4: uuidv4 } = require('uuid');
|
|
11
12
|
const dealWithNoAppId = async (config) => {
|
|
12
13
|
let appID;
|
|
13
14
|
try {
|
|
@@ -15,16 +16,24 @@ const dealWithNoAppId = async (config) => {
|
|
|
15
16
|
if (!appID && config.applicationName) {
|
|
16
17
|
return await (0, catalogueApplication_1.catalogueApplication)(config);
|
|
17
18
|
}
|
|
19
|
+
if (!appID && !config.applicationName) {
|
|
20
|
+
config.applicationName = uuidv4();
|
|
21
|
+
return await (0, catalogueApplication_1.catalogueApplication)(config);
|
|
22
|
+
}
|
|
18
23
|
}
|
|
19
24
|
catch (e) {
|
|
20
|
-
|
|
25
|
+
if (e.toString().includes('tunneling socket could not be established')) {
|
|
26
|
+
console.log(e.message);
|
|
27
|
+
console.log('There seems to be an issue with your proxy, please check and try again');
|
|
28
|
+
}
|
|
29
|
+
process.exit(1);
|
|
21
30
|
}
|
|
22
|
-
console.log(appID);
|
|
23
31
|
return appID;
|
|
24
32
|
};
|
|
33
|
+
exports.dealWithNoAppId = dealWithNoAppId;
|
|
25
34
|
const startAudit = async (config) => {
|
|
26
35
|
if (!config.applicationId) {
|
|
27
|
-
config.applicationId = await dealWithNoAppId(config);
|
|
36
|
+
config.applicationId = await (0, exports.dealWithNoAppId)(config);
|
|
28
37
|
}
|
|
29
38
|
identifyLanguageAE(config.projectPath, languageFactory, config.applicationId, config);
|
|
30
39
|
};
|
|
@@ -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,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const { startScan } = require('../../scan/scanController');
|
|
3
|
-
const { formatScanOutput } = require('../../scan/scan');
|
|
4
|
-
const { scanUsageGuide } = require('../../scan/help');
|
|
5
2
|
const scanConfig = require('../../scan/scanConfig');
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
3
|
+
const { startScan } = require('../../scan/scanController');
|
|
4
|
+
const { saveScanFile } = require('../../utils/saveFile');
|
|
5
|
+
const { ScanResultsModel } = require('../../scan/models/scanResultsModel');
|
|
6
|
+
const { formatScanOutput } = require('../../scan/formatScanOutput');
|
|
7
|
+
const { processSca } = require('./sca/scaAnalysis');
|
|
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
|
-
|
|
10
|
+
if (config.experimental) {
|
|
11
|
+
await processSca(config);
|
|
12
|
+
}
|
|
13
|
+
let scanResults = new ScanResultsModel(await startScan(config));
|
|
16
14
|
if (scanResults) {
|
|
17
|
-
formatScanOutput(scanResults
|
|
15
|
+
formatScanOutput(scanResults);
|
|
18
16
|
}
|
|
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
|
-
}
|
|
17
|
+
if (config.save !== undefined) {
|
|
18
|
+
await saveScanFile(config, scanResults);
|
|
29
19
|
}
|
|
30
20
|
};
|
|
31
|
-
const printHelpMessage = () => {
|
|
32
|
-
console.log(scanUsageGuide);
|
|
33
|
-
};
|
|
34
21
|
module.exports = {
|
|
35
|
-
processScan
|
|
36
|
-
printHelpMessage
|
|
22
|
+
processScan
|
|
37
23
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const autoDetection = require('../../../scan/autoDetection');
|
|
3
|
+
const { javaAnalysis } = require('../../../scaAnalysis/java');
|
|
4
|
+
const { commonSendSnapShot } = require('../../../scaAnalysis/common/treeUpload');
|
|
5
|
+
const { manualDetectAuditFilesAndLanguages } = require('../../../scan/autoDetection');
|
|
6
|
+
const { dealWithNoAppId } = require('../../audit/auditController');
|
|
7
|
+
const { supportedLanguages: { JAVA } } = require('../../../audit/languageAnalysisEngine/constants');
|
|
8
|
+
const processSca = async (config) => {
|
|
9
|
+
let filesFound;
|
|
10
|
+
if (config.projectPath) {
|
|
11
|
+
filesFound = await manualDetectAuditFilesAndLanguages(config.projectPath);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config);
|
|
15
|
+
}
|
|
16
|
+
let messageToSend = undefined;
|
|
17
|
+
if (filesFound.length === 1) {
|
|
18
|
+
switch (Object.keys(filesFound[0])[0]) {
|
|
19
|
+
case JAVA:
|
|
20
|
+
messageToSend = await javaAnalysis(config, filesFound[0]);
|
|
21
|
+
config.language = JAVA;
|
|
22
|
+
break;
|
|
23
|
+
default:
|
|
24
|
+
console.log('language detected not supported');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (!config.applicationId) {
|
|
28
|
+
config.applicationId = await dealWithNoAppId(config);
|
|
29
|
+
}
|
|
30
|
+
console.log('processing dependencies');
|
|
31
|
+
const response = await commonSendSnapShot(messageToSend, config);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
if (filesFound.length === 0) {
|
|
35
|
+
console.log('no compatible dependency files detected. Continuing...');
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
console.log('multiple language files detected, please use --project-path to specify a directory or the file where dependencies are declared');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
module.exports = {
|
|
43
|
+
processSca
|
|
44
|
+
};
|
|
@@ -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,27 @@ 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
|
+
}
|
|
143
150
|
const options = _.cloneDeep(this.requestOptions);
|
|
144
151
|
let url = createSnapshotURL(config);
|
|
145
152
|
options.url = url;
|
|
146
153
|
options.body = requestBody;
|
|
147
154
|
return requestUtils.sendRequest({ method: 'post', options });
|
|
148
155
|
};
|
|
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) {
|
|
156
|
+
HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
|
|
156
157
|
const options = _.cloneDeep(this.requestOptions);
|
|
157
|
-
|
|
158
|
-
|
|
158
|
+
if (config.ignoreDev) {
|
|
159
|
+
options.url = createSpecificReportWithProdUrl(config, reportId);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
options.url = createSpecificReportUrl(config, reportId);
|
|
163
|
+
}
|
|
159
164
|
return requestUtils.sendRequest({ method: 'get', options });
|
|
160
165
|
};
|
|
161
|
-
HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(
|
|
166
|
+
HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(config, requestBody) {
|
|
162
167
|
const options = _.cloneDeep(this.requestOptions);
|
|
163
|
-
|
|
164
|
-
options.url = url;
|
|
168
|
+
options.url = createLibraryVulnerabilitiesUrl(config);
|
|
165
169
|
options.body = requestBody;
|
|
166
170
|
return requestUtils.sendRequest({ method: 'put', options });
|
|
167
171
|
};
|
|
@@ -171,12 +175,6 @@ HTTPClient.prototype.getAppId = function getAppId(config) {
|
|
|
171
175
|
options.url = url;
|
|
172
176
|
return requestUtils.sendRequest({ method: 'get', options });
|
|
173
177
|
};
|
|
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
178
|
function getServerlessHost(config = {}) {
|
|
181
179
|
const originalHost = config?.host || config?.get('host');
|
|
182
180
|
const host = originalHost?.endsWith('/')
|
|
@@ -224,6 +222,11 @@ HTTPClient.prototype.checkLibrary = function checkLibrary(data) {
|
|
|
224
222
|
options.body = data;
|
|
225
223
|
return requestUtils.sendRequest({ method: 'post', options });
|
|
226
224
|
};
|
|
225
|
+
HTTPClient.prototype.getSbom = function getSbom(config) {
|
|
226
|
+
const options = _.cloneDeep(this.requestOptions);
|
|
227
|
+
options.url = createSbomCycloneDXUrl(config);
|
|
228
|
+
return requestUtils.sendRequest({ method: 'get', options });
|
|
229
|
+
};
|
|
227
230
|
const createGetScanIdURL = config => {
|
|
228
231
|
return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/`;
|
|
229
232
|
};
|
|
@@ -263,18 +266,18 @@ const createAppNameUrl = config => {
|
|
|
263
266
|
function createLibraryVulnerabilitiesUrl(config) {
|
|
264
267
|
return `${config.host}/Contrast/api/ng/${config.organizationId}/libraries/artifactsByGroupNameVersion`;
|
|
265
268
|
}
|
|
266
|
-
function createReportUrl(config) {
|
|
267
|
-
return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports`;
|
|
268
|
-
}
|
|
269
269
|
function createSpecificReportUrl(config, reportId) {
|
|
270
|
-
return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}
|
|
270
|
+
return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/reports/${reportId}`;
|
|
271
|
+
}
|
|
272
|
+
function createSpecificReportWithProdUrl(config, reportId) {
|
|
273
|
+
return createSpecificReportUrl(config, reportId).concat(`?nodesToInclude=PROD`);
|
|
271
274
|
}
|
|
272
275
|
function createDataUrl() {
|
|
273
276
|
return `https://ardy.contrastsecurity.com/production`;
|
|
274
277
|
}
|
|
275
|
-
|
|
276
|
-
return `${
|
|
277
|
-
}
|
|
278
|
+
function createSbomCycloneDXUrl(config) {
|
|
279
|
+
return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/cyclonedx`;
|
|
280
|
+
}
|
|
278
281
|
module.exports = HTTPClient;
|
|
279
282
|
module.exports.pollForAuthUrl = pollForAuthUrl;
|
|
280
283
|
module.exports.getServerlessHost = getServerlessHost;
|