@contrast/contrast 1.0.18 → 1.0.20

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 (47) hide show
  1. package/dist/audit/report/commonReportingFunctions.js +3 -4
  2. package/dist/audit/report/models/reportListModel.js +2 -1
  3. package/dist/audit/report/reportingFeature.js +1 -1
  4. package/dist/audit/report/utils/reportUtils.js +30 -11
  5. package/dist/cliConstants.js +1 -0
  6. package/dist/commands/audit/auditConfig.js +1 -2
  7. package/dist/commands/auth/auth.js +43 -7
  8. package/dist/commands/scan/sca/scaAnalysis.js +4 -2
  9. package/dist/common/HTTPClient.js +4 -4
  10. package/dist/common/errorHandling.js +13 -1
  11. package/dist/constants/constants.js +1 -1
  12. package/dist/constants/locales.js +18 -2
  13. package/dist/scaAnalysis/common/auditReport.js +16 -60
  14. package/dist/scaAnalysis/common/commonReportingFunctionsSca.js +154 -0
  15. package/dist/scaAnalysis/common/models/ScaReportModel.js +45 -0
  16. package/dist/scaAnalysis/common/scaServicesUpload.js +4 -3
  17. package/dist/scaAnalysis/common/utils/reportUtilsSca.js +76 -0
  18. package/dist/scaAnalysis/java/analysis.js +1 -28
  19. package/dist/scaAnalysis/java/index.js +1 -13
  20. package/dist/scan/formatScanOutput.js +19 -13
  21. package/dist/utils/getConfig.js +1 -1
  22. package/dist/utils/paramsUtil/configStoreParams.js +1 -12
  23. package/dist/utils/paramsUtil/paramHandler.js +1 -7
  24. package/package.json +5 -1
  25. package/src/audit/report/commonReportingFunctions.js +7 -5
  26. package/src/audit/report/models/reportListModel.ts +12 -2
  27. package/src/audit/report/reportingFeature.ts +1 -1
  28. package/src/audit/report/utils/reportUtils.ts +4 -4
  29. package/src/cliConstants.js +1 -0
  30. package/src/commands/audit/auditConfig.js +1 -2
  31. package/src/commands/auth/auth.js +49 -7
  32. package/src/commands/scan/sca/scaAnalysis.js +7 -2
  33. package/src/common/HTTPClient.js +5 -4
  34. package/src/common/errorHandling.js +14 -1
  35. package/src/constants/constants.js +1 -1
  36. package/src/constants/locales.js +19 -2
  37. package/src/scaAnalysis/common/auditReport.js +25 -80
  38. package/src/scaAnalysis/common/commonReportingFunctionsSca.js +276 -0
  39. package/src/scaAnalysis/common/models/ScaReportModel.ts +81 -0
  40. package/src/scaAnalysis/common/scaServicesUpload.js +5 -3
  41. package/src/scaAnalysis/common/utils/reportUtilsSca.ts +123 -0
  42. package/src/scaAnalysis/java/analysis.js +1 -28
  43. package/src/scaAnalysis/java/index.js +1 -18
  44. package/src/scan/formatScanOutput.ts +28 -17
  45. package/src/utils/getConfig.ts +1 -2
  46. package/src/utils/paramsUtil/configStoreParams.js +1 -14
  47. package/src/utils/paramsUtil/paramHandler.js +1 -9
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScaReportRemediationAdviceModel = exports.ScaReportVulnerabilityModel = exports.ScaReportModel = void 0;
4
+ class ScaReportModel {
5
+ constructor(library) {
6
+ this.uuid = library.uuid;
7
+ this.groupName = library.groupName;
8
+ this.artifactName = library.artifactName;
9
+ this.version = library.version;
10
+ this.hash = library.hash;
11
+ this.fileName = library.fileName;
12
+ this.libraryLanguage = library.libraryLanguage;
13
+ this.vulnerable = library.vulnerable;
14
+ this.privateLibrary = library.privateLibrary;
15
+ this.severity = library.severity;
16
+ this.releaseDate = library.releaseDate;
17
+ this.latestVersionReleaseDate = library.latestVersionReleaseDate;
18
+ this.latestVersion = library.latestVersion;
19
+ this.versionsBehind = library.versionsBehind;
20
+ this.vulnerabilities = library.vulnerabilities;
21
+ this.remediationAdvice = library.remediationAdvice;
22
+ }
23
+ }
24
+ exports.ScaReportModel = ScaReportModel;
25
+ class ScaReportVulnerabilityModel {
26
+ constructor(name, description, cvss2Vector, severityValue, severity, cvss3Vector, cvss3SeverityValue, cvss3Severity, hasCvss3) {
27
+ this.name = name;
28
+ this.description = description;
29
+ this.cvss2Vector = cvss2Vector;
30
+ this.severityValue = severityValue;
31
+ this.severity = severity;
32
+ this.cvss3Vector = cvss3Vector;
33
+ this.cvss3SeverityValue = cvss3SeverityValue;
34
+ this.cvss3Severity = cvss3Severity;
35
+ this.hasCvss3 = hasCvss3;
36
+ }
37
+ }
38
+ exports.ScaReportVulnerabilityModel = ScaReportVulnerabilityModel;
39
+ class ScaReportRemediationAdviceModel {
40
+ constructor(closestStableVersion, latestStableVersion) {
41
+ this.closestStableVersion = closestStableVersion;
42
+ this.latestStableVersion = latestStableVersion;
43
+ }
44
+ }
45
+ exports.ScaReportRemediationAdviceModel = ScaReportRemediationAdviceModel;
@@ -44,16 +44,17 @@ const scaTreeUpload = async (analysis, config) => {
44
44
  if (res.body.status === 'COMPLETED') {
45
45
  keepChecking = false;
46
46
  return client.scaServiceReport(config, reportID).then(res => {
47
- return [res.body, reportID];
47
+ const reportBody = res.body;
48
+ return { reportBody, reportID };
48
49
  });
49
50
  }
50
51
  });
