@contrast/contrast 1.0.10 → 1.0.13
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/README.md +1 -1
- package/dist/audit/{languageAnalysisEngine/report → report}/commonReportingFunctions.js +56 -35
- package/dist/audit/report/models/reportGuidanceModel.js +6 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportLibraryModel.js +0 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportListModel.js +0 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportOutputModel.js +1 -2
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportSeverityModel.js +0 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/severityCountModel.js +1 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/reportingFeature.js +12 -8
- package/dist/audit/{languageAnalysisEngine/report → report}/utils/reportUtils.js +3 -4
- package/dist/commands/audit/auditConfig.js +3 -3
- package/dist/commands/audit/help.js +3 -1
- package/dist/commands/audit/processAudit.js +14 -2
- package/dist/commands/auth/auth.js +1 -1
- package/dist/commands/config/config.js +2 -2
- package/dist/commands/scan/processScan.js +20 -4
- package/dist/commands/scan/sca/scaAnalysis.js +15 -5
- package/dist/common/HTTPClient.js +39 -2
- package/dist/common/commonHelp.js +19 -0
- package/dist/common/fail.js +70 -0
- package/dist/common/versionChecker.js +14 -6
- package/dist/constants/constants.js +2 -2
- package/dist/constants/locales.js +15 -5
- package/dist/constants.js +42 -5
- package/dist/index.js +6 -3
- package/dist/lambda/help.js +2 -3
- package/dist/lambda/lambda.js +7 -0
- package/dist/scaAnalysis/common/scaParserForGoAndJava.js +32 -0
- package/dist/scaAnalysis/common/scaServicesUpload.js +52 -0
- package/dist/scaAnalysis/common/treeUpload.js +20 -5
- package/dist/scaAnalysis/dotnet/analysis.js +15 -3
- package/dist/scaAnalysis/go/goAnalysis.js +8 -2
- package/dist/scaAnalysis/java/analysis.js +10 -6
- package/dist/scaAnalysis/java/index.js +7 -1
- package/dist/scaAnalysis/java/javaBuildDepsParser.js +19 -3
- package/dist/scaAnalysis/javascript/index.js +4 -0
- package/dist/scaAnalysis/javascript/scaServiceParser.js +109 -0
- package/dist/scaAnalysis/php/analysis.js +1 -1
- package/dist/scaAnalysis/php/index.js +12 -6
- package/dist/scaAnalysis/php/phpNewServicesMapper.js +62 -0
- package/dist/scaAnalysis/python/analysis.js +43 -5
- package/dist/scaAnalysis/python/index.js +7 -2
- package/dist/scaAnalysis/ruby/analysis.js +116 -9
- package/dist/scaAnalysis/ruby/index.js +6 -1
- package/dist/scan/formatScanOutput.js +6 -5
- package/dist/scan/help.js +2 -3
- package/dist/scan/populateProjectIdAndProjectName.js +5 -0
- package/dist/scan/scan.js +4 -0
- package/dist/scan/scanConfig.js +4 -4
- package/dist/scan/scanResults.js +46 -3
- package/dist/telemetry/telemetry.js +137 -0
- package/dist/{audit/languageAnalysisEngine/util → utils}/capabilities.js +0 -0
- package/dist/{audit/languageAnalysisEngine/util → utils}/generalAPI.js +14 -5
- package/dist/utils/getConfig.js +2 -4
- package/dist/utils/parsedCLIOptions.js +3 -1
- package/dist/utils/requestUtils.js +7 -1
- package/package.json +4 -2
- package/src/audit/{languageAnalysisEngine/report → report}/commonReportingFunctions.ts +80 -44
- package/src/audit/report/models/reportGuidanceModel.ts +5 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportLibraryModel.ts +0 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportListModel.ts +0 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportOutputModel.ts +1 -7
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportSeverityModel.ts +0 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/severityCountModel.ts +2 -0
- package/src/audit/{languageAnalysisEngine/report → report}/reportingFeature.ts +16 -9
- package/src/audit/{languageAnalysisEngine/report → report}/utils/reportUtils.ts +4 -4
- package/src/commands/audit/auditConfig.ts +10 -3
- package/src/commands/audit/help.ts +3 -1
- package/src/commands/audit/processAudit.ts +24 -2
- package/src/commands/auth/auth.js +3 -1
- package/src/commands/config/config.js +4 -2
- package/src/commands/scan/processScan.js +32 -4
- package/src/commands/scan/sca/scaAnalysis.js +23 -5
- package/src/common/HTTPClient.js +59 -2
- package/src/common/commonHelp.ts +13 -0
- package/src/common/fail.js +79 -0
- package/src/common/versionChecker.ts +18 -8
- package/src/constants/constants.js +2 -2
- package/src/constants/locales.js +19 -7
- package/src/constants.js +46 -6
- package/src/index.ts +18 -4
- package/src/lambda/help.ts +2 -3
- package/src/lambda/lambda.ts +12 -0
- package/src/scaAnalysis/common/scaParserForGoAndJava.js +41 -0
- package/src/scaAnalysis/common/scaServicesUpload.js +54 -0
- package/src/scaAnalysis/common/treeUpload.js +21 -5
- package/src/scaAnalysis/dotnet/analysis.js +21 -3
- package/src/scaAnalysis/go/goAnalysis.js +9 -2
- package/src/scaAnalysis/java/analysis.js +11 -6
- package/src/scaAnalysis/java/index.js +9 -1
- package/src/scaAnalysis/java/javaBuildDepsParser.js +25 -6
- package/src/scaAnalysis/javascript/index.js +4 -0
- package/src/scaAnalysis/javascript/scaServiceParser.js +145 -0
- package/src/scaAnalysis/php/analysis.js +1 -1
- package/src/scaAnalysis/php/index.js +12 -6
- package/src/scaAnalysis/php/phpNewServicesMapper.js +77 -0
- package/src/scaAnalysis/python/analysis.js +49 -5
- package/src/scaAnalysis/python/index.js +7 -2
- package/src/scaAnalysis/ruby/analysis.js +149 -9
- package/src/scaAnalysis/ruby/index.js +6 -1
- package/src/scan/formatScanOutput.ts +7 -5
- package/src/scan/help.js +2 -3
- package/src/scan/populateProjectIdAndProjectName.js +5 -1
- package/src/scan/scan.ts +4 -0
- package/src/scan/scanConfig.js +6 -4
- package/src/scan/scanResults.js +52 -3
- package/src/telemetry/telemetry.ts +154 -0
- package/src/{audit/languageAnalysisEngine/util → utils}/capabilities.js +0 -0
- package/src/{audit/languageAnalysisEngine/util → utils}/generalAPI.js +16 -6
- package/src/utils/getConfig.ts +2 -11
- package/src/utils/parsedCLIOptions.js +14 -1
- package/src/utils/requestUtils.js +8 -1
package/README.md
CHANGED
|
@@ -3,22 +3,29 @@ 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.getNumOfAndSeverityType = exports.buildFormattedHeaderNum = exports.gatherRemediationAdvice = exports.buildBody = exports.buildHeader = exports.printFormattedOutput = exports.printVulnerabilityResponse = exports.getReport = exports.
|
|
7
|
-
const commonApi_1 = require("
|
|
6
|
+
exports.getNumOfAndSeverityType = exports.buildFormattedHeaderNum = exports.gatherRemediationAdvice = exports.buildBody = exports.buildHeader = exports.printFormattedOutput = exports.printVulnerabilityResponse = exports.getReport = exports.createSummaryMessageBottom = exports.createSummaryMessageTop = void 0;
|
|
7
|
+
const commonApi_1 = require("../../utils/commonApi");
|
|
8
8
|
const reportListModel_1 = require("./models/reportListModel");
|
|
9
9
|
const lodash_1 = require("lodash");
|
|
10
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
11
|
const reportUtils_1 = require("./utils/reportUtils");
|
|
12
12
|
const severityCountModel_1 = require("./models/severityCountModel");
|
|
13
13
|
const reportOutputModel_1 = require("./models/reportOutputModel");
|
|
14
|
-
const constants_1 = require("
|
|
14
|
+
const constants_1 = require("../../constants/constants");
|
|
15
15
|
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
16
|
-
const
|
|
16
|
+
const reportGuidanceModel_1 = require("./models/reportGuidanceModel");
|
|
17
|
+
const createSummaryMessageTop = (numberOfVulnerableLibraries, numberOfCves) => {
|
|
17
18
|
numberOfVulnerableLibraries === 1
|
|
18
19
|
? console.log(`Found 1 vulnerable library containing ${numberOfCves} CVE`)
|
|
19
20
|
: console.log(`Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVEs`);
|
|
20
21
|
};
|
|
21
|
-
exports.
|
|
22
|
+
exports.createSummaryMessageTop = createSummaryMessageTop;
|
|
23
|
+
const createSummaryMessageBottom = (numberOfVulnerableLibraries) => {
|
|
24
|
+
numberOfVulnerableLibraries === 1
|
|
25
|
+
? console.log(`Found 1 vulnerable library`)
|
|
26
|
+
: console.log(`Found ${numberOfVulnerableLibraries} vulnerable libraries`);
|
|
27
|
+
};
|
|
28
|
+
exports.createSummaryMessageBottom = createSummaryMessageBottom;
|
|
22
29
|
const getReport = async (config, reportId) => {
|
|
23
30
|
const client = (0, commonApi_1.getHttpClient)(config);
|
|
24
31
|
return client
|
|
@@ -47,7 +54,7 @@ const printVulnerabilityResponse = (config, vulnerableLibraries, numberOfVulnera
|
|
|
47
54
|
};
|
|
48
55
|
exports.printVulnerabilityResponse = printVulnerabilityResponse;
|
|
49
56
|
const printFormattedOutput = (config, libraries, numberOfVulnerableLibraries, numberOfCves, guidance) => {
|
|
50
|
-
(0, exports.
|
|
57
|
+
(0, exports.createSummaryMessageTop)(numberOfVulnerableLibraries, numberOfCves);
|
|
51
58
|
console.log();
|
|
52
59
|
const report = new reportListModel_1.ReportList();
|
|
53
60
|
for (const library of libraries) {
|
|
@@ -92,24 +99,29 @@ const printFormattedOutput = (config, libraries, numberOfVulnerableLibraries, nu
|
|
|
92
99
|
colWidths: [12, 1, 100]
|
|
93
100
|
});
|
|
94
101
|
const header = buildHeader(highestSeverity, contrastHeaderNumCounter, libraryName, libraryVersion, numOfCVEs);
|
|
95
|
-
const advice = gatherRemediationAdvice(guidance,
|
|
102
|
+
const advice = gatherRemediationAdvice(guidance, libraryName, libraryVersion);
|
|
96
103
|
const body = buildBody(reportModel.cveArray, advice);
|
|
97
104
|
const reportOutputModel = new reportOutputModel_1.ReportOutputModel(header, body);
|
|
98
|
-
table.push(reportOutputModel.body.issueMessage, reportOutputModel.body.
|
|
105
|
+
table.push(reportOutputModel.body.issueMessage, reportOutputModel.body.adviceMessage);
|
|
99
106
|
console.log(reportOutputModel.header.vulnMessage, reportOutputModel.header.introducesMessage);
|
|
100
107
|
console.log(table.toString() + '\n');
|
|
101
108
|
}
|
|
102
|
-
(0, exports.
|
|
109
|
+
(0, exports.createSummaryMessageBottom)(numberOfVulnerableLibraries);
|
|
103
110
|
const { criticalMessage, highMessage, mediumMessage, lowMessage, noteMessage } = buildFooter(outputOrderedByLowestSeverityAndLowestNumOfCvesFirst);
|
|
104
111
|
console.log(`${criticalMessage} | ${highMessage} | ${mediumMessage} | ${lowMessage} | ${noteMessage}`);
|
|
112
|
+
if (config.host !== constants_1.CE_URL) {
|
|
113
|
+
console.log('\n' + chalk_1.default.bold('View your full dependency tree in Contrast:'));
|
|
114
|
+
console.log(`${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`);
|
|
115
|
+
}
|
|
105
116
|
};
|
|
106
117
|
exports.printFormattedOutput = printFormattedOutput;
|
|
107
118
|
function buildHeader(highestSeverity, contrastHeaderNum, libraryName, version, numOfCVEs) {
|
|
108
119
|
const vulnerabilityPluralised = numOfCVEs > 1 ? 'vulnerabilities' : 'vulnerability';
|
|
109
120
|
const formattedHeaderNum = buildFormattedHeaderNum(contrastHeaderNum);
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
121
|
+
const headerColour = chalk_1.default.hex(highestSeverity.outputColour);
|
|
122
|
+
const headerNumAndSeverity = headerColour(`${formattedHeaderNum} - [${highestSeverity.severity}]`);
|
|
123
|
+
const libraryNameAndVersion = headerColour.bold(`${libraryName}-${version}`);
|
|
124
|
+
const vulnMessage = `${headerNumAndSeverity} ${libraryNameAndVersion}`;
|
|
113
125
|
const introducesMessage = `introduces ${numOfCVEs} ${vulnerabilityPluralised}`;
|
|
114
126
|
return new reportOutputModel_1.ReportOutputHeaderModel(vulnMessage, introducesMessage);
|
|
115
127
|
}
|
|
@@ -125,29 +137,27 @@ function buildBody(cveArray, advice) {
|
|
|
125
137
|
cveMessages.push(builtMessage);
|
|
126
138
|
});
|
|
127
139
|
const numAndSeverityType = getNumOfAndSeverityType(cveArray);
|
|
128
|
-
const issueMessage = [
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
140
|
+
const issueMessage = [
|
|
141
|
+
chalk_1.default.bold('Issue'),
|
|
142
|
+
':',
|
|
143
|
+
`${numAndSeverityType} ${cveMessages.join(', ')}`
|
|
144
|
+
];
|
|
145
|
+
const minOrMax = advice.maximum ? advice.maximum : advice.minimum;
|
|
146
|
+
const displayAdvice = minOrMax
|
|
147
|
+
? `Change to version ${chalk_1.default.bold(minOrMax)}`
|
|
148
|
+
: 'No recommendation is available according to our data. Upgrade to the latest stable is the best advice we can give.';
|
|
133
149
|
const adviceMessage = [chalk_1.default.bold('Advice'), ':', displayAdvice];
|
|
134
|
-
return new reportOutputModel_1.ReportOutputBodyModel(issueMessage,
|
|
150
|
+
return new reportOutputModel_1.ReportOutputBodyModel(issueMessage, adviceMessage);
|
|
135
151
|
}
|
|
136
152
|
exports.buildBody = buildBody;
|
|
137
|
-
function gatherRemediationAdvice(guidance,
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
maximum: undefined,
|
|
141
|
-
latest: undefined
|
|
142
|
-
};
|
|
143
|
-
const data = guidance[reportModel.compositeKey.libraryName +
|
|
144
|
-
'@' +
|
|
145
|
-
reportModel.compositeKey.libraryVersion];
|
|
153
|
+
function gatherRemediationAdvice(guidance, libraryName, libraryVersion) {
|
|
154
|
+
const guidanceModel = new reportGuidanceModel_1.ReportGuidanceModel();
|
|
155
|
+
const data = guidance[libraryName + '@' + libraryVersion];
|
|
146
156
|
if (data) {
|
|
147
|
-
|
|
148
|
-
|
|
157
|
+
guidanceModel.minimum = data.minUpgradeVersion;
|
|
158
|
+
guidanceModel.maximum = data.maxUpgradeVersion;
|
|
149
159
|
}
|
|
150
|
-
return
|
|
160
|
+
return guidanceModel;
|
|
151
161
|
}
|
|
152
162
|
exports.gatherRemediationAdvice = gatherRemediationAdvice;
|
|
153
163
|
function buildFormattedHeaderNum(contrastHeaderNum) {
|
|
@@ -156,11 +166,22 @@ function buildFormattedHeaderNum(contrastHeaderNum) {
|
|
|
156
166
|
exports.buildFormattedHeaderNum = buildFormattedHeaderNum;
|
|
157
167
|
function getNumOfAndSeverityType(cveArray) {
|
|
158
168
|
const { critical, high, medium, low, note } = (0, reportUtils_1.severityCountAllCVEs)(cveArray, new severityCountModel_1.SeverityCountModel());
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
const
|
|
162
|
-
const
|
|
163
|
-
const
|
|
169
|
+
const criticalNumCheck = critical > 0;
|
|
170
|
+
const highNumCheck = high > 0;
|
|
171
|
+
const highDivider = highNumCheck ? '|' : '';
|
|
172
|
+
const mediumNumCheck = medium > 0;
|
|
173
|
+
const mediumDivider = mediumNumCheck ? '|' : '';
|
|
174
|
+
const lowNumCheck = low > 0;
|
|
175
|
+
const lowDivider = lowNumCheck ? '|' : '';
|
|
176
|
+
const noteNumCheck = low > 0;
|
|
177
|
+
const noteDivider = noteNumCheck ? '|' : '';
|
|
178
|
+
const criticalMessage = criticalNumCheck
|
|
179
|
+
? `${critical} Critical ${highDivider}`
|
|
180
|
+
: '';
|
|
181
|
+
const highMessage = highNumCheck ? `${high} High ${mediumDivider}` : '';
|
|
182
|
+
const mediumMessage = mediumNumCheck ? `${medium} Medium ${lowDivider}` : '';
|
|
183
|
+
const lowMessage = lowNumCheck ? `${low} Low ${noteDivider}` : '';
|
|
184
|
+
const noteMessage = noteNumCheck ? `${note} Note` : '';
|
|
164
185
|
return `${criticalMessage} ${highMessage} ${mediumMessage} ${lowMessage} ${noteMessage}`
|
|
165
186
|
.replace(/\s+/g, ' ')
|
|
166
187
|
.trim();
|
|
File without changes
|
|
File without changes
|
|
@@ -16,9 +16,8 @@ class ReportOutputHeaderModel {
|
|
|
16
16
|
}
|
|
17
17
|
exports.ReportOutputHeaderModel = ReportOutputHeaderModel;
|
|
18
18
|
class ReportOutputBodyModel {
|
|
19
|
-
constructor(issueMessage,
|
|
19
|
+
constructor(issueMessage, adviceMessage) {
|
|
20
20
|
this.issueMessage = issueMessage;
|
|
21
|
-
this.issueMessageCves = issueMessageCves;
|
|
22
21
|
this.adviceMessage = adviceMessage;
|
|
23
22
|
}
|
|
24
23
|
}
|
|
File without changes
|
|
@@ -31,7 +31,9 @@ const commonReportingFunctions_1 = require("./commonReportingFunctions");
|
|
|
31
31
|
const reportUtils_1 = require("./utils/reportUtils");
|
|
32
32
|
const i18n_1 = __importDefault(require("i18n"));
|
|
33
33
|
const chalk_1 = __importDefault(require("chalk"));
|
|
34
|
-
const constants = __importStar(require("
|
|
34
|
+
const constants = __importStar(require("../../constants/constants"));
|
|
35
|
+
const severityCountModel_1 = require("./models/severityCountModel");
|
|
36
|
+
const common = __importStar(require("../../common/fail"));
|
|
35
37
|
function convertKeysToStandardFormat(config, guidance) {
|
|
36
38
|
let convertedGuidance = guidance;
|
|
37
39
|
switch (config.language) {
|
|
@@ -70,16 +72,16 @@ function formatVulnerabilityOutput(libraryVulnerabilityResponse, id, config, rem
|
|
|
70
72
|
console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundGoodWork'));
|
|
71
73
|
console.log(chalk_1.default.bold(`Found ${numberOfVulnerableLibraries} vulnerabilities`));
|
|
72
74
|
console.log(i18n_1.default.__('foundDetailedVulnerabilities', String(0), String(0), String(0), String(0), String(0)));
|
|
75
|
+
return [false, 0, [new severityCountModel_1.SeverityCountModel()]];
|
|
73
76
|
}
|
|
74
77
|
else {
|
|
75
78
|
let numberOfCves = 0;
|
|
76
79
|
vulnerableLibraries.forEach(lib => (numberOfCves += lib.cveArray.length));
|
|
77
80
|
const hasSomeVulnerabilitiesReported = (0, commonReportingFunctions_1.printVulnerabilityResponse)(config, vulnerableLibraries, numberOfVulnerableLibraries, numberOfCves, guidance);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
];
|
|
81
|
+
let severityCount = new severityCountModel_1.SeverityCountModel();
|
|
82
|
+
severityCount = (0, reportUtils_1.severityCountAllLibraries)(vulnerableLibraries, severityCount);
|
|
83
|
+
severityCount.total = severityCount.getTotal;
|
|
84
|
+
return [hasSomeVulnerabilitiesReported, numberOfCves, severityCount];
|
|
83
85
|
}
|
|
84
86
|
}
|
|
85
87
|
exports.formatVulnerabilityOutput = formatVulnerabilityOutput;
|
|
@@ -87,10 +89,12 @@ async function vulnerabilityReportV2(config, reportId) {
|
|
|
87
89
|
console.log();
|
|
88
90
|
const reportResponse = await (0, commonReportingFunctions_1.getReport)(config, reportId);
|
|
89
91
|
if (reportResponse !== undefined) {
|
|
90
|
-
|
|
91
|
-
formatVulnerabilityOutput(reportResponse.vulnerabilities, config.applicationId, config, reportResponse.remediationGuidance
|
|
92
|
+
let output = formatVulnerabilityOutput(reportResponse.vulnerabilities, config.applicationId, config, reportResponse.remediationGuidance
|
|
92
93
|
? reportResponse.remediationGuidance
|
|
93
94
|
: {});
|
|
95
|
+
if (config.fail) {
|
|
96
|
+
common.processFail(config, output[2]);
|
|
97
|
+
}
|
|
94
98
|
}
|
|
95
99
|
}
|
|
96
100
|
exports.vulnerabilityReportV2 = vulnerabilityReportV2;
|
|
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.countVulnerableLibrariesBySeverity = exports.findNameAndVersion = exports.severityCountSingleCVE = exports.severityCountAllCVEs = exports.severityCountAllLibraries = exports.convertGenericToTypedLibraryVulns = exports.findCVESeverity = exports.findCVESeveritiesAndOrderByHighestPriority = exports.findHighestSeverityCVE = void 0;
|
|
7
7
|
const reportLibraryModel_1 = require("../models/reportLibraryModel");
|
|
8
8
|
const reportSeverityModel_1 = require("../models/reportSeverityModel");
|
|
9
|
-
const constants_1 = __importDefault(require("
|
|
10
|
-
const constants_2 = require("
|
|
9
|
+
const constants_1 = __importDefault(require("../../../constants/constants"));
|
|
10
|
+
const constants_2 = require("../../../constants/constants");
|
|
11
11
|
const lodash_1 = require("lodash");
|
|
12
12
|
const severityCountModel_1 = require("../models/severityCountModel");
|
|
13
13
|
const { supportedLanguages: { GO } } = constants_1.default;
|
|
@@ -46,8 +46,7 @@ function convertGenericToTypedLibraryVulns(libraries) {
|
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
exports.convertGenericToTypedLibraryVulns = convertGenericToTypedLibraryVulns;
|
|
49
|
-
function severityCountAllLibraries(vulnerableLibraries) {
|
|
50
|
-
const severityCount = new severityCountModel_1.SeverityCountModel();
|
|
49
|
+
function severityCountAllLibraries(vulnerableLibraries, severityCount) {
|
|
51
50
|
vulnerableLibraries.forEach(lib => severityCountAllCVEs(lib.cveArray, severityCount));
|
|
52
51
|
return severityCount;
|
|
53
52
|
}
|
|
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.getAuditConfig = void 0;
|
|
7
7
|
const paramHandler_1 = __importDefault(require("../../utils/paramsUtil/paramHandler"));
|
|
8
8
|
const constants_1 = __importDefault(require("../../constants"));
|
|
9
|
-
const parsedCLIOptions_1 =
|
|
10
|
-
const getAuditConfig = (argv) => {
|
|
11
|
-
const auditParameters = parsedCLIOptions_1.
|
|
9
|
+
const parsedCLIOptions_1 = require("../../utils/parsedCLIOptions");
|
|
10
|
+
const getAuditConfig = async (contrastConf, command, argv) => {
|
|
11
|
+
const auditParameters = await (0, parsedCLIOptions_1.getCommandLineArgsCustom)(contrastConf, command, argv, constants_1.default.commandLineDefinitions.auditOptionDefinitions);
|
|
12
12
|
const paramsAuth = paramHandler_1.default.getAuth(auditParameters);
|
|
13
13
|
return { ...paramsAuth, ...auditParameters };
|
|
14
14
|
};
|
|
@@ -7,6 +7,7 @@ exports.auditUsageGuide = void 0;
|
|
|
7
7
|
const command_line_usage_1 = __importDefault(require("command-line-usage"));
|
|
8
8
|
const i18n_1 = __importDefault(require("i18n"));
|
|
9
9
|
const constants_1 = __importDefault(require("../../constants"));
|
|
10
|
+
const commonHelp_1 = require("../../common/commonHelp");
|
|
10
11
|
const auditUsageGuide = (0, command_line_usage_1.default)([
|
|
11
12
|
{
|
|
12
13
|
header: i18n_1.default.__('auditHeader'),
|
|
@@ -53,6 +54,7 @@ const auditUsageGuide = (0, command_line_usage_1.default)([
|
|
|
53
54
|
'app-groups',
|
|
54
55
|
'metadata'
|
|
55
56
|
]
|
|
56
|
-
}
|
|
57
|
+
},
|
|
58
|
+
(0, commonHelp_1.commonHelpLinks)()
|
|
57
59
|
]);
|
|
58
60
|
exports.auditUsageGuide = auditUsageGuide;
|
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.processAudit = void 0;
|
|
4
7
|
const auditConfig_1 = require("./auditConfig");
|
|
5
8
|
const help_1 = require("./help");
|
|
6
9
|
const scaAnalysis_1 = require("../scan/sca/scaAnalysis");
|
|
7
|
-
const
|
|
10
|
+
const telemetry_1 = require("../../telemetry/telemetry");
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
const processAudit = async (contrastConf, argv) => {
|
|
8
13
|
if (argv.indexOf('--help') != -1) {
|
|
9
14
|
printHelpMessage();
|
|
10
15
|
process.exit(0);
|
|
11
16
|
}
|
|
12
|
-
const config = (0, auditConfig_1.getAuditConfig)(argv);
|
|
17
|
+
const config = await (0, auditConfig_1.getAuditConfig)(contrastConf, 'audit', argv);
|
|
13
18
|
await (0, scaAnalysis_1.processSca)(config);
|
|
19
|
+
postRunMessage();
|
|
20
|
+
await (0, telemetry_1.sendTelemetryConfigAsObject)(config, 'audit', argv, 'SUCCESS', config.language);
|
|
14
21
|
};
|
|
15
22
|
exports.processAudit = processAudit;
|
|
16
23
|
const printHelpMessage = () => {
|
|
17
24
|
console.log(help_1.auditUsageGuide);
|
|
18
25
|
};
|
|
26
|
+
const postRunMessage = () => {
|
|
27
|
+
console.log('\n' + chalk_1.default.underline.bold('Other Codesec Features:'));
|
|
28
|
+
console.log("'contrast scan' to run CodeSec’s industry leading SAST scanner");
|
|
29
|
+
console.log("'contrast lambda' to secure your AWS serverless functions\n");
|
|
30
|
+
};
|
|
@@ -11,7 +11,7 @@ const parsedCLIOptions = require('../../utils/parsedCLIOptions');
|
|
|
11
11
|
const constants = require('../../constants');
|
|
12
12
|
const commandLineUsage = require('command-line-usage');
|
|
13
13
|
const processAuth = async (argv, config) => {
|
|
14
|
-
let authParams = parsedCLIOptions.getCommandLineArgsCustom(argv, constants.commandLineDefinitions.authOptionDefinitions);
|
|
14
|
+
let authParams = await parsedCLIOptions.getCommandLineArgsCustom(config, 'auth', argv, constants.commandLineDefinitions.authOptionDefinitions);
|
|
15
15
|
if (authParams.help) {
|
|
16
16
|
console.log(authUsageGuide);
|
|
17
17
|
process.exit(0);
|
|
@@ -3,9 +3,9 @@ const parsedCLIOptions = require('../../utils/parsedCLIOptions');
|
|
|
3
3
|
const constants = require('../../constants');
|
|
4
4
|
const commandLineUsage = require('command-line-usage');
|
|
5
5
|
const i18n = require('i18n');
|
|
6
|
-
const processConfig = (argv, config) => {
|
|
6
|
+
const processConfig = async (argv, config) => {
|
|
7
7
|
try {
|
|
8
|
-
let configParams = parsedCLIOptions.getCommandLineArgsCustom(argv, constants.commandLineDefinitions.configOptionDefinitions);
|
|
8
|
+
let configParams = await parsedCLIOptions.getCommandLineArgsCustom(config, 'config', argv, constants.commandLineDefinitions.configOptionDefinitions);
|
|
9
9
|
if (configParams.help) {
|
|
10
10
|
console.log(configUsageGuide);
|
|
11
11
|
process.exit(0);
|
|
@@ -5,18 +5,34 @@ const { saveScanFile } = require('../../utils/saveFile');
|
|
|
5
5
|
const { ScanResultsModel } = require('../../scan/models/scanResultsModel');
|
|
6
6
|
const { formatScanOutput } = require('../../scan/formatScanOutput');
|
|
7
7
|
const { processSca } = require('./sca/scaAnalysis');
|
|
8
|
-
const
|
|
9
|
-
|
|
8
|
+
const common = require('../../common/fail');
|
|
9
|
+
const { sendTelemetryConfigAsObject } = require('../../telemetry/telemetry');
|
|
10
|
+
const chalk = require('chalk');
|
|
11
|
+
const generalAPI = require('../../utils/generalAPI');
|
|
12
|
+
const processScan = async (contrastConf, argv) => {
|
|
13
|
+
let config = await scanConfig.getScanConfig(contrastConf, 'scan', argv);
|
|
14
|
+
let output = undefined;
|
|
15
|
+
config.mode = await generalAPI.getMode(config);
|
|
10
16
|
if (config.experimental) {
|
|
11
|
-
await processSca(config);
|
|
17
|
+
await processSca(config, argv);
|
|
12
18
|
}
|
|
13
19
|
let scanResults = new ScanResultsModel(await startScan(config));
|
|
20
|
+
await sendTelemetryConfigAsObject(config, 'scan', argv, 'SUCCESS', scanResults.scanDetail.language);
|
|
14
21
|
if (scanResults.scanResultsInstances !== undefined) {
|
|
15
|
-
formatScanOutput(scanResults);
|
|
22
|
+
output = formatScanOutput(scanResults);
|
|
16
23
|
}
|
|
17
24
|
if (config.save !== undefined) {
|
|
18
25
|
await saveScanFile(config, scanResults);
|
|
19
26
|
}
|
|
27
|
+
if (config.fail) {
|
|
28
|
+
common.processFail(config, output);
|
|
29
|
+
}
|
|
30
|
+
postRunMessage();
|
|
31
|
+
};
|
|
32
|
+
const postRunMessage = () => {
|
|
33
|
+
console.log('\n' + chalk.underline.bold('Other Codesec Features:'));
|
|
34
|
+
console.log("'contrast audit' to find vulnerabilities in your open source dependencies");
|
|
35
|
+
console.log("'contrast lambda' to secure your AWS serverless functions\n");
|
|
20
36
|
};
|
|
21
37
|
module.exports = {
|
|
22
38
|
processScan
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const autoDetection = require('../../../scan/autoDetection');
|
|
3
3
|
const javaAnalysis = require('../../../scaAnalysis/java');
|
|
4
4
|
const treeUpload = require('../../../scaAnalysis/common/treeUpload');
|
|
5
|
+
const scaUpload = require('../../../scaAnalysis/common/scaServicesUpload');
|
|
5
6
|
const auditController = require('../../audit/auditController');
|
|
6
7
|
const { supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET } } = require('../../../constants/constants');
|
|
7
8
|
const goAnalysis = require('../../../scaAnalysis/go/goAnalysis');
|
|
@@ -12,23 +13,30 @@ const javascriptAnalysis = require('../../../scaAnalysis/javascript');
|
|
|
12
13
|
const { pollForSnapshotCompletition } = require('../../../audit/languageAnalysisEngine/sendSnapshot');
|
|
13
14
|
const { returnOra, startSpinner, succeedSpinner } = require('../../../utils/oraWrapper');
|
|
14
15
|
const i18n = require('i18n');
|
|
15
|
-
const { vulnerabilityReportV2 } = require('../../../audit/
|
|
16
|
+
const { vulnerabilityReportV2 } = require('../../../audit/report/reportingFeature');
|
|
16
17
|
const auditSave = require('../../../audit/save');
|
|
17
18
|
const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet');
|
|
19
|
+
const { auditUsageGuide } = require('../../audit/help');
|
|
18
20
|
const rootFile = require('../../../audit/languageAnalysisEngine/getProjectRootFilenames');
|
|
19
21
|
const path = require('path');
|
|
22
|
+
const generalAPI = require('../../../utils/generalAPI');
|
|
20
23
|
const processSca = async (config) => {
|
|
24
|
+
config.mode = await generalAPI.getMode(config);
|
|
21
25
|
const startTime = performance.now();
|
|
22
26
|
let filesFound;
|
|
27
|
+
if (config.help) {
|
|
28
|
+
console.log(auditUsageGuide);
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
23
31
|
const projectStats = await rootFile.getProjectStats(config.file);
|
|
24
32
|
let pathWithFile = projectStats.isFile();
|
|
25
|
-
|
|
33
|
+
config.fileName = config.file;
|
|
26
34
|
config.file = pathWithFile
|
|
27
35
|
? rootFile.getDirectoryFromPathGiven(config.file).concat('/')
|
|
28
36
|
: config.file;
|
|
29
37
|
filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config.file);
|
|
30
38
|
if (filesFound.length > 1 && pathWithFile) {
|
|
31
|
-
filesFound = filesFound.filter(i => Object.values(i)[0].includes(path.basename(fileName)));
|
|
39
|
+
filesFound = filesFound.filter(i => Object.values(i)[0].includes(path.basename(config.fileName)));
|
|
32
40
|
}
|
|
33
41
|
let messageToSend = undefined;
|
|
34
42
|
if (filesFound.length === 1) {
|
|
@@ -49,7 +57,7 @@ const processSca = async (config) => {
|
|
|
49
57
|
messageToSend = rubyAnalysis(config, filesFound[0]);
|
|
50
58
|
config.language = RUBY;
|
|
51
59
|
break;
|
|
52
|
-
case
|
|
60
|
+
case PHP:
|
|
53
61
|
messageToSend = phpAnalysis.phpAnalysis(config, filesFound[0]);
|
|
54
62
|
config.language = PHP;
|
|
55
63
|
break;
|
|
@@ -89,7 +97,9 @@ const processSca = async (config) => {
|
|
|
89
97
|
throw new Error();
|
|
90
98
|
}
|
|
91
99
|
else {
|
|
92
|
-
throw new Error(
|
|
100
|
+
throw new Error(`multiple language files detected \n` +
|
|
101
|
+
JSON.stringify(filesFound) +
|
|
102
|
+
`\nplease use --file to audit one language only. Example: contrast audit --file package-lock.json`);
|
|
93
103
|
}
|
|
94
104
|
}
|
|
95
105
|
};
|
|
@@ -130,9 +130,9 @@ HTTPClient.prototype.getScanProjectById = function getScanProjectById(config) {
|
|
|
130
130
|
options.url = createScanProjectUrl(config);
|
|
131
131
|
return requestUtils.sendRequest({ method: 'get', options });
|
|
132
132
|
};
|
|
133
|
-
HTTPClient.prototype.getGlobalProperties = function getGlobalProperties() {
|
|
133
|
+
HTTPClient.prototype.getGlobalProperties = function getGlobalProperties(host) {
|
|
134
134
|
const options = _.cloneDeep(this.requestOptions);
|
|
135
|
-
let url = createGlobalPropertiesUrl(
|
|
135
|
+
let url = createGlobalPropertiesUrl(host);
|
|
136
136
|
options.url = url;
|
|
137
137
|
return requestUtils.sendRequest({ method: 'get', options });
|
|
138
138
|
};
|
|
@@ -166,6 +166,25 @@ HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
|
|
|
166
166
|
options.body = requestBody;
|
|
167
167
|
return requestUtils.sendRequest({ method: 'post', options });
|
|
168
168
|
};
|
|
169
|
+
HTTPClient.prototype.scaServiceIngest = function scaServiceIngest(requestBody, config) {
|
|
170
|
+
const options = _.cloneDeep(this.requestOptions);
|
|
171
|
+
let url = createScaServiceIngestURL(config);
|
|
172
|
+
options.url = url;
|
|
173
|
+
options.body = requestBody;
|
|
174
|
+
return requestUtils.sendRequest({ method: 'post', options });
|
|
175
|
+
};
|
|
176
|
+
HTTPClient.prototype.scaServiceReport = function scaServiceReport(config, reportId) {
|
|
177
|
+
const options = _.cloneDeep(this.requestOptions);
|
|
178
|
+
let url = createScaServiceReportURL(config, reportId);
|
|
179
|
+
options.url = url;
|
|
180
|
+
return requestUtils.sendRequest({ method: 'get', options });
|
|
181
|
+
};
|
|
182
|
+
HTTPClient.prototype.scaServiceReportStatus = function scaServiceReport(config, reportId) {
|
|
183
|
+
const options = _.cloneDeep(this.requestOptions);
|
|
184
|
+
let url = createScaServiceReportStatusURL(config, reportId);
|
|
185
|
+
options.url = url;
|
|
186
|
+
return requestUtils.sendRequest({ method: 'get', options });
|
|
187
|
+
};
|
|
169
188
|
HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
|
|
170
189
|
const options = _.cloneDeep(this.requestOptions);
|
|
171
190
|
if (config.ignoreDev) {
|
|
@@ -253,6 +272,12 @@ HTTPClient.prototype.getLatestVersion = function getLatestVersion() {
|
|
|
253
272
|
'https://pkg.contrastsecurity.com/artifactory/cli/latest-version.txt';
|
|
254
273
|
return requestUtils.sendRequest({ method: 'get', options });
|
|
255
274
|
};
|
|
275
|
+
HTTPClient.prototype.postTelemetry = function postTelemetry(config, requestBody) {
|
|
276
|
+
const options = _.cloneDeep(this.requestOptions);
|
|
277
|
+
options.url = createTelemetryEventUrl(config);
|
|
278
|
+
options.body = requestBody;
|
|
279
|
+
return requestUtils.sendRequest({ method: 'post', options });
|
|
280
|
+
};
|
|
256
281
|
HTTPClient.prototype.postAnalyticsFunction = function (config, provider, body) {
|
|
257
282
|
const url = createAnalyticsFunctionPostUrl(config, provider);
|
|
258
283
|
const options = { ...this.requestOptions, body, url };
|
|
@@ -295,6 +320,15 @@ const pollForAuthUrl = () => {
|
|
|
295
320
|
function createSnapshotURL(config) {
|
|
296
321
|
return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/snapshots`;
|
|
297
322
|
}
|
|
323
|
+
function createScaServiceReportURL(config, reportId) {
|
|
324
|
+
return ``;
|
|
325
|
+
}
|
|
326
|
+
function createScaServiceReportStatusURL(config, reportId) {
|
|
327
|
+
return ``;
|
|
328
|
+
}
|
|
329
|
+
function createScaServiceIngestURL(config) {
|
|
330
|
+
return ``;
|
|
331
|
+
}
|
|
298
332
|
const createAppCreateURL = config => {
|
|
299
333
|
return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/create`;
|
|
300
334
|
};
|
|
@@ -319,6 +353,9 @@ function createDataUrl() {
|
|
|
319
353
|
function createSbomUrl(config, type) {
|
|
320
354
|
return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/${type}`;
|
|
321
355
|
}
|
|
356
|
+
function createTelemetryEventUrl(config) {
|
|
357
|
+
return `${config.host}/Contrast/api/sast/organizations/${config.organizationId}/cli`;
|
|
358
|
+
}
|
|
322
359
|
module.exports = HTTPClient;
|
|
323
360
|
module.exports.pollForAuthUrl = pollForAuthUrl;
|
|
324
361
|
module.exports.getServerlessHost = getServerlessHost;
|
|
@@ -0,0 +1,19 @@
|
|
|
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.commonHelpLinks = void 0;
|
|
7
|
+
const i18n_1 = __importDefault(require("i18n"));
|
|
8
|
+
function commonHelpLinks() {
|
|
9
|
+
return {
|
|
10
|
+
header: i18n_1.default.__('commonHelpHeader'),
|
|
11
|
+
content: [
|
|
12
|
+
i18n_1.default.__('commonHelpCheckOutHeader') + i18n_1.default.__('commonHelpCheckOutText'),
|
|
13
|
+
i18n_1.default.__('commonHelpLearnMoreHeader') + i18n_1.default.__('commonHelpLearnMoreText'),
|
|
14
|
+
i18n_1.default.__('commonHelpJoinDiscussionHeader') +
|
|
15
|
+
i18n_1.default.__('commonHelpJoinDiscussionText')
|
|
16
|
+
]
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
exports.commonHelpLinks = commonHelpLinks;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const i18n = require('i18n');
|
|
3
|
+
const processFail = (config, reportResults) => {
|
|
4
|
+
if (config.severity !== undefined) {
|
|
5
|
+
if (reportResults[config.severity] !== undefined &&
|
|
6
|
+
isSeverityViolation(config.severity, reportResults)) {
|
|
7
|
+
failPipeline('failSeverityOptionErrorMessage');
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
if (config.severity === undefined && reportResults.total > 0) {
|
|
11
|
+
failPipeline('failThresholdOptionErrorMessage');
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const isSeverityViolation = (severity, reportResults) => {
|
|
15
|
+
let count = 0;
|
|
16
|
+
switch (severity) {
|
|
17
|
+
case 'critical':
|
|
18
|
+
count += reportResults.critical;
|
|
19
|
+
break;
|
|
20
|
+
case 'high':
|
|
21
|
+
count += reportResults.high + reportResults.critical;
|
|
22
|
+
break;
|
|
23
|
+
case 'medium':
|
|
24
|
+
count +=
|
|
25
|
+
reportResults.medium + reportResults.high + reportResults.critical;
|
|
26
|
+
break;
|
|
27
|
+
case 'low':
|
|
28
|
+
count +=
|
|
29
|
+
reportResults.high +
|
|
30
|
+
reportResults.critical +
|
|
31
|
+
reportResults.medium +
|
|
32
|
+
reportResults.low;
|
|
33
|
+
break;
|
|
34
|
+
case 'note':
|
|
35
|
+
if (reportResults.note == reportResults.total) {
|
|
36
|
+
count = 0;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
count = reportResults.total;
|
|
40
|
+
}
|
|
41
|
+
break;
|
|
42
|
+
default:
|
|
43
|
+
count = 0;
|
|
44
|
+
}
|
|
45
|
+
return count > 0;
|
|
46
|
+
};
|
|
47
|
+
const failPipeline = (message = '') => {
|
|
48
|
+
console.log('\n ******************************** ' +
|
|
49
|
+
i18n.__('snapshotFailureHeader') +
|
|
50
|
+
' *********************************\n' +
|
|
51
|
+
i18n.__(message));
|
|
52
|
+
process.exit(2);
|
|
53
|
+
};
|
|
54
|
+
const parseSeverity = severity => {
|
|
55
|
+
const severities = ['NOTE', 'LOW', 'MEDIUM', 'HIGH', 'CRITICAL'];
|
|
56
|
+
if (severities.includes(severity.toUpperCase())) {
|
|
57
|
+
return severity.toLowerCase();
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.log(severity +
|
|
61
|
+
' Not recognised as a severity type please use LOW, MEDIUM, HIGH, CRITICAL, NOTE');
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
module.exports = {
|
|
66
|
+
failPipeline,
|
|
67
|
+
processFail,
|
|
68
|
+
isSeverityViolation,
|
|
69
|
+
parseSeverity
|
|
70
|
+
};
|