@contrast/contrast 1.0.5 → 1.0.8

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 (138) hide show
  1. package/.prettierignore +0 -5
  2. package/dist/audit/autodetection/autoDetectLanguage.js +3 -3
  3. package/dist/audit/catalogueApplication/catalogueApplication.js +23 -5
  4. package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +4 -2
  5. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
  6. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
  7. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
  8. package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +5 -5
  9. package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +9 -9
  10. package/dist/audit/languageAnalysisEngine/index.js +2 -2
  11. package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +6 -27
  12. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +25 -5
  13. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +99 -20
  14. package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +2 -1
  15. package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +24 -0
  16. package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +3 -1
  17. package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +16 -0
  18. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +35 -14
  19. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +58 -47
  20. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +65 -3
  21. package/dist/audit/save.js +29 -0
  22. package/dist/commands/audit/auditController.js +22 -6
  23. package/dist/commands/audit/help.js +24 -1
  24. package/dist/commands/audit/processAudit.js +8 -2
  25. package/dist/commands/audit/saveFile.js +7 -3
  26. package/dist/commands/scan/processScan.js +1 -1
  27. package/dist/commands/scan/sca/scaAnalysis.js +48 -11
  28. package/dist/common/HTTPClient.js +56 -15
  29. package/dist/common/errorHandling.js +6 -1
  30. package/dist/common/versionChecker.js +20 -5
  31. package/dist/constants/constants.js +13 -3
  32. package/dist/constants/locales.js +15 -12
  33. package/dist/constants.js +9 -4
  34. package/dist/index.js +4 -3
  35. package/dist/lambda/analytics.js +11 -0
  36. package/dist/lambda/lambda.js +35 -4
  37. package/dist/lambda/types.js +13 -0
  38. package/dist/sbom/generateSbom.js +4 -3
  39. package/dist/scaAnalysis/common/formatMessage.js +46 -1
  40. package/dist/scaAnalysis/common/treeUpload.js +1 -3
  41. package/dist/scaAnalysis/go/goAnalysis.js +17 -0
  42. package/dist/scaAnalysis/go/goParseDeps.js +158 -0
  43. package/dist/scaAnalysis/go/goReadDepFile.js +21 -0
  44. package/dist/scaAnalysis/java/analysis.js +11 -22
  45. package/dist/scaAnalysis/java/index.js +6 -6
  46. package/dist/scaAnalysis/java/javaBuildDepsParser.js +14 -1
  47. package/dist/scaAnalysis/javascript/analysis.js +110 -0
  48. package/dist/scaAnalysis/javascript/index.js +41 -0
  49. package/dist/scaAnalysis/php/analysis.js +89 -0
  50. package/dist/scaAnalysis/php/index.js +10 -0
  51. package/dist/scaAnalysis/python/analysis.js +42 -0
  52. package/dist/scaAnalysis/python/index.js +10 -0
  53. package/dist/scaAnalysis/ruby/analysis.js +226 -0
  54. package/dist/scaAnalysis/ruby/index.js +10 -0
  55. package/dist/scan/autoDetection.js +8 -4
  56. package/dist/scan/fileUtils.js +26 -8
  57. package/dist/scan/formatScanOutput.js +18 -17
  58. package/dist/scan/models/groupedResultsModel.js +1 -1
  59. package/dist/scan/models/scanResultsModel.js +3 -1
  60. package/dist/scan/populateProjectIdAndProjectName.js +2 -1
  61. package/dist/scan/scan.js +5 -3
  62. package/dist/scan/scanConfig.js +6 -1
  63. package/dist/scan/scanController.js +26 -6
  64. package/dist/scan/scanResults.js +20 -6
  65. package/dist/utils/commonApi.js +4 -1
  66. package/dist/utils/filterProjectPath.js +7 -2
  67. package/dist/utils/oraWrapper.js +5 -1
  68. package/package.json +13 -9
  69. package/src/audit/autodetection/autoDetectLanguage.ts +3 -3
  70. package/src/audit/catalogueApplication/catalogueApplication.js +28 -7
  71. package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +11 -8
  72. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
  73. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
  74. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
  75. package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +5 -5
  76. package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +11 -11
  77. package/src/audit/languageAnalysisEngine/index.js +2 -2
  78. package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +11 -31
  79. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +35 -32
  80. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +179 -25
  81. package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +3 -3
  82. package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +18 -11
  83. package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +29 -0
  84. package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +12 -3
  85. package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +20 -0
  86. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +50 -18
  87. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +88 -66
  88. package/src/audit/languageAnalysisEngine/sendSnapshot.js +78 -3
  89. package/src/audit/save.js +32 -0
  90. package/src/commands/audit/auditController.ts +23 -15
  91. package/src/commands/audit/help.ts +24 -1
  92. package/src/commands/audit/processAudit.ts +7 -4
  93. package/src/commands/audit/saveFile.ts +5 -1
  94. package/src/commands/scan/processScan.js +2 -1
  95. package/src/commands/scan/sca/scaAnalysis.js +70 -29
  96. package/src/common/HTTPClient.js +72 -25
  97. package/src/common/errorHandling.ts +10 -1
  98. package/src/common/versionChecker.ts +24 -5
  99. package/src/constants/constants.js +13 -3
  100. package/src/constants/locales.js +15 -12
  101. package/src/constants.js +9 -4
  102. package/src/index.ts +5 -3
  103. package/src/lambda/analytics.ts +9 -0
  104. package/src/lambda/arn.ts +2 -1
  105. package/src/lambda/lambda.ts +37 -17
  106. package/src/lambda/types.ts +35 -0
  107. package/src/lambda/utils.ts +2 -7
  108. package/src/sbom/generateSbom.ts +1 -1
  109. package/src/scaAnalysis/common/formatMessage.js +51 -1
  110. package/src/scaAnalysis/common/treeUpload.js +1 -6
  111. package/src/scaAnalysis/go/goAnalysis.js +19 -0
  112. package/src/scaAnalysis/go/goParseDeps.js +203 -0
  113. package/src/scaAnalysis/go/goReadDepFile.js +30 -0
  114. package/src/scaAnalysis/java/analysis.js +15 -32
  115. package/src/scaAnalysis/java/index.js +6 -6
  116. package/src/scaAnalysis/java/javaBuildDepsParser.js +15 -2
  117. package/src/scaAnalysis/javascript/analysis.js +127 -0
  118. package/src/scaAnalysis/javascript/index.js +56 -0
  119. package/src/scaAnalysis/php/analysis.js +98 -0
  120. package/src/scaAnalysis/php/index.js +11 -0
  121. package/src/scaAnalysis/python/analysis.js +49 -0
  122. package/src/scaAnalysis/python/index.js +11 -0
  123. package/src/scaAnalysis/ruby/analysis.js +282 -0
  124. package/src/scaAnalysis/ruby/index.js +11 -0
  125. package/src/scan/autoDetection.js +11 -7
  126. package/src/scan/fileUtils.js +27 -8
  127. package/src/scan/formatScanOutput.ts +26 -18
  128. package/src/scan/models/groupedResultsModel.ts +3 -3
  129. package/src/scan/models/resultContentModel.ts +1 -1
  130. package/src/scan/models/scanResultsModel.ts +5 -2
  131. package/src/scan/populateProjectIdAndProjectName.js +3 -1
  132. package/src/scan/scan.ts +8 -6
  133. package/src/scan/scanConfig.js +5 -1
  134. package/src/scan/scanController.js +30 -9
  135. package/src/scan/scanResults.js +31 -10
  136. package/src/utils/commonApi.js +4 -1
  137. package/src/utils/filterProjectPath.js +6 -2
  138. package/src/utils/oraWrapper.js +6 -1