51
52
  if (!keepChecking) {
52
- return [res, reportID];
53
+ return { reportArray: res.reportBody, reportID };
53
54
  }
54
55
  await requestUtils.sleep(5000);
55
56
  }
56
- return [res, reportID];
57
+ return { reportArray: res, reportID };
57
58
  };
58
59
  module.exports = {
59
60
  scaTreeUpload
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.severityCountSingleCVESca = exports.severityCountAllCVEsSca = exports.severityCountAllLibrariesSca = exports.convertGenericToTypedReportModelSca = exports.findCVESeveritySca = exports.orderByHighestPrioritySca = exports.findHighestSeverityCVESca = void 0;
4
+ const lodash_1 = require("lodash");
5
+ const constants_1 = require("../../../constants/constants");
6
+ const reportSeverityModel_1 = require("../../../audit/report/models/reportSeverityModel");
7
+ const ScaReportModel_1 = require("../models/ScaReportModel");
8
+ function findHighestSeverityCVESca(cveArray) {
9
+ const mappedToReportSeverityModels = cveArray.map(cve => findCVESeveritySca(cve));
10
+ return (0, lodash_1.orderBy)(mappedToReportSeverityModels, cve => cve?.priority)[0];
11
+ }
12
+ exports.findHighestSeverityCVESca = findHighestSeverityCVESca;
13
+ function orderByHighestPrioritySca(reportSeverityModel) {
14
+ return (0, lodash_1.orderBy)(reportSeverityModel, ['priority'], ['asc']);
15
+ }
16
+ exports.orderByHighestPrioritySca = orderByHighestPrioritySca;
17
+ function findCVESeveritySca(vulnerabilityModel) {
18
+ const { name } = vulnerabilityModel;
19
+ if (vulnerabilityModel.cvss3Severity === 'CRITICAL' ||
20
+ vulnerabilityModel.severity === 'CRITICAL') {
21
+ return new reportSeverityModel_1.ReportSeverityModel('CRITICAL', constants_1.CRITICAL_PRIORITY, constants_1.CRITICAL_COLOUR, name);
22
+ }
23
+ else if (vulnerabilityModel.cvss3Severity === 'HIGH' ||
24
+ vulnerabilityModel.severity === 'HIGH') {
25
+ return new reportSeverityModel_1.ReportSeverityModel('HIGH', constants_1.HIGH_PRIORITY, constants_1.HIGH_COLOUR, name);
26
+ }
27
+ else if (vulnerabilityModel.cvss3Severity === 'MEDIUM' ||
28
+ vulnerabilityModel.severity === 'MEDIUM') {
29
+ return new reportSeverityModel_1.ReportSeverityModel('MEDIUM', constants_1.MEDIUM_PRIORITY, constants_1.MEDIUM_COLOUR, name);
30
+ }
31
+ else if (vulnerabilityModel.cvss3Severity === 'LOW' ||
32
+ vulnerabilityModel.severity === 'LOW') {
33
+ return new reportSeverityModel_1.ReportSeverityModel('LOW', constants_1.LOW_PRIORITY, constants_1.LOW_COLOUR, name);
34
+ }
35
+ else if (vulnerabilityModel.cvss3Severity === 'NOTE' ||
36
+ vulnerabilityModel.severity === 'NOTE') {
37
+ return new reportSeverityModel_1.ReportSeverityModel('NOTE', constants_1.NOTE_PRIORITY, constants_1.NOTE_COLOUR, name);
38
+ }
39
+ }
40
+ exports.findCVESeveritySca = findCVESeveritySca;
41
+ function convertGenericToTypedReportModelSca(reportArray) {
42
+ return reportArray.map((library) => {
43
+ return new ScaReportModel_1.ScaReportModel(library);
44
+ });
45
+ }
46
+ exports.convertGenericToTypedReportModelSca = convertGenericToTypedReportModelSca;
47
+ function severityCountAllLibrariesSca(vulnerableLibraries, severityCount) {
48
+ vulnerableLibraries.forEach(lib => severityCountAllCVEsSca(lib.vulnerabilities, severityCount));
49
+ return severityCount;
50
+ }
51
+ exports.severityCountAllLibrariesSca = severityCountAllLibrariesSca;
52
+ function severityCountAllCVEsSca(cveArray, severityCount) {
53
+ const severityCountInner = severityCount;
54
+ cveArray.forEach(cve => severityCountSingleCVESca(cve, severityCountInner));
55
+ return severityCountInner;
56
+ }
57
+ exports.severityCountAllCVEsSca = severityCountAllCVEsSca;
58
+ function severityCountSingleCVESca(cve, severityCount) {
59
+ if (cve.cvss3Severity === 'CRITICAL' || cve.severity === 'CRITICAL') {
60
+ severityCount.critical += 1;
61
+ }
62
+ else if (cve.cvss3Severity === 'HIGH' || cve.severity === 'HIGH') {
63
+ severityCount.high += 1;
64
+ }
65
+ else if (cve.cvss3Severity === 'MEDIUM' || cve.severity === 'MEDIUM') {
66
+ severityCount.medium += 1;
67
+ }
68
+ else if (cve.cvss3Severity === 'LOW' || cve.severity === 'LOW') {
69
+ severityCount.low += 1;
70
+ }
71
+ else if (cve.cvss3Severity === 'NOTE' || cve.severity === 'NOTE') {
72
+ severityCount.note += 1;
73
+ }
74
+ return severityCount;
75
+ }
76
+ exports.severityCountSingleCVESca = severityCountSingleCVESca;
@@ -111,34 +111,7 @@ const getJavaBuildDeps = (config, files) => {
111
111
  console.log(err.message.toString());
112
112
  }
113
113
  };
