@contrast/contrast 1.0.13 → 1.0.15

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.
Files changed (45) hide show
  1. package/dist/audit/report/commonReportingFunctions.js +175 -116
  2. package/dist/audit/report/models/reportSeverityModel.js +3 -3
  3. package/dist/audit/report/reportingFeature.js +1 -10
  4. package/dist/audit/report/utils/reportUtils.js +4 -4
  5. package/dist/audit/save.js +7 -2
  6. package/dist/commands/audit/help.js +3 -1
  7. package/dist/commands/scan/processScan.js +0 -6
  8. package/dist/commands/scan/sca/scaAnalysis.js +32 -15
  9. package/dist/common/HTTPClient.js +22 -3
  10. package/dist/common/errorHandling.js +1 -2
  11. package/dist/constants/constants.js +10 -2
  12. package/dist/constants/locales.js +17 -7
  13. package/dist/constants.js +31 -2
  14. package/dist/index.js +4 -2
  15. package/dist/lambda/lambda.js +1 -1
  16. package/dist/sbom/generateSbom.js +18 -1
  17. package/dist/scaAnalysis/common/auditReport.js +78 -0
  18. package/dist/scaAnalysis/common/scaServicesUpload.js +21 -13
  19. package/dist/scan/formatScanOutput.js +4 -29
  20. package/dist/utils/commonApi.js +1 -0
  21. package/dist/utils/settingsHelper.js +24 -0
  22. package/package.json +4 -1
  23. package/src/audit/report/commonReportingFunctions.js +432 -0
  24. package/src/audit/report/models/reportSeverityModel.ts +6 -6
  25. package/src/audit/report/reportingFeature.ts +2 -16
  26. package/src/audit/report/utils/reportUtils.ts +2 -8
  27. package/src/audit/save.js +14 -6
  28. package/src/commands/audit/help.ts +3 -1
  29. package/src/commands/scan/processScan.js +0 -8
  30. package/src/commands/scan/sca/scaAnalysis.js +52 -32
  31. package/src/common/HTTPClient.js +26 -3
  32. package/src/common/errorHandling.ts +1 -2
  33. package/src/constants/constants.js +12 -2
  34. package/src/constants/locales.js +19 -7
  35. package/src/constants.js +34 -2
  36. package/src/index.ts +4 -6
  37. package/src/lambda/lambda.ts +1 -1
  38. package/src/lambda/lambdaUtils.ts +1 -1
  39. package/src/sbom/generateSbom.ts +20 -0
  40. package/src/scaAnalysis/common/auditReport.js +108 -0
  41. package/src/scaAnalysis/common/scaServicesUpload.js +24 -14
  42. package/src/scan/formatScanOutput.ts +5 -42
  43. package/src/utils/commonApi.js +1 -0
  44. package/src/utils/settingsHelper.js +26 -0
  45. package/src/audit/report/commonReportingFunctions.ts +0 -355
@@ -1,72 +1,64 @@
1
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.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
- const reportListModel_1 = require("./models/reportListModel");
9
- const lodash_1 = require("lodash");
10
- const chalk_1 = __importDefault(require("chalk"));
11
- const reportUtils_1 = require("./utils/reportUtils");
12
- const severityCountModel_1 = require("./models/severityCountModel");
13
- const reportOutputModel_1 = require("./models/reportOutputModel");
14
- const constants_1 = require("../../constants/constants");
15
- const cli_table3_1 = __importDefault(require("cli-table3"));
16
- const reportGuidanceModel_1 = require("./models/reportGuidanceModel");
2
+ const commonApi = require('../../utils/commonApi');
3
+ const { ReportCompositeKey, ReportList, ReportModelStructure } = require('./models/reportListModel');
4
+ const { orderBy } = require('lodash');
5
+ const chalk = require('chalk');
6
+ const { countVulnerableLibrariesBySeverity, orderByHighestPriority, findHighestSeverityCVE, findNameAndVersion, severityCountAllCVEs, findCVESeverity } = require('./utils/reportUtils');
7
+ const { SeverityCountModel } = require('./models/severityCountModel');
8
+ const { ReportOutputBodyModel, ReportOutputHeaderModel, ReportOutputModel } = require('./models/reportOutputModel');
9
+ const { CE_URL, CRITICAL_COLOUR, HIGH_COLOUR, LOW_COLOUR, MEDIUM_COLOUR, NOTE_COLOUR } = require('../../constants/constants');
10
+ const Table = require('cli-table3');
11
+ const { ReportGuidanceModel } = require('./models/reportGuidanceModel');
12
+ const i18n = require('i18n');
17
13
  const createSummaryMessageTop = (numberOfVulnerableLibraries, numberOfCves) => {
18
14
  numberOfVulnerableLibraries === 1
19
15
  ? console.log(`Found 1 vulnerable library containing ${numberOfCves} CVE`)
20
16
  : console.log(`Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVEs`);
21
17
  };