@@ -3,70 +3,81 @@ 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.findNameAndVersion = exports.severityCount = exports.convertGenericToTypedLibraries = exports.findHighestSeverityCVE = void 0;
6
+ 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
9
  const constants_1 = __importDefault(require("../../../languageAnalysisEngine/constants"));
10
+ const constants_2 = require("../../../../constants/constants");
11
+ const lodash_1 = require("lodash");
12
+ const severityCountModel_1 = require("../models/severityCountModel");
10
13
  const { supportedLanguages: { GO } } = constants_1.default;
11
14
  function findHighestSeverityCVE(cveArray) {
12
- if (cveArray.find(cve => cve.cvss3SeverityCode === 'CRITICAL' || cve.severityCode === 'CRITICAL')) {
13
- return new reportSeverityModel_1.ReportSeverityModel('CRITICAL', 1);
15
+ const mappedToReportSeverityModels = cveArray.map(cve => findCVESeverity(cve));
16
+ return (0, lodash_1.orderBy)(mappedToReportSeverityModels, cve => cve?.priority)[0];
17
+ }
18
+ exports.findHighestSeverityCVE = findHighestSeverityCVE;
19
+ function findCVESeveritiesAndOrderByHighestPriority(cves) {
20
+ return (0, lodash_1.orderBy)(cves.map(cve => findCVESeverity(cve)), ['priority'], ['asc']);
21
+ }
22
+ exports.findCVESeveritiesAndOrderByHighestPriority = findCVESeveritiesAndOrderByHighestPriority;
23
+ function findCVESeverity(cve) {
24
+ const cveName = cve.name;
25
+ if (cve.cvss3SeverityCode === 'CRITICAL' || cve.severityCode === 'CRITICAL') {
26
+ return new reportSeverityModel_1.ReportSeverityModel('CRITICAL', constants_2.CRITICAL_PRIORITY, constants_2.CRITICAL_COLOUR, cveName);
14
27
  }
15
- else if (cveArray.find(cve => cve.cvss3SeverityCode === 'HIGH' || cve.severityCode === 'HIGH')) {
16
- return new reportSeverityModel_1.ReportSeverityModel('HIGH', 2);
28
+ else if (cve.cvss3SeverityCode === 'HIGH' || cve.severityCode === 'HIGH') {
29
+ return new reportSeverityModel_1.ReportSeverityModel('HIGH', constants_2.HIGH_PRIORITY, constants_2.HIGH_COLOUR, cveName);
17
30
  }
18
- else if (cveArray.find(cve => cve.cvss3SeverityCode === 'MEDIUM' || cve.severityCode === 'MEDIUM')) {
19
- return new reportSeverityModel_1.ReportSeverityModel('MEDIUM', 3);
31
+ else if (cve.cvss3SeverityCode === 'MEDIUM' ||
32
+ cve.severityCode === 'MEDIUM') {
33
+ return new reportSeverityModel_1.ReportSeverityModel('MEDIUM', constants_2.MEDIUM_PRIORITY, constants_2.MEDIUM_COLOUR, cveName);
20
34
  }
21
- else if (cveArray.find(cve => cve.cvss3SeverityCode === 'LOW' || cve.severityCode === 'LOW')) {
22
- return new reportSeverityModel_1.ReportSeverityModel('LOW', 4);
35
+ else if (cve.cvss3SeverityCode === 'LOW' || cve.severityCode === 'LOW') {
36
+ return new reportSeverityModel_1.ReportSeverityModel('LOW', constants_2.LOW_PRIORITY, constants_2.LOW_COLOUR, cveName);
23
37
  }
24
- else if (cveArray.find(cve => cve.cvss3SeverityCode === 'NOTE' || cve.severityCode === 'NOTE')) {
25
- return new reportSeverityModel_1.ReportSeverityModel('NOTE', 5);
38
+ else if (cve.cvss3SeverityCode === 'NOTE' || cve.severityCode === 'NOTE') {
39
+ return new reportSeverityModel_1.ReportSeverityModel('NOTE', constants_2.NOTE_PRIORITY, constants_2.NOTE_COLOUR, cveName);
26
40
  }
27
41
  }
28
- exports.findHighestSeverityCVE = findHighestSeverityCVE;
29
- function convertGenericToTypedLibraries(libraries) {
42
+ exports.findCVESeverity = findCVESeverity;
43
+ function convertGenericToTypedLibraryVulns(libraries) {
30
44
  return Object.entries(libraries).map(([name, cveArray]) => {
31
45
  return new reportLibraryModel_1.ReportLibraryModel(name, cveArray);
32
46
  });
33
47
  }
34
- exports.convertGenericToTypedLibraries = convertGenericToTypedLibraries;
35
- function severityCount(vulnerableLibraries) {
36
- const severityCount = {
37
- critical: 0,
38
- high: 0,
39
- medium: 0,
40
- low: 0,
41
- note: 0
42
- };
43
- vulnerableLibraries.forEach(lib => {
44
- lib.cveArray.forEach(cve => {
45
- if (cve.cvss3SeverityCode === 'CRITICAL' ||
46
- cve.severityCode === 'CRITICAL') {
47
- severityCount['critical'] += 1;
48
- }
49
- else if (cve.cvss3SeverityCode === 'HIGH' ||
50
- cve.severityCode === 'HIGH') {
51
- severityCount['high'] += 1;
52
- }
53
- else if (cve.cvss3SeverityCode === 'MEDIUM' ||
54
- cve.severityCode === 'MEDIUM') {
55
- severityCount['medium'] += 1;
56
- }
57
- else if (cve.cvss3SeverityCode === 'LOW' ||
58
- cve.severityCode === 'LOW') {
59
- severityCount['low'] += 1;
60
- }
61
- else if (cve.cvss3SeverityCode === 'NOTE' ||
62
- cve.severityCode === 'NOTE') {
63
- severityCount['note'] += 1;
64
- }
65
- });
66
- });
48
+ exports.convertGenericToTypedLibraryVulns = convertGenericToTypedLibraryVulns;
49
+ function severityCountAllLibraries(vulnerableLibraries) {
50
+ const severityCount = new severityCountModel_1.SeverityCountModel();
51
+ vulnerableLibraries.forEach(lib => severityCountAllCVEs(lib.cveArray, severityCount));
52
+ return severityCount;
53
+ }
54
+ exports.severityCountAllLibraries = severityCountAllLibraries;
55
+ function severityCountAllCVEs(cveArray, severityCount) {
56
+ const severityCountInner = severityCount;
57
+ cveArray.forEach(cve => severityCountSingleCVE(cve, severityCountInner));
58
+ return severityCountInner;
59
+ }
60
+ exports.severityCountAllCVEs = severityCountAllCVEs;
61
+ function severityCountSingleCVE(cve, severityCount) {
62
+ if (cve.cvss3SeverityCode === 'CRITICAL' || cve.severityCode === 'CRITICAL') {
63
+ severityCount.critical += 1;
64
+ }
65
+ else if (cve.cvss3SeverityCode === 'HIGH' || cve.severityCode === 'HIGH') {
66
+ severityCount.high += 1;
67
+ }
68
+ else if (cve.cvss3SeverityCode === 'MEDIUM' ||
69
+ cve.severityCode === 'MEDIUM') {
70
+ severityCount.medium += 1;
71
+ }
72
+ else if (cve.cvss3SeverityCode === 'LOW' || cve.severityCode === 'LOW') {
73
+ severityCount.low += 1;
74
+ }
75
+ else if (cve.cvss3SeverityCode === 'NOTE' || cve.severityCode === 'NOTE') {
76
+ severityCount.note += 1;
77
+ }
67
78
  return severityCount;
68
79
  }
69
- exports.severityCount = severityCount;
80
+ exports.severityCountSingleCVE = severityCountSingleCVE;
70
81
  function findNameAndVersion(library, config) {
71
82
  if (config.language.toUpperCase() === GO) {
72
83
  const nameVersion = library.name.split('@');
@@ -1,7 +1,13 @@
1
1
  "use strict";
2
- const { getHttpClient } = require('../../utils/commonApi');
3
2
  const { handleResponseErrors } = require('../../common/errorHandling');
4
3
  const { APP_VERSION } = require('../../constants/constants');
4
+ const commonApi = require('../../utils/commonApi');
5
+ const _ = require('lodash');
6
+ const oraFunctions = require('../../utils/oraWrapper');
7
+ const i18n = require('i18n');
8
+ const oraWrapper = require('../../utils/oraWrapper');
9
+ const requestUtils = require('../../utils/requestUtils');
10
+ const { performance } = require('perf_hooks');
5
11
  const newSendSnapShot = async (analysis) => {
6
12
  const analysisLanguage = analysis.config.language.toLowerCase();
7
13
  const requestBody = {
@@ -9,7 +15,7 @@ const newSendSnapShot = async (analysis) => {
9
15
  cliVersion: APP_VERSION,
10
16
  snapshot: { [analysisLanguage]: analysis[analysisLanguage] }
11
17
  };
12
- const client = getHttpClient(analysis.config);
18
+ const client = commonApi.getHttpClient(analysis.config);
13
19
  return client
14
20
  .sendSnapshot(requestBody, analysis.config)
15
21
  .then(res => {
@@ -24,6 +30,62 @@ const newSendSnapShot = async (analysis) => {
24
30
  console.log(err);
25
31
  });
26
32
  };
33
+ const pollSnapshotResults = async (config, snapshotId, client) => {
34
+ await requestUtils.sleep(5000);
35
+ return client
36
+ .getReportStatusById(config, snapshotId)
37
+ .then(res => {
38
+ return res;
39
+ })
40
+ .catch(err => {
41
+ console.log(err);
42
+ });
43
+ };
44
+ const getTimeout = config => {
45
+ if (config.timeout) {
46
+ return config.timeout;
47
+ }
48
+ else {
49
+ if (config.verbose) {
50
+ console.log('Timeout set to 2 minutes');
51
+ }
52
+ return 120;
53
+ }
54
+ };
55
+ const pollForSnapshotCompletition = async (config, snapshotId, reportSpinner) => {
56
+ const client = commonApi.getHttpClient(config);
57
+ const startTime = performance.now();
58
+ const timeout = getTimeout(config);
59
+ let complete = false;
60
+ if (!_.isNil(snapshotId)) {
61
+ while (!complete) {
62
+ let result = await pollSnapshotResults(config, snapshotId, client);
63
+ if (result.statusCode === 200) {
64
+ if (result.body.status === 'PROCESSED') {
65
+ complete = true;
66
+ return result.body;
67
+ }
68
+ if (result.body.status === 'FAILED') {
69
+ complete = true;
70
+ if (config.debug) {
71
+ oraFunctions.failSpinner(reportSpinner, i18n.__('auditNotCompleted'));
72
+ }
73
+ console.log(result.body.errorMessage);
74
+ oraWrapper.stopSpinner(reportSpinner);
75
+ console.log('Contrast audit finished');
76
+ process.exit(1);
77
+ }
78
+ }
79
+ const endTime = performance.now() - startTime;
80
+ if (requestUtils.millisToSeconds(endTime) > timeout) {
81
+ oraFunctions.failSpinner(reportSpinner, 'Contrast audit timed out at the specified ' + timeout + ' seconds.');
82
+ console.log('Please try again, allowing more time.');
83
+ process.exit(1);
84
+ }
85
+ }
86
+ }
87
+ };
27
88
  module.exports = {
28
- newSendSnapShot: newSendSnapShot
89
+ newSendSnapShot: newSendSnapShot,
90
+ pollForSnapshotCompletition: pollForSnapshotCompletition
29
91
  };
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ const fs = require('fs');
3
+ const i18n = require('i18n');
4
+ const chalk = require('chalk');
5
+ const save = require('../commands/audit/saveFile');
6
+ const sbom = require('../sbom/generateSbom');
7
+ async function auditSave(config) {
8
+ if (config.save) {
9
+ if (config.save.toLowerCase() === 'sbom') {
10
+ save.saveFile(config, await sbom.generateSbom(config));
11
+ const filename = `${config.applicationId}-sbom-cyclonedx.json`;
12
+ if (fs.existsSync(filename)) {
13
+ console.log(i18n.__('auditSBOMSaveSuccess') + ` - ${filename}`);
14
+ }
15
+ else {
16
+ console.log(chalk.yellow.bold(`\n Unable to save ${filename} Software Bill of Materials (SBOM)`));
17
+ }
18
+ }
19
+ else {
20
+ console.log(i18n.__('auditBadFiletypeSpecifiedForSave'));
21
+ }
22
+ }
23
+ else if (config.save === null) {
24
+ console.log(i18n.__('auditNoFiletypeSpecifiedForSave'));
25
+ }
26
+ }
27
+ module.exports = {
28
+ auditSave
29
+ };
@@ -3,12 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.startAudit = exports.dealWithNoAppId = void 0;
6
+ exports.getAppName = exports.startAudit = exports.dealWithNoAppId = void 0;
7
7
  const catalogueApplication_1 = require("../../audit/catalogueApplication/catalogueApplication");
8
8
  const commonApi_1 = __importDefault(require("../../audit/languageAnalysisEngine/commonApi"));
9
9
  const identifyLanguageAE = require('./../../audit/languageAnalysisEngine');
10
10
  const languageFactory = require('../../audit/languageAnalysisEngine/languageAnalysisFactory');
11
- const { v4: uuidv4 } = require('uuid');
12
11
  const dealWithNoAppId = async (config) => {
13
12
  let appID;
14
13
  try {
@@ -17,13 +16,16 @@ const dealWithNoAppId = async (config) => {
17
16
  return await (0, catalogueApplication_1.catalogueApplication)(config);
18
17
  }
19
18
  if (!appID && !config.applicationName) {
20
- config.applicationName = uuidv4();
21
- return await (0, catalogueApplication_1.catalogueApplication)(config);
19
+ config.applicationName = (0, exports.getAppName)(config.file);
20
+ appID = await commonApi_1.default.returnAppId(config);
21
+ if (!appID) {
22
+ return await (0, catalogueApplication_1.catalogueApplication)(config);
23
+ }
22
24
  }
23
25
  }
24
26
  catch (e) {
25
27
  if (e.toString().includes('tunneling socket could not be established')) {
26
- console.log(e.message);
28
+ console.log(e.message.toString());
27
29
  console.log('There seems to be an issue with your proxy, please check and try again');
28
30
  }
29
31
  process.exit(1);
@@ -35,6 +37,20 @@ const startAudit = async (config) => {
35
37
  if (!config.applicationId) {
36
38
  config.applicationId = await (0, exports.dealWithNoAppId)(config);
37
39
  }
38
- identifyLanguageAE(config.projectPath, languageFactory, config.applicationId, config);
40
+ identifyLanguageAE(config.file, languageFactory, config.applicationId, config);
39
41
  };
40
42
  exports.startAudit = startAudit;
43
+ const getAppName = (file) => {
44
+ const last = file.charAt(file.length - 1);
45
+ if (last !== '/') {
46
+ return file.split('/').pop();
47
+ }
48
+ else {
49
+ const str = removeLastChar(file);
50
+ return str.split('/').pop();
51
+ }
52
+ };
53
+ exports.getAppName = getAppName;
54
+ const removeLastChar = (str) => {
55
+ return str.substring(0, str.length - 1);
56
+ };
@@ -46,7 +46,30 @@ const auditUsageGuide = (0, command_line_usage_1.default)([
46
46
  },
47
47
  {
48
48
  header: i18n_1.default.__('constantsAuditOptions'),
49
- optionList: constants_1.default.commandLineDefinitions.auditOptionDefinitions
49
+ optionList: constants_1.default.commandLineDefinitions.auditOptionDefinitions,
50
+ hide: [
51
+ 'application-id',
52
+ 'application-name',
53
+ 'organization-id',
54
+ 'api-key',
55
+ 'authorization',
56
+ 'host',
57
+ 'proxy',
58
+ 'help',
59
+ 'ff',
60
+ 'ignore-cert-errors',
61
+ 'verbose',
62
+ 'debug',
63
+ 'experimental',
64
+ 'tags',
65
+ 'sub-project',
66
+ 'code',
67
+ 'maven-settings-path',
68
+ 'language',
69
+ 'experimental',
70
+ 'app-groups',
71
+ 'metadata'
72
+ ]
50
73
  }
51
74
  ]);
52
75
  exports.auditUsageGuide = auditUsageGuide;
@@ -4,13 +4,19 @@ exports.processAudit = void 0;
4
4
  const auditController_1 = require("./auditController");
5
5
  const auditConfig_1 = require("./auditConfig");
6
6
  const help_1 = require("./help");
7
+ const scaAnalysis_1 = require("../scan/sca/scaAnalysis");
7
8
  const processAudit = async (argv) => {
8
9
  if (argv.indexOf('--help') != -1) {
9
10
  printHelpMessage();
10
- process.exit(1);
11
+ process.exit(0);
11
12
  }
12
13
  const config = (0, auditConfig_1.getAuditConfig)(argv);
13
- const auditResults = await (0, auditController_1.startAudit)(config);
14
+ if (config.experimental) {
15
+ await (0, scaAnalysis_1.processSca)(config);
16
+ }
17
+ else {
18
+ await (0, auditController_1.startAudit)(config);
19
+ }
14
20
  };
15
21
  exports.processAudit = processAudit;
16
22
  const printHelpMessage = () => {
@@ -3,9 +3,13 @@ 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.saveFile = void 0;
6
7
  const fs_1 = __importDefault(require("fs"));
7
- function saveFile(config, rawResults) {
8
+ const saveFile = (config, rawResults) => {
8
9
  const fileName = `${config.applicationId}-sbom-cyclonedx.json`;
9
10
  fs_1.default.writeFileSync(fileName, JSON.stringify(rawResults));
10
- }
11
- exports.default = saveFile;
11
+ };
12
+ exports.saveFile = saveFile;
13
+ module.exports = {
14
+ saveFile: exports.saveFile
15
+ };
@@ -11,7 +11,7 @@ const processScan = async (argvMain) => {
11
11
  await processSca(config);
12
12
  }
13
13
  let scanResults = new ScanResultsModel(await startScan(config));
14
- if (scanResults) {
14
+ if (scanResults.scanResultsInstances !== undefined) {
15
15
  formatScanOutput(scanResults);
16
16
  }
17
17
  if (config.save !== undefined) {
@@ -1,41 +1,78 @@
1
1
  "use strict";
2
2
  const autoDetection = require('../../../scan/autoDetection');
3
- const { javaAnalysis } = require('../../../scaAnalysis/java');
4
- const { commonSendSnapShot } = require('../../../scaAnalysis/common/treeUpload');
3
+ const javaAnalysis = require('../../../scaAnalysis/java');
4
+ const treeUpload = require('../../../scaAnalysis/common/treeUpload');
5
5
  const { manualDetectAuditFilesAndLanguages } = require('../../../scan/autoDetection');
6
- const { dealWithNoAppId } = require('../../audit/auditController');
7
- const { supportedLanguages: { JAVA } } = require('../../../audit/languageAnalysisEngine/constants');
6
+ const auditController = require('../../audit/auditController');
7
+ const { supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP } } = require('../../../audit/languageAnalysisEngine/constants');
8
+ const goAnalysis = require('../../../scaAnalysis/go/goAnalysis');
9
+ const phpAnalysis = require('../../../scaAnalysis/php/index');
10
+ const { rubyAnalysis } = require('../../../scaAnalysis/ruby');
11
+ const { pythonAnalysis } = require('../../../scaAnalysis/python');
12
+ const javascriptAnalysis = require('../../../scaAnalysis/javascript');
13
+ const { pollForSnapshotCompletition } = require('../../../audit/languageAnalysisEngine/sendSnapshot');
14
+ const { returnOra, startSpinner, succeedSpinner } = require('../../../utils/oraWrapper');
15
+ const i18n = require('i18n');
16
+ const { vulnerabilityReportV2 } = require('../../../audit/languageAnalysisEngine/report/reportingFeature');
17
+ const auditSave = require('../../../audit/save');
8
18
  const processSca = async (config) => {
9
19
  let filesFound;
10
- if (config.projectPath) {
11
- filesFound = await manualDetectAuditFilesAndLanguages(config.projectPath);
20
+ if (config.file) {
21
+ config.file = config.file.concat('/');
22
+ filesFound = await manualDetectAuditFilesAndLanguages(config.file);
12
23
  }
13
24
  else {
14
25
  filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config);
26
+ config.file = process.cwd().concat('/');
15
27
  }
16
28
  let messageToSend = undefined;
17
29
  if (filesFound.length === 1) {
18
30
  switch (Object.keys(filesFound[0])[0]) {
19
31
  case JAVA:
20
- messageToSend = await javaAnalysis(config, filesFound[0]);
32
+ messageToSend = javaAnalysis.javaAnalysis(config, filesFound[0]);
21
33
  config.language = JAVA;
22
34
  break;
35
+ case JAVASCRIPT:
36
+ messageToSend = await javascriptAnalysis.jsAnalysis(config, filesFound[0]);
37
+ config.language = NODE;
38
+ break;
39
+ case PYTHON:
40
+ messageToSend = pythonAnalysis(config, filesFound[0]);
41
+ config.language = PYTHON;
42
+ break;
43
+ case RUBY:
44
+ messageToSend = rubyAnalysis(config, filesFound[0]);
45
+ config.language = RUBY;
46
+ break;
47
+ case 'PHP':
48
+ messageToSend = phpAnalysis.phpAnalysis(config, filesFound[0]);
49
+ config.language = PHP;
50
+ break;
51
+ case GO:
52
+ messageToSend = goAnalysis.goAnalysis(config, filesFound[0]);
53
+ config.language = GO;
54
+ break;
23
55
  default:
24
56
  console.log('language detected not supported');
25
57
  return;
26
58
  }
27
59
  if (!config.applicationId) {
28
- config.applicationId = await dealWithNoAppId(config);
60
+ config.applicationId = await auditController.dealWithNoAppId(config);
29
61
  }
30
- console.log('processing dependencies');
31
- const response = await commonSendSnapShot(messageToSend, config);
62
+ const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
63
+ startSpinner(reportSpinner);
64
+ const snapshotResponse = await treeUpload.commonSendSnapShot(messageToSend, config);
65
+ await pollForSnapshotCompletition(config, snapshotResponse.id, reportSpinner);
66
+ succeedSpinner(reportSpinner, 'Contrast SCA audit complete');
67
+ await vulnerabilityReportV2(config, snapshotResponse.id);
68
+ await auditSave.auditSave(config);
32
69
  }
33
70
  else {
34
71
  if (filesFound.length === 0) {
35
72
  console.log('no compatible dependency files detected. Continuing...');
36
73
  }
37
74
  else {
38
- console.log('multiple language files detected, please use --project-path to specify a directory or the file where dependencies are declared');
75
+ console.log('multiple language files detected, please use --file to specify a directory or the file where dependencies are declared');
39
76
  }
40
77
  }
41
78
  };
@@ -20,7 +20,8 @@ function HTTPClient(config) {
20
20
  Authorization: authToken,
21
21
  'API-Key': apiKey,
22
22
  SuperAuthorization: superAuthToken,
23
- 'Super-API-Key': superApiKey
23
+ 'Super-API-Key': superApiKey,
24
+ 'User-Agent': 'contrast-cli-v2'
24
25
  }
25
26
  };
26
27
  if (config.proxy) {
@@ -66,10 +67,24 @@ HTTPClient.prototype.getSpecificScanResult = function getSpecificScanResult(conf
66
67
  options.url = url;
67
68
  return requestUtils.sendRequest({ method: 'get', options });
68
69
  };
69
- HTTPClient.prototype.getSpecificScanResultSarif = function getSpecificScanResultSarif(config, scanId) {
70
+ HTTPClient.prototype.getSpecificScanResultSarif =
71
+ function getSpecificScanResultSarif(config, scanId) {
72
+ const options = _.cloneDeep(this.requestOptions);
73
+ options.url = createRawOutputURL(config, scanId);
74
+ return requestUtils.sendRequest({ method: 'get', options });
75
+ };
76
+ HTTPClient.prototype.createNewEvent = function createNewEvent(config, scanId, newProject) {
70
77
  const options = _.cloneDeep(this.requestOptions);
71
- options.url = createRawOutputURL(config, scanId);
72
- return requestUtils.sendRequest({ method: 'get', options });
78
+ options.url = createEventCollectorURL(config, scanId);
79
+ options.body = {
80
+ eventSource: process.env.CODESEC_INVOCATION_ENVIRONMENT,
81
+ trackingProperties: {
82
+ projectNameSource: config.projectNameSource,
83
+ waitedForResults: !config.ff,
84
+ newProject
85
+ }
86
+ };
87
+ return requestUtils.sendRequest({ method: 'post', options });
73
88
  };
74
89
  HTTPClient.prototype.getScanId = function getScanId(config, codeArtifactId) {
75
90
  const options = _.cloneDeep(this.requestOptions);
@@ -145,8 +160,6 @@ HTTPClient.prototype.catalogueCommand = function catalogueCommand(config) {
145
160
  return requestUtils.sendRequest({ method: 'post', options });
146
161
  };
147
162
  HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
148
- if (config.language.toUpperCase() === 'RUBY') {
149
- }
150
163
  const options = _.cloneDeep(this.requestOptions);
151
164
  let url = createSnapshotURL(config);
152
165
  options.url = url;
@@ -163,12 +176,18 @@ HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
163
176
  }
164
177
  return requestUtils.sendRequest({ method: 'get', options });
165
178
  };
166
- HTTPClient.prototype.getLibraryVulnerabilities = function getLibraryVulnerabilities(config, requestBody) {
179
+ HTTPClient.prototype.getReportStatusById = function getReportStatusById(config, snapshotId) {
167
180
  const options = _.cloneDeep(this.requestOptions);
168
- options.url = createLibraryVulnerabilitiesUrl(config);
169
- options.body = requestBody;
170
- return requestUtils.sendRequest({ method: 'put', options });
181
+ options.url = createSpecificReportStatusURL(config, snapshotId);
182
+ return requestUtils.sendRequest({ method: 'get', options });
171
183
  };
184
+ HTTPClient.prototype.getLibraryVulnerabilities =
185
+ function getLibraryVulnerabilities(config, requestBody) {
186
+ const options = _.cloneDeep(this.requestOptions);
187
+ options.url = createLibraryVulnerabilitiesUrl(config);
188
+ options.body = requestBody;
189
+ return requestUtils.sendRequest({ method: 'put', options });
190
+ };
172
191
  HTTPClient.prototype.getAppId = function getAppId(config) {
173
192
  const options = _.cloneDeep(this.requestOptions);
174
193
  let url = createAppNameUrl(config);
@@ -210,11 +229,12 @@ HTTPClient.prototype.getScanResources = async function getScanResources(config,
210
229
  const options = { ...this.requestOptions, url };
211
230
  return requestUtils.sendRequest({ method: 'get', options });
212
231
  };
213
- HTTPClient.prototype.getFunctionScanResults = async function getFunctionScanResults(config, params, scanId, functionArn) {
214
- const url = createScanResultsGetUrl(config, params, scanId, functionArn);
215
- const options = { ...this.requestOptions, url };
216
- return requestUtils.sendRequest({ method: 'get', options });
217
- };
232
+ HTTPClient.prototype.getFunctionScanResults =
233
+ async function getFunctionScanResults(config, params, scanId, functionArn) {
234
+ const url = createScanResultsGetUrl(config, params, scanId, functionArn);
235
+ const options = { ...this.requestOptions, url };
236
+ return requestUtils.sendRequest({ method: 'get', options });
237
+ };
218
238
  HTTPClient.prototype.checkLibrary = function checkLibrary(data) {
219
239
  const options = _.cloneDeep(this.requestOptions);
220
240
  let url = createDataUrl();
@@ -227,6 +247,21 @@ HTTPClient.prototype.getSbom = function getSbom(config) {
227
247
  options.url = createSbomCycloneDXUrl(config);
228
248
  return requestUtils.sendRequest({ method: 'get', options });
229
249
  };
250
+ HTTPClient.prototype.getLatestVersion = function getLatestVersion() {
251
+ const options = _.cloneDeep(this.requestOptions);
252
+ options.url =
253
+ 'https://pkg.contrastsecurity.com/artifactory/cli/latest-version.txt';
254
+ return requestUtils.sendRequest({ method: 'get', options });
255
+ };
256
+ HTTPClient.prototype.postAnalyticsFunction = function (config, provider, body) {
257
+ const url = createAnalyticsFunctionPostUrl(config, provider);
258
+ const options = { ...this.requestOptions, body, url };
259
+ return requestUtils.sendRequest({ method: 'post', options });
260
+ };
261
+ const createAnalyticsFunctionPostUrl = (config, provider) => {
262
+ const url = getServerlessHost(config);
263
+ return `${url}/organizations/${config.organizationId}/providers/${provider}/analytics`;
264
+ };
230
265
  const createGetScanIdURL = config => {
231
266
  return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}/scans/`;
232
267
  };
@@ -248,6 +283,9 @@ function createHarmonyProjectsUrl(config) {
248
283
  function createScanProjectUrl(config) {
249
284
  return `${config.host}/Contrast/api/sast/v1/organizations/${config.organizationId}/projects/${config.projectId}`;
250
285
  }
286
+ const createEventCollectorURL = (config, scanId) => {
287
+ return `${config.host}/Contrast/api/sast/organizations/${config.organizationId}/projects/${config.projectId}/scans/${scanId}/events`;
288
+ };
251
289
  const createGlobalPropertiesUrl = protocol => {
252
290
  return `${protocol}/Contrast/api/ng/global/properties`;
253
291
  };
@@ -272,6 +310,9 @@ function createSpecificReportUrl(config, reportId) {
272
310
  function createSpecificReportWithProdUrl(config, reportId) {
273
311
  return createSpecificReportUrl(config, reportId).concat(`?nodesToInclude=PROD`);
274
312
  }
313
+ function createSpecificReportStatusURL(config, reportId) {
314
+ return `${config.host}/Contrast/api/ng/sca/organizations/${config.organizationId}/applications/${config.applicationId}/snapshots/${reportId}/status`;
315
+ }
275
316
  function createDataUrl() {
276
317
  return `https://ardy.contrastsecurity.com/production`;
277
318
  }
@@ -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.reportFailureError = exports.vulnerabilitiesFailureError = exports.snapshotFailureError = exports.findCommandOnError = exports.libraryAnalysisError = exports.handleResponseErrors = exports.getErrorMessage = exports.generalError = exports.failOptionError = exports.proxyError = exports.forbiddenError = exports.badRequestError = exports.unauthenticatedError = exports.genericError = void 0;
6
+ exports.maxAppError = exports.reportFailureError = exports.vulnerabilitiesFailureError = exports.snapshotFailureError = exports.findCommandOnError = exports.libraryAnalysisError = exports.handleResponseErrors = exports.getErrorMessage = exports.generalError = exports.failOptionError = exports.proxyError = exports.forbiddenError = exports.badRequestError = exports.unauthenticatedError = exports.genericError = void 0;
7
7
  const i18n_1 = __importDefault(require("i18n"));
8
8
  const handleResponseErrors = (res, api) => {
9
9
  if (res.statusCode === 400) {
@@ -72,6 +72,11 @@ const proxyError = () => {
72
72
  generalError('proxyErrorHeader', 'proxyErrorMessage');
73
73
  };
74
74
  exports.proxyError = proxyError;
75
+ const maxAppError = () => {
76
+ generalError('No applications remaining', 'You have reached the maximum number of application you can create.');
77
+ process.exit(1);
78
+ };
79
+ exports.maxAppError = maxAppError;
75
80
  const failOptionError = () => {
76
81
  console.log('\n ******************************** ' +
77
82
  i18n_1.default.__('snapshotFailureHeader') +