114
- const agreementPrompt = async (config) => {
115
- const rl = readLine.createInterface({
116
- input: process.stdin,
117
- output: process.stdout
118
- });
119
- return new Promise((resolve, reject) => {
120
- rl.question('❔ Do you want to continue? Type Y or N', async (input) => {
121
- if (input.toLowerCase() === 'yes' || input.toLowerCase() === 'y') {
122
- config.javaAgreement = paramHandler.setAgreement(true);
123
- rl.close();
124
- resolve(config);
125
- }
126
- else if (input.toLowerCase() === 'no' || input.toLowerCase() === 'n') {
127
- rl.close();
128
- resolve(process.exit(1));
129
- }
130
- else {
131
- rl.close();
132
- console.log('Invalid Input: Exiting');
133
- resolve(process.exit(1));
134
- }
135
- });
136
- }).catch(e => {
137
- throw e;
138
- });
139
- };
140
114
  module.exports = {
141
115
  getJavaBuildDeps,
142
- determineProjectTypeAndCwd,
143
- agreementPrompt
116
+ determineProjectTypeAndCwd
144
117
  };
@@ -3,13 +3,10 @@ const analysis = require('./analysis');
3
3
  const { parseBuildDeps } = require('./javaBuildDepsParser');
4
4
  const { createJavaTSMessage } = require('../common/formatMessage');
5
5
  const { parseDependenciesForSCAServices } = require('../common/scaParserForGoAndJava');