22
- exports.createSummaryMessageTop = createSummaryMessageTop;
23
- const createSummaryMessageBottom = (numberOfVulnerableLibraries) => {
18
+ const createSummaryMessageBottom = numberOfVulnerableLibraries => {
24
19
  numberOfVulnerableLibraries === 1
25
- ? console.log(`Found 1 vulnerable library`)
26
- : console.log(`Found ${numberOfVulnerableLibraries} vulnerable libraries`);
20
+ ? console.log(`Found 1 vulnerability`)
21
+ : console.log(`Found ${numberOfVulnerableLibraries} vulnerabilities`);
27
22
  };
28
- exports.createSummaryMessageBottom = createSummaryMessageBottom;
29
23
  const getReport = async (config, reportId) => {
30
- const client = (0, commonApi_1.getHttpClient)(config);
24
+ const client = commonApi.getHttpClient(config);
31
25
  return client
32
26
  .getReportById(config, reportId)
33
- .then((res) => {
27
+ .then(res => {
34
28
  if (res.statusCode === 200) {
35
29
  return res.body;
36
30
  }
37
31
  else {
38
- console.log(JSON.stringify(res));
39
- (0, commonApi_1.handleResponseErrors)(res, 'report');
32
+ console.log(JSON.stringify(res.statusCode));
33
+ commonApi.handleResponseErrors(res, 'report');
40
34
  }
41
35
  })
42
- .catch((err) => {
36
+ .catch(err => {
43
37
  console.log(err);
44
38
  });
45
39
  };
46
- exports.getReport = getReport;
47
40
  const printVulnerabilityResponse = (config, vulnerableLibraries, numberOfVulnerableLibraries, numberOfCves, guidance) => {
48
41
  let hasSomeVulnerabilitiesReported = false;
49
- (0, exports.printFormattedOutput)(config, vulnerableLibraries, numberOfVulnerableLibraries, numberOfCves, guidance);
42
+ printFormattedOutput(config, vulnerableLibraries, numberOfVulnerableLibraries, numberOfCves, guidance);
50
43
  if (Object.keys(vulnerableLibraries).length > 0) {
51
44
  hasSomeVulnerabilitiesReported = true;
52
45
  }
53
46
  return hasSomeVulnerabilitiesReported;
54
47
  };
55
- exports.printVulnerabilityResponse = printVulnerabilityResponse;
56
48
  const printFormattedOutput = (config, libraries, numberOfVulnerableLibraries, numberOfCves, guidance) => {
57
- (0, exports.createSummaryMessageTop)(numberOfVulnerableLibraries, numberOfCves);
49
+ createSummaryMessageTop(numberOfVulnerableLibraries, numberOfCves);
58
50
  console.log();
59
- const report = new reportListModel_1.ReportList();
51
+ const report = new ReportList();
60
52
  for (const library of libraries) {
61
- const { name, version } = (0, reportUtils_1.findNameAndVersion)(library, config);
62
- const newOutputModel = new reportListModel_1.ReportModelStructure(new reportListModel_1.ReportCompositeKey(name, version, (0, reportUtils_1.findHighestSeverityCVE)(library.cveArray), (0, reportUtils_1.severityCountAllCVEs)(library.cveArray, new severityCountModel_1.SeverityCountModel()).getTotal), library.cveArray);
53
+ const { name, version } = findNameAndVersion(library, config);
54
+ const newOutputModel = new ReportModelStructure(new ReportCompositeKey(name, version, findHighestSeverityCVE(library.cveArray), severityCountAllCVEs(library.cveArray, new SeverityCountModel()).getTotal), library.cveArray);
63
55
  report.reportOutputList.push(newOutputModel);
64
56
  }
65
- const outputOrderedByLowestSeverityAndLowestNumOfCvesFirst = (0, lodash_1.orderBy)(report.reportOutputList, [
66
- (reportListItem) => {
57
+ const outputOrderedByLowestSeverityAndLowestNumOfCvesFirst = orderBy(report.reportOutputList, [
58
+ reportListItem => {
67
59
  return reportListItem.compositeKey.highestSeverity.priority;
68
60
  },
69
- (reportListItem) => {
61
+ reportListItem => {
70
62
  return reportListItem.compositeKey.numberOfSeverities;
71
63
  }
72
64
  ], ['asc', 'desc']);
@@ -75,83 +67,81 @@ const printFormattedOutput = (config, libraries, numberOfVulnerableLibraries, nu
75
67
  contrastHeaderNumCounter++;
76
68
  const { libraryName, libraryVersion, highestSeverity } = reportModel.compositeKey;
77
69
  const numOfCVEs = reportModel.cveArray.length;
78
- const table = new cli_table3_1.default({
79
- chars: {
80
- top: '',
81
- 'top-mid': '',
82
- 'top-left': '',
83
- 'top-right': '',
84
- bottom: '',
85
- 'bottom-mid': '',
86
- 'bottom-left': '',
87
- 'bottom-right': '',
88
- left: '',
89
- 'left-mid': '',
90
- mid: '',
91
- 'mid-mid': '',
92
- right: '',
93
- 'right-mid': '',
94
- middle: ' '
95
- },
96
- style: { 'padding-left': 0, 'padding-right': 0 },
97
- colAligns: ['right'],
98
- wordWrap: true,
99
- colWidths: [12, 1, 100]
100
- });
70
+ const table = getReportTable();
101
71
  const header = buildHeader(highestSeverity, contrastHeaderNumCounter, libraryName, libraryVersion, numOfCVEs);
102
72
  const advice = gatherRemediationAdvice(guidance, libraryName, libraryVersion);
103
73
  const body = buildBody(reportModel.cveArray, advice);
104
- const reportOutputModel = new reportOutputModel_1.ReportOutputModel(header, body);
74
+ const reportOutputModel = new ReportOutputModel(header, body);
105
75
  table.push(reportOutputModel.body.issueMessage, reportOutputModel.body.adviceMessage);
106
76
  console.log(reportOutputModel.header.vulnMessage, reportOutputModel.header.introducesMessage);
107
77
  console.log(table.toString() + '\n');
108
78
  }
109
- (0, exports.createSummaryMessageBottom)(numberOfVulnerableLibraries);
79
+ createSummaryMessageBottom(numberOfVulnerableLibraries);
110
80
  const { criticalMessage, highMessage, mediumMessage, lowMessage, noteMessage } = buildFooter(outputOrderedByLowestSeverityAndLowestNumOfCvesFirst);
111
81
  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:'));
82
+ if (config.host !== CE_URL) {
83
+ console.log('\n' + chalk.bold('View your full dependency tree in Contrast:'));
114
84
  console.log(`${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`);
115
85
  }
116
86
  };
117
- exports.printFormattedOutput = printFormattedOutput;
87
+ function getReportTable() {
88
+ return new Table({
89
+ chars: {
90
+ top: '',
91
+ 'top-mid': '',
92
+ 'top-left': '',
93
+ 'top-right': '',
94
+ bottom: '',
95
+ 'bottom-mid': '',
96
+ 'bottom-left': '',
97
+ 'bottom-right': '',
98
+ left: '',
99
+ 'left-mid': '',
100
+ mid: '',
101
+ 'mid-mid': '',
102
+ right: '',
103
+ 'right-mid': '',
104
+ middle: ' '
105
+ },
106
+ style: { 'padding-left': 0, 'padding-right': 0 },
107
+ colAligns: ['right'],
108
+ wordWrap: true,
109
+ colWidths: [12, 1, 100]
110
+ });
111
+ }
118
112
  function buildHeader(highestSeverity, contrastHeaderNum, libraryName, version, numOfCVEs) {
119
113
  const vulnerabilityPluralised = numOfCVEs > 1 ? 'vulnerabilities' : 'vulnerability';
120
114
  const formattedHeaderNum = buildFormattedHeaderNum(contrastHeaderNum);
121
- const headerColour = chalk_1.default.hex(highestSeverity.outputColour);
115
+ const headerColour = chalk.hex(highestSeverity.colour);
122
116
  const headerNumAndSeverity = headerColour(`${formattedHeaderNum} - [${highestSeverity.severity}]`);
123
117
  const libraryNameAndVersion = headerColour.bold(`${libraryName}-${version}`);
124
118
  const vulnMessage = `${headerNumAndSeverity} ${libraryNameAndVersion}`;
125
119
  const introducesMessage = `introduces ${numOfCVEs} ${vulnerabilityPluralised}`;
126
- return new reportOutputModel_1.ReportOutputHeaderModel(vulnMessage, introducesMessage);
120
+ return new ReportOutputHeaderModel(vulnMessage, introducesMessage);
127
121
  }
128
- exports.buildHeader = buildHeader;
129
122
  function buildBody(cveArray, advice) {
130
- const cveMessages = [];
131
- (0, reportUtils_1.findCVESeveritiesAndOrderByHighestPriority)(cveArray).forEach(reportSeverityModel => {
132
- const { outputColour, severity, cveName } = reportSeverityModel;
133
- const severityShorthand = chalk_1.default
134
- .hex(outputColour)
135
- .bold(`[${severity.charAt(0).toUpperCase()}]`);
136
- const builtMessage = severityShorthand + cveName;
137
- cveMessages.push(builtMessage);
138
- });
139
- const numAndSeverityType = getNumOfAndSeverityType(cveArray);
140
- const issueMessage = [
141
- chalk_1.default.bold('Issue'),
142
- ':',
143
- `${numAndSeverityType} ${cveMessages.join(', ')}`
144
- ];
123
+ let assignPriorityToVulns = cveArray.map(result => findCVESeverity(result));
124
+ const issueMessage = getIssueRow(assignPriorityToVulns);
145
125
  const minOrMax = advice.maximum ? advice.maximum : advice.minimum;
146
126
  const displayAdvice = minOrMax
147
- ? `Change to version ${chalk_1.default.bold(minOrMax)}`
127
+ ? `Change to version ${chalk.bold(minOrMax)}`
148
128
  : 'No recommendation is available according to our data. Upgrade to the latest stable is the best advice we can give.';
149
- const adviceMessage = [chalk_1.default.bold('Advice'), ':', displayAdvice];
150
- return new reportOutputModel_1.ReportOutputBodyModel(issueMessage, adviceMessage);
129
+ const adviceMessage = [chalk.bold('Advice'), ':', displayAdvice];
130
+ return new ReportOutputBodyModel(issueMessage, adviceMessage);
131
+ }
132
+ function getIssueRow(cveArray) {
133
+ orderByHighestPriority(cveArray);
134
+ const cveMessagesList = getIssueCveMsgList(cveArray);
135
+ const cveNumbers = getSeverityCounts(cveArray);
136
+ const numAndSeverityTypeDesc = getNumOfAndSeverityType(cveNumbers);
137
+ return [
138
+ chalk.bold('Issue'),
139
+ ':',
140
+ `${numAndSeverityTypeDesc} ${cveMessagesList.join(', ')}`
141
+ ];
151
142
  }
152
- exports.buildBody = buildBody;
153
143
  function gatherRemediationAdvice(guidance, libraryName, libraryVersion) {
154
- const guidanceModel = new reportGuidanceModel_1.ReportGuidanceModel();
144
+ const guidanceModel = new ReportGuidanceModel();
155
145
  const data = guidance[libraryName + '@' + libraryVersion];
156
146
  if (data) {
157
147
  guidanceModel.minimum = data.minUpgradeVersion;
@@ -159,43 +149,29 @@ function gatherRemediationAdvice(guidance, libraryName, libraryVersion) {
159
149
  }
160
150
  return guidanceModel;
161
151
  }
162
- exports.gatherRemediationAdvice = gatherRemediationAdvice;
163
152
  function buildFormattedHeaderNum(contrastHeaderNum) {
164
153
  return `CONTRAST-${contrastHeaderNum.toString().padStart(3, '0')}`;
165
154
  }
166
- exports.buildFormattedHeaderNum = buildFormattedHeaderNum;
167
- function getNumOfAndSeverityType(cveArray) {
168
- const { critical, high, medium, low, note } = (0, reportUtils_1.severityCountAllCVEs)(cveArray, new severityCountModel_1.SeverityCountModel());
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` : '';
185
- return `${criticalMessage} ${highMessage} ${mediumMessage} ${lowMessage} ${noteMessage}`
155
+ function getNumOfAndSeverityType(cveNumbers) {
156
+ const { critical, high, medium, low, note } = cveNumbers;
157
+ const criticalMsg = critical > 0 ? `${critical} Critical | ` : '';
158
+ const highMsg = high > 0 ? `${high} High | ` : '';
159
+ const mediumMsg = medium > 0 ? `${medium} Medium | ` : '';
160
+ const lowMsg = low > 0 ? `${low} Low | ` : '';
161
+ const noteMsg = note > 0 ? `${note} Note` : '';
162
+ return `${criticalMsg} ${highMsg} ${mediumMsg} ${lowMsg} ${noteMsg}`
186
163
  .replace(/\s+/g, ' ')
187
164
  .trim();
188
165
  }
189
- exports.getNumOfAndSeverityType = getNumOfAndSeverityType;
190
- const buildFooter = (reportModelStructure) => {
191
- const { critical, high, medium, low, note } = (0, reportUtils_1.countVulnerableLibrariesBySeverity)(reportModelStructure);
192
- const criticalMessage = chalk_1.default
193
- .hex(constants_1.CRITICAL_COLOUR)
166
+ const buildFooter = reportModelStructure => {
167
+ const { critical, high, medium, low, note } = countVulnerableLibrariesBySeverity(reportModelStructure);
168
+ const criticalMessage = chalk
169
+ .hex(CRITICAL_COLOUR)
194
170
  .bold(`${critical} Critical`);
195
- const highMessage = chalk_1.default.hex(constants_1.HIGH_COLOUR).bold(`${high} High`);
196
- const mediumMessage = chalk_1.default.hex(constants_1.MEDIUM_COLOUR).bold(`${medium} Medium`);
197
- const lowMessage = chalk_1.default.hex(constants_1.LOW_COLOUR).bold(`${low} Low`);
198
- const noteMessage = chalk_1.default.hex(constants_1.NOTE_COLOUR).bold(`${note} Note`);
171
+ const highMessage = chalk.hex(HIGH_COLOUR).bold(`${high} High`);
172
+ const mediumMessage = chalk.hex(MEDIUM_COLOUR).bold(`${medium} Medium`);
173
+ const lowMessage = chalk.hex(LOW_COLOUR).bold(`${low} Low`);
174
+ const noteMessage = chalk.hex(NOTE_COLOUR).bold(`${note} Note`);
199
175
  return {
200
176
  criticalMessage,
201
177
  highMessage,
@@ -204,3 +180,86 @@ const buildFooter = (reportModelStructure) => {
204
180
  noteMessage
205
181
  };
206
182
  };
183
+ const getIssueCveMsgList = results => {
184
+ const cveMessages = [];
185
+ results.forEach(reportSeverityModel => {
186
+ const { colour, severity, name } = reportSeverityModel;
187
+ const severityShorthand = chalk
188
+ .hex(colour)
189
+ .bold(`[${severity.charAt(0).toUpperCase()}]`);
190
+ const builtMessage = severityShorthand + name;
191
+ cveMessages.push(builtMessage);
192
+ });
193
+ return cveMessages;
194
+ };
195
+ const getSeverityCounts = results => {
196
+ const acc = {
197
+ critical: 0,
198
+ high: 0,
199
+ medium: 0,
200
+ low: 0,
201
+ note: 0,
202
+ total: 0
203
+ };
204
+ if (results && results.length > 0) {
205
+ results.forEach(i => {
206
+ acc[i.severity.toLowerCase()] += 1;
207
+ acc.total += 1;
208
+ return acc;
209
+ });
210
+ }
211
+ return acc;
212
+ };
213
+ const printNoVulnFoundMsg = () => {
214
+ console.log(i18n.__('scanNoVulnerabilitiesFound'));
215
+ console.log(i18n.__('scanNoVulnerabilitiesFoundSecureCode'));
216
+ console.log(i18n.__('scanNoVulnerabilitiesFoundGoodWork'));
217
+ console.log(chalk.bold(`Found 0 vulnerabilities`));
218
+ console.log(i18n.__('foundDetailedVulnerabilities', String(0), String(0), String(0), String(0), String(0)));
219
+ };
220
+ const printVulnInfo = projectOverview => {
221
+ const totalVulnerabilities = projectOverview.total;
222
+ createSummaryMessageBottom(totalVulnerabilities);
223
+ const formattedValues = severityFormatted(projectOverview);
224
+ console.log(i18n.__('foundDetailedVulnerabilities', String(formattedValues.criticalFormatted), String(formattedValues.highFormatted), String(formattedValues.mediumFormatted), String(formattedValues.lowFormatted), String(formattedValues.noteFormatted)));
225
+ };
226
+ const severityFormatted = projectOverview => {
227
+ const criticalFormatted = chalk
228
+ .hex(CRITICAL_COLOUR)
229
+ .bold(`${projectOverview.critical} Critical`);
230
+ const highFormatted = chalk
231
+ .hex(HIGH_COLOUR)
232
+ .bold(`${projectOverview.high} High`);
233
+ const mediumFormatted = chalk
234
+ .hex(MEDIUM_COLOUR)
235
+ .bold(`${projectOverview.medium} Medium`);
236
+ const lowFormatted = chalk.hex(LOW_COLOUR).bold(`${projectOverview.low} Low`);
237
+ const noteFormatted = chalk
238
+ .hex(NOTE_COLOUR)
239
+ .bold(`${projectOverview.note} Note`);
240
+ return {
241
+ criticalFormatted,
242
+ highFormatted,
243
+ mediumFormatted,
244
+ lowFormatted,
245
+ noteFormatted
246
+ };
247
+ };
248
+ module.exports = {
249
+ createSummaryMessageTop,
250
+ getReport,
251
+ createSummaryMessageBottom,
252
+ printVulnerabilityResponse,
253
+ printFormattedOutput,
254
+ getReportTable,
255
+ buildHeader,
256
+ buildBody,
257
+ getIssueRow,
258
+ gatherRemediationAdvice,
259
+ buildFormattedHeaderNum,
260
+ getNumOfAndSeverityType,
261
+ getIssueCveMsgList,
262
+ getSeverityCounts,
263
+ printNoVulnFoundMsg,
264
+ printVulnInfo
265
+ };
@@ -2,11 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ReportSeverityModel = void 0;
4
4
  class ReportSeverityModel {
5
- constructor(severity, priority, outputColour, cveName) {
5
+ constructor(severity, priority, colour, name) {
6
6
  this.severity = severity;
7
7
  this.priority = priority;
8
- this.outputColour = outputColour;
9
- this.cveName = cveName;
8
+ this.colour = colour;
9
+ this.name = name;
10
10
  }
11
11
  }
12
12
  exports.ReportSeverityModel = ReportSeverityModel;
@@ -22,15 +22,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
25
  Object.defineProperty(exports, "__esModule", { value: true });
29
26
  exports.vulnerabilityReportV2 = exports.formatVulnerabilityOutput = exports.convertJSDotNetPython = exports.convertKeysToStandardFormat = void 0;
30
27
  const commonReportingFunctions_1 = require("./commonReportingFunctions");
31
28
  const reportUtils_1 = require("./utils/reportUtils");
32
- const i18n_1 = __importDefault(require("i18n"));
33
- const chalk_1 = __importDefault(require("chalk"));
34
29
  const constants = __importStar(require("../../constants/constants"));
35
30
  const severityCountModel_1 = require("./models/severityCountModel");
36
31
  const common = __importStar(require("../../common/fail"));
@@ -67,11 +62,7 @@ function formatVulnerabilityOutput(libraryVulnerabilityResponse, id, config, rem
67
62
  const guidance = convertKeysToStandardFormat(config, remediationGuidance);
68
63
  const numberOfVulnerableLibraries = vulnerableLibraries.length;
69
64
  if (numberOfVulnerableLibraries === 0) {
70
- console.log(i18n_1.default.__('scanNoVulnerabilitiesFound'));
71
- console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundSecureCode'));
72
- console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundGoodWork'));
73
- console.log(chalk_1.default.bold(`Found ${numberOfVulnerableLibraries} vulnerabilities`));
74
- console.log(i18n_1.default.__('foundDetailedVulnerabilities', String(0), String(0), String(0), String(0), String(0)));
65
+ (0, commonReportingFunctions_1.printNoVulnFoundMsg)();
75
66
  return [false, 0, [new severityCountModel_1.SeverityCountModel()]];
76
67
  }
77
68
  else {
@@ -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.countVulnerableLibrariesBySeverity = exports.findNameAndVersion = exports.severityCountSingleCVE = exports.severityCountAllCVEs = exports.severityCountAllLibraries = exports.convertGenericToTypedLibraryVulns = exports.findCVESeverity = exports.findCVESeveritiesAndOrderByHighestPriority = exports.findHighestSeverityCVE = void 0;
6
+ exports.countVulnerableLibrariesBySeverity = exports.findNameAndVersion = exports.severityCountSingleCVE = exports.severityCountAllCVEs = exports.severityCountAllLibraries = exports.convertGenericToTypedLibraryVulns = exports.findCVESeverity = exports.orderByHighestPriority = exports.findHighestSeverityCVE = void 0;
7
7
  const reportLibraryModel_1 = require("../models/reportLibraryModel");
8
8
  const reportSeverityModel_1 = require("../models/reportSeverityModel");
9
9
  const constants_1 = __importDefault(require("../../../constants/constants"));
@@ -16,10 +16,10 @@ function findHighestSeverityCVE(cveArray) {
16
16
  return (0, lodash_1.orderBy)(mappedToReportSeverityModels, cve => cve?.priority)[0];
17
17
  }
18
18
  exports.findHighestSeverityCVE = findHighestSeverityCVE;
19
- function findCVESeveritiesAndOrderByHighestPriority(cves) {
20
- return (0, lodash_1.orderBy)(cves.map(cve => findCVESeverity(cve)), ['priority'], ['asc']);
19
+ function orderByHighestPriority(cves) {
20
+ return (0, lodash_1.orderBy)(cves, ['priority'], ['asc']);
21
21
  }
22
- exports.findCVESeveritiesAndOrderByHighestPriority = findCVESeveritiesAndOrderByHighestPriority;
22
+ exports.orderByHighestPriority = orderByHighestPriority;
23
23
  function findCVESeverity(cve) {
24
24
  const cveName = cve.name;
25
25
  if (cve.cvss3SeverityCode === 'CRITICAL' || cve.severityCode === 'CRITICAL') {
@@ -5,7 +5,7 @@ const chalk = require('chalk');
5
5
  const save = require('../commands/audit/saveFile');
6
6
  const sbom = require('../sbom/generateSbom');
7
7
  const { SBOM_CYCLONE_DX_FILE, SBOM_SPDX_FILE } = require('../constants/constants');
8
- async function auditSave(config) {
8
+ async function auditSave(config, reportId) {
9
9
  let fileFormat;
10
10
  switch (config.save) {
11
11
  case null:
@@ -19,7 +19,12 @@ async function auditSave(config) {
19
19
  break;
20
20
  }
21
21
  if (fileFormat) {
22
- save.saveFile(config, fileFormat, await sbom.generateSbom(config, fileFormat));
22
+ if (config.experimental) {
23
+ save.saveFile(config, fileFormat, await sbom.generateSCASbom(config, fileFormat, reportId));
24
+ }
25
+ else {
26
+ save.saveFile(config, fileFormat, await sbom.generateSbom(config, fileFormat));
27
+ }
23
28
  const filename = `${config.applicationId}-sbom-${fileFormat}.json`;
24
29
  if (fs.existsSync(filename)) {
25
30
  console.log(i18n.__('auditSBOMSaveSuccess') + ` - ${filename}`);
@@ -52,7 +52,9 @@ const auditUsageGuide = (0, command_line_usage_1.default)([
52
52
  'language',
53
53
  'experimental',
54
54
  'app-groups',
55
- 'metadata'
55
+ 'metadata',
56
+ 'track',
57
+ 'branch'
56
58
  ]
57
59
  },
58
60
  (0, commonHelp_1.commonHelpLinks)()
@@ -4,18 +4,12 @@ const { startScan } = require('../../scan/scanController');
4
4
  const { saveScanFile } = require('../../utils/saveFile');
5
5
  const { ScanResultsModel } = require('../../scan/models/scanResultsModel');
6
6
  const { formatScanOutput } = require('../../scan/formatScanOutput');
7
- const { processSca } = require('./sca/scaAnalysis');
8
7
  const common = require('../../common/fail');
9
8
  const { sendTelemetryConfigAsObject } = require('../../telemetry/telemetry');
10
9
  const chalk = require('chalk');
11
- const generalAPI = require('../../utils/generalAPI');
12
10
  const processScan = async (contrastConf, argv) => {
13
11
  let config = await scanConfig.getScanConfig(contrastConf, 'scan', argv);
14
12
  let output = undefined;
15
- config.mode = await generalAPI.getMode(config);
16
- if (config.experimental) {
17
- await processSca(config, argv);
18
- }
19
13
  let scanResults = new ScanResultsModel(await startScan(config));
20
14
  await sendTelemetryConfigAsObject(config, 'scan', argv, 'SUCCESS', scanResults.scanDetail.language);
21
15
  if (scanResults.scanResultsInstances !== undefined) {
@@ -2,7 +2,6 @@
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');
6
5
  const auditController = require('../../audit/auditController');
7
6
  const { supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET } } = require('../../../constants/constants');
8
7
  const goAnalysis = require('../../../scaAnalysis/go/goAnalysis');
@@ -19,9 +18,11 @@ const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet');
19
18
  const { auditUsageGuide } = require('../../audit/help');
20
19
  const rootFile = require('../../../audit/languageAnalysisEngine/getProjectRootFilenames');
21
20
  const path = require('path');
22
- const generalAPI = require('../../../utils/generalAPI');
21
+ const auditReport = require('../../../scaAnalysis/common/auditReport');
22
+ const scaUpload = require('../../../scaAnalysis/common/scaServicesUpload');
23
+ const settingsHelper = require('../../../utils/settingsHelper');
23
24
  const processSca = async (config) => {
24
- config.mode = await generalAPI.getMode(config);
25
+ config = await settingsHelper.getSettings(config);
25
26
  const startTime = performance.now();
26
27
  let filesFound;
27
28
  if (config.help) {
@@ -76,19 +77,35 @@ const processSca = async (config) => {
76
77
  if (!config.applicationId) {
77
78
  config.applicationId = await auditController.dealWithNoAppId(config);
78
79
  }
79
- console.log('');
80
- const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
81
- startSpinner(reportSpinner);
82
- const snapshotResponse = await treeUpload.commonSendSnapShot(messageToSend, config);
83
- await pollForSnapshotCompletition(config, snapshotResponse.id, reportSpinner);
84
- succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
85
- await vulnerabilityReportV2(config, snapshotResponse.id);
86
- if (config.save !== undefined) {
87
- await auditSave.auditSave(config);
80
+ if (config.experimental) {
81
+ console.log('');
82
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
83
+ startSpinner(reportSpinner);
84
+ const [reports, reportId] = await scaUpload.scaTreeUpload(messageToSend, config);
85
+ auditReport.processAuditReport(config, reports[0]);
86
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
87
+ if (config.save !== undefined) {
88
+ await auditSave.auditSave(config, reportId);
89
+ }
90
+ const endTime = performance.now() - startTime;
91
+ const scanDurationMs = endTime - startTime;
92
+ console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
93
+ }
94
+ else {
95
+ console.log('');
96
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
97
+ startSpinner(reportSpinner);
98
+ const snapshotResponse = await treeUpload.commonSendSnapShot(messageToSend, config);
99
+ await pollForSnapshotCompletition(config, snapshotResponse.id, reportSpinner);
100
+ succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
101
+ await vulnerabilityReportV2(config, snapshotResponse.id);
102
+ if (config.save !== undefined) {
103
+ await auditSave.auditSave(config);
104
+ }
105
+ const endTime = performance.now() - startTime;
106
+ const scanDurationMs = endTime - startTime;
107
+ console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
88
108
  }
89
- const endTime = performance.now() - startTime;
90
- const scanDurationMs = endTime - startTime;
91
- console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`);
92
109
  }
93
110
  else {
94
111
  if (filesFound.length === 0) {
@@ -185,6 +185,12 @@ HTTPClient.prototype.scaServiceReportStatus = function scaServiceReport(config,
185
185
  options.url = url;
186
186
  return requestUtils.sendRequest({ method: 'get', options });
187
187
  };
188
+ HTTPClient.prototype.scaServiceIngests = function scaServiceIngests(config) {
189
+ const options = _.cloneDeep(this.requestOptions);
190
+ let url = createScaServiceIngestsURL(config);
191
+ options.url = url;
192
+ return requestUtils.sendRequest({ method: 'get', options });
193
+ };
188
194
  HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
189
195
  const options = _.cloneDeep(this.requestOptions);
190
196
  if (config.ignoreDev) {
@@ -266,6 +272,11 @@ HTTPClient.prototype.getSbom = function getSbom(config, type) {
266
272
  options.url = createSbomUrl(config, type);
267
273
  return requestUtils.sendRequest({ method: 'get', options });
268
274
  };
275
+ HTTPClient.prototype.getSCASbom = function getSbom(config, type, reportId) {
276
+ const options = _.cloneDeep(this.requestOptions);
277
+ options.url = createSCASbomUrl(config, type, reportId);
278
+ return requestUtils.sendRequest({ method: 'get', options });
279
+ };
269
280
  HTTPClient.prototype.getLatestVersion = function getLatestVersion() {
270
281
  const options = _.cloneDeep(this.requestOptions);
271
282
  options.url =
@@ -321,13 +332,18 @@ function createSnapshotURL(config) {
321
332
  return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/snapshots`;
322
333
  }
323
334
  function createScaServiceReportURL(config, reportId) {
324
- return ``;
335
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/applications/${config.applicationId}/reports/${reportId}`;
325
336
  }
326
337
  function createScaServiceReportStatusURL(config, reportId) {
327
- return ``;
338
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/${reportId}/status`;
339
+ }
340
+ function createScaServiceIngestsURL(config) {
341
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests`;
328
342
  }
329
343
  function createScaServiceIngestURL(config) {
330
- return ``;
344
+ let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/tree`;
345
+ baseUrl = config.track ? baseUrl.concat('?persist=true') : baseUrl;
346
+ return baseUrl;
331
347
  }
332
348
  const createAppCreateURL = config => {
333
349
  return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/create`;
@@ -353,6 +369,9 @@ function createDataUrl() {
353
369
  function createSbomUrl(config, type) {
354
370
  return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/${type}`;
355
371
  }
372
+ function createSCASbomUrl(config, type, reportId) {
373
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/applications/${config.applicationId}/sbom/${reportId}?toolType=${type}`;
374
+ }
356
375
  function createTelemetryEventUrl(config) {
357
376
  return `${config.host}/Contrast/api/sast/organizations/${config.organizationId}/cli`;
358
377
  }
@@ -47,8 +47,7 @@ const reportFailureError = () => {
47
47
  console.log(i18n_1.default.__('auditReportFailureMessage'));
48
48
  };
49
49
  exports.reportFailureError = reportFailureError;
50
- const genericError = (missingCliOption) => {
51
- console.log(missingCliOption);
50
+ const genericError = () => {
52
51
  console.error(i18n_1.default.__('genericErrorMessage'));
53
52
  process.exit(1);
54
53
  };