6
- const chalk = require('chalk');
7
- const _ = require('lodash');
8
6
  const javaAnalysis = async (config, languageFiles) => {
9
7
  languageFiles.JAVA.forEach(file => {
10
8
  file.replace('build.gradle.kts', 'build.gradle');
11
9
  });
12
- await getAgreement(config);
13
10
  const javaDeps = buildJavaTree(config, languageFiles.JAVA);
14
11
  if (config.experimental) {
15
12
  return parseDependenciesForSCAServices(javaDeps);
@@ -18,19 +15,10 @@ const javaAnalysis = async (config, languageFiles) => {
18
15
  return createJavaTSMessage(javaDeps);
19
16
  }
20
17
  };
21
- const getAgreement = async (config) => {
22
- console.log(chalk.bold('Java project detected'));
23
- console.log('Java analysis uses maven / gradle which are potentially susceptible to command injection. Be sure that the code you are running Contrast CLI on is trusted before continuing.');
24
- if (!process.env.CI && !config?.javaAgreement) {
25
- return await analysis.agreementPrompt(config);
26
- }
27
- return config;
28
- };
29
18
  const buildJavaTree = (config, files) => {
30
19
  const javaBuildDeps = analysis.getJavaBuildDeps(config, files);
31
20
  return parseBuildDeps(config, javaBuildDeps);
32
21
  };
33
22
  module.exports = {
34
- javaAnalysis,
35
- getAgreement
23
+ javaAnalysis
36
24
  };
@@ -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.assignBySeverity = exports.stripTags = exports.getCodeFlowInfo = exports.getSourceLineNumber = exports.getLocationsSyncInfo = exports.editVulName = exports.getDefaultView = exports.formatLinks = exports.formatScanOutput = void 0;
6
+ exports.assignBySeverity = exports.stripTags = exports.getCodeFlowInfo = exports.getSourceLineNumber = exports.getLocationsSyncInfo = exports.editVulName = exports.doAddSourceLineNumber = exports.getDefaultView = exports.formatLinks = exports.formatScanOutput = void 0;
7
7
  const i18n_1 = __importDefault(require("i18n"));
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const groupedResultsModel_1 = require("./models/groupedResultsModel");
@@ -12,24 +12,25 @@ const cli_table3_1 = __importDefault(require("cli-table3"));
12
12
  const constants_1 = require("../constants/constants");
13
13
  const commonReportingFunctions_1 = require("../audit/report/commonReportingFunctions");
14
14
  function formatScanOutput(scanResults) {
15
- const { scanResultsInstances } = scanResults;
16
- const projectOverview = (0, commonReportingFunctions_1.getSeverityCounts)(scanResultsInstances.content);
17
- if (scanResultsInstances.content.length === 0) {
15
+ const { content } = scanResults.scanResultsInstances;
16
+ const { language } = scanResults.scanDetail;
17
+ const severityCounts = (0, commonReportingFunctions_1.getSeverityCounts)(content);
18
+ if (content.length === 0) {
18
19
  console.log(i18n_1.default.__('scanNoVulnerabilitiesFound'));
19
20
  console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundSecureCode'));
20
21
  console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundGoodWork'));
21
22
  }
22
23
  else {
23
- const message = projectOverview.critical || projectOverview.high
24
+ const message = severityCounts.critical || severityCounts.high
24
25
  ? 'Here are your top priorities to fix'
25
26
  : "No major issues, here's what we found";
26
27
  console.log(chalk_1.default.bold(message));
27
28
  console.log();
28
- let defaultView = getDefaultView(scanResultsInstances.content);
29
+ const defaultView = getDefaultView(content, language);
29
30
  let count = 0;
30
31
  defaultView.forEach(entry => {
31
32
  count++;
32
- let table = new cli_table3_1.default({
33
+ const table = new cli_table3_1.default({
33
34
  chars: {
34
35
  top: '',
35
36
  'top-mid': '',
@@ -90,8 +91,8 @@ function formatScanOutput(scanResults) {
90
91
  console.log();
91
92
  });
92
93
  }
93
- (0, commonReportingFunctions_1.printVulnInfo)(projectOverview);
94
- return projectOverview;
94
+ (0, commonReportingFunctions_1.printVulnInfo)(severityCounts);
95
+ return severityCounts;
95
96
  }
96
97
  exports.formatScanOutput = formatScanOutput;
97
98
  function formatLinks(objName, entry) {
@@ -107,7 +108,7 @@ function formatLinks(objName, entry) {
107
108
  }
108
109
  }
109
110
  exports.formatLinks = formatLinks;
110
- function getDefaultView(content) {
111
+ function getDefaultView(content, language) {
111
112
  const groupTypeResults = [];
112
113
  content.forEach(resultEntry => {
113
114
  const groupResultsObj = new groupedResultsModel_1.GroupedResultsModel(resultEntry.ruleId);
@@ -118,8 +119,7 @@ function getDefaultView(content) {
118
119
  groupResultsObj.learn = resultEntry.learn;
119
120
  groupResultsObj.message = resultEntry.message?.text
120
121
  ? editVulName(resultEntry.message.text) +
121
- ':' +
122
- getSourceLineNumber(resultEntry)
122
+ doAddSourceLineNumber(resultEntry, language)
123
123
  : '';
124
124
  groupResultsObj.codePath = getLocationsSyncInfo(resultEntry);
125
125
  groupTypeResults.push(groupResultsObj);
@@ -128,6 +128,12 @@ function getDefaultView(content) {
128
128
  return (0, lodash_1.sortBy)(groupTypeResults, ['priority']);
129
129
  }
130
130
  exports.getDefaultView = getDefaultView;
131
+ function doAddSourceLineNumber(resultEntry, language) {
132
+ return language !== constants_1.supportedLanguagesScan.JAVASCRIPT
133
+ ? ':' + getSourceLineNumber(resultEntry)
134
+ : '';
135
+ }
136
+ exports.doAddSourceLineNumber = doAddSourceLineNumber;
131
137
  function editVulName(message) {
132
138
  return message.substring(message.indexOf(' in '));
133
139
  }
@@ -143,7 +149,7 @@ function getLocationsSyncInfo(resultEntry) {
143
149
  exports.getLocationsSyncInfo = getLocationsSyncInfo;
144
150
  function getSourceLineNumber(resultEntry) {
145
151
  const locationsLineNumber = resultEntry.locations[0]?.physicalLocation?.region?.startLine || '';
146
- let codeFlowLineNumber = getCodeFlowInfo(resultEntry);
152
+ const codeFlowLineNumber = getCodeFlowInfo(resultEntry);
147
153
  return codeFlowLineNumber ? codeFlowLineNumber : locationsLineNumber;
148
154
  }
149
155
  exports.getSourceLineNumber = getSourceLineNumber;
@@ -21,6 +21,6 @@ const setConfigValues = (config, values) => {
21
21
  config.set('apiKey', values.apiKey);
22
22
  config.set('organizationId', values.orgId);
23
23
  config.set('authorization', values.authHeader);
24
- values.host ? config.set('host', values.host) : null;
24
+ values.host ? config.set('host', values.host) : config.set('host', constants_1.CE_URL);
25
25
  };
26
26
  exports.setConfigValues = setConfigValues;
@@ -15,15 +15,4 @@ const getAuth = () => {
15
15
  }
16
16
  return ContrastConfToUse;
17
17
  };
18
- const getAgreement = () => {
19
- const ContrastConf = config.localConfig(APP_NAME, APP_VERSION);
20
- let ContrastConfToUse = {};
21
- ContrastConfToUse.javaAgreement = ContrastConf.get('javaAgreement');
22
- return ContrastConfToUse;
23
- };
24
- const setAgreement = agreement => {
25
- const ContrastConf = config.localConfig(APP_NAME, APP_VERSION);
26
- ContrastConf.set('javaAgreement', agreement);
27
- return agreement;
28
- };
29
- module.exports = { getAuth, getAgreement, setAgreement };
18
+ module.exports = { getAuth };
@@ -22,10 +22,4 @@ const getAuth = params => {
22
22
  process.exit(1);
23
23
  }
24
24
  };
25
- const getAgreement = () => {
26
- return configStoreParams.getAgreement();
27
- };
28
- const setAgreement = answer => {
29
- return configStoreParams.setAgreement(answer);
30
- };
31
- module.exports = { getAuth, getAgreement, setAgreement };
25
+ module.exports = { getAuth };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/contrast",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "description": "Contrast Security's command line tool",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -15,6 +15,10 @@
15
15
  {
16
16
  "name": "Andrew Shanks",
17
17
  "email": "andrew.shanks@contrastsecurity.com"
18
+ },
19
+ {
20
+ "name": "Oisín Cassidy",
21
+ "email": "oisin.cassidy@contrastsecurity.com"
18
22
  }
19
23
  ],
20
24
  "license": "ISC",
@@ -108,7 +108,8 @@ const printFormattedOutput = (
108
108
  new SeverityCountModel()
109
109
  ).getTotal
110
110
  ),
111
- library.cveArray
111
+ library.cveArray,
112
+ null
112
113
  )
113
114
  report.reportOutputList.push(newOutputModel)
114
115
  }
@@ -131,6 +132,7 @@ const printFormattedOutput = (
131
132
  contrastHeaderNumCounter++
132
133
  const { libraryName, libraryVersion, highestSeverity } =
133
134
  reportModel.compositeKey
135
+
134
136
  const numOfCVEs = reportModel.cveArray.length
135
137
 
136
138
  const table = getReportTable()
@@ -236,9 +238,11 @@ function buildHeader(
236
238
  }
237
239
 
238
240
  function buildBody(cveArray, advice) {
239
- let assignPriorityToVulns = cveArray.map(result => findCVESeverity(result))
241
+ const orderedCvesWithSeverityAssigned = orderByHighestPriority(
242
+ cveArray.map(cve => findCVESeverity(cve))
243
+ )
240
244
 
241
- const issueMessage = getIssueRow(assignPriorityToVulns)
245
+ const issueMessage = getIssueRow(orderedCvesWithSeverityAssigned)
242
246
 
243
247
  //todo different advice based on remediationGuidance being available or now
244
248
  // console.log(advice)
@@ -254,7 +258,6 @@ function buildBody(cveArray, advice) {
254
258
  }
255
259
 
256
260
  function getIssueRow(cveArray) {
257
- orderByHighestPriority(cveArray)
258
261
  const cveMessagesList = getIssueCveMsgList(cveArray)
259
262
  return [chalk.bold('Issue'), ':', `${cveMessagesList.join(', ')}`]
260
263
  }
@@ -301,7 +304,6 @@ const getIssueCveMsgList = results => {
301
304
  const cveMessages = []
302
305
 
303
306
  results.forEach(reportSeverityModel => {
304
- // @ts-ignore
305
307
  const { colour, severity, name } = reportSeverityModel
306
308
 
307
309
  const severityShorthand = chalk
@@ -1,5 +1,9 @@
1
1
  import { ReportSeverityModel } from './reportSeverityModel'
2
2
  import { ReportCVEModel } from './reportLibraryModel'
3
+ import {
4
+ ScaReportRemediationAdviceModel,
5
+ ScaReportVulnerabilityModel
6
+ } from '../../../scaAnalysis/common/models/ScaReportModel'
3
7
 
4
8
  export class ReportList {
5
9
  reportOutputList: ReportModelStructure[]
@@ -11,11 +15,17 @@ export class ReportList {
11
15
 
12
16
  export class ReportModelStructure {
13
17
  compositeKey: ReportCompositeKey
14
- cveArray: ReportCVEModel[]
18
+ cveArray: ReportCVEModel[] | ScaReportVulnerabilityModel[]
19
+ remediationAdvice: ScaReportRemediationAdviceModel | null
15
20
 
16
- constructor(compositeKey: ReportCompositeKey, cveArray: ReportCVEModel[]) {
21
+ constructor(
22
+ compositeKey: ReportCompositeKey,
23
+ cveArray: ReportCVEModel[] | ScaReportVulnerabilityModel[],
24
+ remediationAdvice: ScaReportRemediationAdviceModel | null
25
+ ) {
17
26
  this.compositeKey = compositeKey
18
27
  this.cveArray = cveArray
28
+ this.remediationAdvice = remediationAdvice
19
29
  }
20
30
  }
21
31
 
@@ -87,7 +87,7 @@ export async function vulnerabilityReportV2(config: any, reportId: string) {
87
87
  const reportResponse = await getReport(config, reportId)
88
88
 
89
89
  if (reportResponse !== undefined) {
90
- let output = formatVulnerabilityOutput(
90
+ const output = formatVulnerabilityOutput(
91
91
  reportResponse.vulnerabilities,
92
92
  config.applicationId,
93
93
  config,
@@ -3,8 +3,7 @@ import {
3
3
  ReportLibraryModel
4
4
  } from '../models/reportLibraryModel'
5
5
  import { ReportSeverityModel } from '../models/reportSeverityModel'
6
- import languageAnalysisEngine from '../../../constants/constants'
7
- import {
6
+ import languageAnalysisEngine, {
8
7
  CRITICAL_COLOUR,
9
8
  CRITICAL_PRIORITY,
10
9
  HIGH_COLOUR,
@@ -19,6 +18,7 @@ import {
19
18
  import { orderBy } from 'lodash'
20
19
  import { SeverityCountModel } from '../models/severityCountModel'
21
20
  import { ReportModelStructure } from '../models/reportListModel'
21
+
22
22
  const {
23
23
  supportedLanguages: { GO }
24
24
  } = languageAnalysisEngine
@@ -30,8 +30,8 @@ export function findHighestSeverityCVE(cveArray: ReportCVEModel[]) {
30
30
  return orderBy(mappedToReportSeverityModels, cve => cve?.priority)[0]
31
31
  }
32
32
 
33
- export function orderByHighestPriority(cves: ReportCVEModel[]) {
34
- return orderBy(cves, ['priority'], ['asc'])
33
+ export function orderByHighestPriority(severityModels: ReportSeverityModel[]) {
34
+ return orderBy(severityModels, ['priority'], ['asc'])
35
35
  }
36
36
 
37
37
  export function findCVESeverity(cve: ReportCVEModel) {
@@ -211,6 +211,7 @@ const scanOptionDefinitions = [
211
211
  ]
212
212
 
213
213
  const authOptionDefinitions = [
214
+ ...sharedConnectionOptionDefinitions,
214
215
  {
215
216
  name: 'help',
216
217
  alias: 'h',
@@ -10,8 +10,7 @@ const getAuditConfig = async (contrastConf, command, argv) => {
10
10
  constants.commandLineDefinitions.auditOptionDefinitions
11
11
  )
12
12
  const paramsAuth = paramHandler.getAuth(auditParameters)
13
- const javaAgreement = paramHandler.getAgreement()
14
- return { ...paramsAuth, ...auditParameters, ...javaAgreement }
13
+ return { ...paramsAuth, ...auditParameters }
15
14
  }
16
15
 
17
16
  module.exports = {
@@ -1,8 +1,7 @@
1
1
  const { v4: uuidv4 } = require('uuid')
2
- const { setConfigValues } = require('../../utils/getConfig')
3
- const open = require('open')
2
+ const configFunctions = require('../../utils/getConfig')
4
3
  const commonApi = require('../../utils/commonApi')
5
- const { sleep } = require('../../utils/requestUtils')
4
+ const requestUtils = require('../../utils/requestUtils')
6
5
  const i18n = require('i18n')
7
6
  const {
8
7
  returnOra,
@@ -14,6 +13,9 @@ const { TIMEOUT, AUTH_UI_URL } = require('../../constants/constants')
14
13
  const parsedCLIOptions = require('../../utils/parsedCLIOptions')
15
14
  const constants = require('../../cliConstants')
16
15
  const commandLineUsage = require('command-line-usage')
16
+ const { commonMessageFormatter } = require('../../common/errorHandling')
17
+ const open = require('open')
18
+ const messages = require('../../constants/locales').en_locales()
17
19
 
18
20
  const processAuth = async (argv, config) => {
19
21
  let authParams = await parsedCLIOptions.getCommandLineArgsCustom(
@@ -28,6 +30,15 @@ const processAuth = async (argv, config) => {
28
30
  process.exit(0)
29
31
  }
30
32
 
33
+ //check if user has entered enterprise credentials
34
+ if (checkForCustomCredentials(authParams)) {
35
+ processCustomCredentials(authParams, config)
36
+ } else {
37
+ await startAuthProcess(config)
38
+ }
39
+ }
40
+
41
+ const startAuthProcess = async config => {
31
42
  const token = uuidv4()
32
43
  const url = `${AUTH_UI_URL}/?token=${token}`
33
44
 
@@ -41,9 +52,8 @@ const processAuth = async (argv, config) => {
41
52
 
42
53
  const result = await isAuthComplete(token, TIMEOUT, config)
43
54
  if (result) {
44
- setConfigValues(config, result)
55
+ configFunctions.setConfigValues(config, result)
45
56
  }
46
- return
47
57
  } finally {
48
58
  //spinner stop
49
59
  }
@@ -72,7 +82,7 @@ const isAuthComplete = async (token, timeout, config) => {
72
82
  }
73
83
 
74
84
  const pollAuthResult = async (token, client) => {
75
- await sleep(5000)
85
+ await requestUtils.sleep(5000)
76
86
  return client
77
87
  .pollForAuth(token)
78
88
  .then(res => {
@@ -94,6 +104,38 @@ const authUsageGuide = commandLineUsage([
94
104
  }
95
105
  ])
96
106
 
107
+ const checkForCustomCredentials = authParams => {
108
+ const hasSomeKeys =
109
+ authParams.apiKey ||
110
+ authParams.organizationId ||
111
+ authParams.host ||
112
+ authParams.authorization
113
+ const hasAllKeys =
114
+ authParams.apiKey &&
115
+ authParams.organizationId &&
116
+ authParams.host &&
117
+ authParams.authorization
118
+
119
+ if (hasAllKeys) {
120
+ return true
121
+ }
122
+ if (hasSomeKeys) {
123
+ commonMessageFormatter(messages.authCommand.credentialsMissing, true)
124
+ }
125
+ return false
126
+ }
127
+
128
+ const processCustomCredentials = (authParams, config) => {
129
+ const valuesToSet = {
130
+ apiKey: authParams.apiKey,
131
+ orgId: authParams.organizationId,
132
+ authHeader: authParams.authorization,
133
+ host: authParams.host
134
+ }
135
+ configFunctions.setConfigValues(config, valuesToSet)
136
+ commonMessageFormatter(messages.authCommand.credentialsAccepted, false)
137
+ }
138
+
97
139
  module.exports = {
98
- processAuth: processAuth
140
+ processAuth
99
141
  }
@@ -33,6 +33,9 @@ const scaUpload = require('../../../scaAnalysis/common/scaServicesUpload')
33
33
  const settingsHelper = require('../../../utils/settingsHelper')
34
34
  const chalk = require('chalk')
35
35
  const saveResults = require('../../../scan/saveResults')
36
+ const {
37
+ convertGenericToTypedReportModelSca
38
+ } = require('../../../scaAnalysis/common/utils/reportUtilsSca')
36
39
 
37
40
  const processSca = async config => {
38
41
  //checks to see whether to use old TS / new SCA path
@@ -133,12 +136,14 @@ const processSca = async config => {
133
136
  console.log('') //empty log for space before spinner
134
137
  const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
135
138
  startSpinner(reportSpinner)
136
- const [reports, reportId] = await scaUpload.scaTreeUpload(
139
+ const { reportArray, reportId } = await scaUpload.scaTreeUpload(
137
140
  messageToSend,
138
141
  config
139
142
  )
140
143
 
141
- auditReport.processAuditReport(config, reports[0])
144
+ const reportModelLibraryList =
145
+ convertGenericToTypedReportModelSca(reportArray)
146
+ auditReport.processAuditReport(config, reportModelLibraryList)
142
147
  succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
143
148
 
144
149
  if (config.save !== undefined) {
@@ -226,6 +226,7 @@ HTTPClient.prototype.scaServiceIngest = function scaServiceIngest(
226
226
  options.body = requestBody
227
227
  return requestUtils.sendRequest({ method: 'post', options })
228
228
  }
229
+
229
230
  HTTPClient.prototype.scaServiceReport = function scaServiceReport(
230
231
  config,
231
232
  reportId
@@ -460,21 +461,21 @@ function createSnapshotURL(config) {
460
461
  }
461
462
 
462
463
  function createScaServiceReportURL(config, reportId) {
463
- let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/applications/${config.applicationId}/reports/${reportId}`
464
+ let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/reports/${reportId}`
464
465
  baseUrl = config.ignoreDev ? baseUrl.concat('?nodesToInclude=PROD') : baseUrl
465
466
  return baseUrl
466
467
  }
467
468
 
468
469
  function createScaServiceReportStatusURL(config, reportId) {
469
- return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/${reportId}/status`
470
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests/${reportId}/status`
470
471
  }
471
472
 
472
473
  function createScaServiceIngestsURL(config) {
473
- return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests`
474
+ return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests`
474
475
  }
475
476
 
476
477
  function createScaServiceIngestURL(config) {
477
- let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/tree`
478
+ let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/applications/${config.applicationId}/libraries/ingests/tree`
478
479
  baseUrl = config.track ? baseUrl.concat('?persist=true') : baseUrl
479
480
  return baseUrl
480
481
  }