@contrast/contrast 1.0.0 → 1.0.1

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 (201) hide show
  1. package/.prettierignore +2 -0
  2. package/README.md +120 -47
  3. package/dist/audit/AnalysisEngine.js +37 -0
  4. package/dist/audit/catalogueApplication/catalogueApplication.js +36 -0
  5. package/dist/audit/dotnetAnalysisEngine/index.js +25 -0
  6. package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +35 -0
  7. package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +15 -0
  8. package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +18 -0
  9. package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +14 -0
  10. package/dist/audit/dotnetAnalysisEngine/sanitizer.js +9 -0
  11. package/dist/audit/goAnalysisEngine/index.js +17 -0
  12. package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +164 -0
  13. package/dist/audit/goAnalysisEngine/readProjectFileContents.js +21 -0
  14. package/dist/audit/goAnalysisEngine/sanitizer.js +5 -0
  15. package/dist/audit/javaAnalysisEngine/index.js +34 -0
  16. package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +153 -0
  17. package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +353 -0
  18. package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +98 -0
  19. package/dist/audit/javaAnalysisEngine/sanitizer.js +5 -0
  20. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +24 -0
  21. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +24 -0
  22. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +35 -0
  23. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +23 -0
  24. package/dist/audit/languageAnalysisEngine/commonApi.js +18 -0
  25. package/dist/audit/languageAnalysisEngine/constants.js +20 -0
  26. package/dist/audit/languageAnalysisEngine/filterProjectPath.js +20 -0
  27. package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +25 -0
  28. package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +39 -0
  29. package/dist/audit/languageAnalysisEngine/index.js +39 -0
  30. package/dist/audit/languageAnalysisEngine/langugageAnalysisFactory.js +70 -0
  31. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +121 -0
  32. package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +17 -0
  33. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +257 -0
  34. package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +81 -0
  35. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +133 -0
  36. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +41 -0
  37. package/dist/audit/languageAnalysisEngine/util/capabilities.js +11 -0
  38. package/dist/audit/languageAnalysisEngine/util/generalAPI.js +39 -0
  39. package/dist/audit/languageAnalysisEngine/util/requestUtils.js +14 -0
  40. package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +40 -0
  41. package/dist/audit/nodeAnalysisEngine/index.js +31 -0
  42. package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +18 -0
  43. package/dist/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +51 -0
  44. package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +18 -0
  45. package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +17 -0
  46. package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +14 -0
  47. package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +24 -0
  48. package/dist/audit/nodeAnalysisEngine/sanitizer.js +9 -0
  49. package/dist/audit/phpAnalysisEngine/index.js +23 -0
  50. package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +52 -0
  51. package/dist/audit/phpAnalysisEngine/readLockFileContents.js +13 -0
  52. package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +16 -0
  53. package/dist/audit/phpAnalysisEngine/sanitizer.js +5 -0
  54. package/dist/audit/pythonAnalysisEngine/index.js +25 -0
  55. package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +17 -0
  56. package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +21 -0
  57. package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +13 -0
  58. package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +14 -0
  59. package/dist/audit/pythonAnalysisEngine/sanitizer.js +7 -0
  60. package/dist/audit/rubyAnalysisEngine/index.js +25 -0
  61. package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +176 -0
  62. package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +22 -0
  63. package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +14 -0
  64. package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +14 -0
  65. package/dist/audit/rubyAnalysisEngine/sanitizer.js +6 -0
  66. package/dist/commands/audit/auditConfig.js +25 -0
  67. package/dist/commands/audit/auditController.js +31 -0
  68. package/dist/commands/audit/help.js +52 -0
  69. package/dist/commands/audit/processAudit.js +18 -0
  70. package/dist/commands/auth/auth.js +1 -1
  71. package/dist/commands/scan/processScan.js +19 -5
  72. package/dist/common/HTTPClient.js +101 -13
  73. package/dist/common/errorHandling.js +49 -1
  74. package/dist/common/findLatestCLIVersion.js +23 -0
  75. package/dist/constants/constants.js +1 -1
  76. package/dist/constants/lambda.js +32 -4
  77. package/dist/constants/locales.js +39 -16
  78. package/dist/constants.js +148 -20
  79. package/dist/index.js +7 -1
  80. package/dist/lambda/aws.js +14 -11
  81. package/dist/lambda/help.js +4 -0
  82. package/dist/lambda/lambda.js +50 -27
  83. package/dist/lambda/lambdaUtils.js +72 -0
  84. package/dist/lambda/logUtils.js +11 -1
  85. package/dist/lambda/scanDetailCompletion.js +4 -4
  86. package/dist/lambda/scanRequest.js +11 -5
  87. package/dist/lambda/utils.js +110 -53
  88. package/dist/scan/autoDetection.js +0 -32
  89. package/dist/scan/fileUtils.js +1 -1
  90. package/dist/scan/help.js +12 -40
  91. package/dist/scan/populateProjectIdAndProjectName.js +4 -0
  92. package/dist/scan/saveResults.js +15 -0
  93. package/dist/scan/scan.js +77 -42
  94. package/dist/scan/scanConfig.js +20 -0
  95. package/dist/scan/scanController.js +13 -15
  96. package/dist/scan/scanResults.js +18 -16
  97. package/dist/utils/commonApi.js +3 -3
  98. package/dist/utils/fileUtils.js +31 -0
  99. package/dist/utils/paramsUtil/commandlineParams.js +1 -20
  100. package/dist/utils/paramsUtil/genericCommandLineParams.js +12 -0
  101. package/dist/utils/paramsUtil/paramHandler.js +3 -6
  102. package/dist/utils/parsedCLIOptions.js +14 -8
  103. package/package.json +26 -21
  104. package/src/audit/AnalysisEngine.js +103 -0
  105. package/src/audit/catalogueApplication/catalogueApplication.js +42 -0
  106. package/src/audit/dotnetAnalysisEngine/index.js +26 -0
  107. package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +47 -0
  108. package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +29 -0
  109. package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +30 -0
  110. package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +26 -0
  111. package/src/audit/dotnetAnalysisEngine/sanitizer.js +11 -0
  112. package/src/audit/goAnalysisEngine/index.js +18 -0
  113. package/src/audit/goAnalysisEngine/parseProjectFileContents.js +209 -0
  114. package/src/audit/goAnalysisEngine/readProjectFileContents.js +31 -0
  115. package/src/audit/goAnalysisEngine/sanitizer.js +7 -0
  116. package/src/audit/javaAnalysisEngine/index.js +41 -0
  117. package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +222 -0
  118. package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +420 -0
  119. package/src/audit/javaAnalysisEngine/readProjectFileContents.js +141 -0
  120. package/src/audit/javaAnalysisEngine/sanitizer.js +6 -0
  121. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +35 -0
  122. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +41 -0
  123. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +54 -0
  124. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +32 -0
  125. package/src/audit/languageAnalysisEngine/commonApi.js +20 -0
  126. package/src/audit/languageAnalysisEngine/constants.js +23 -0
  127. package/src/audit/languageAnalysisEngine/filterProjectPath.js +21 -0
  128. package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +41 -0
  129. package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +72 -0
  130. package/src/audit/languageAnalysisEngine/index.js +45 -0
  131. package/src/audit/languageAnalysisEngine/langugageAnalysisFactory.js +94 -0
  132. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +177 -0
  133. package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +27 -0
  134. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +303 -0
  135. package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +124 -0
  136. package/src/audit/languageAnalysisEngine/report/reportingFeature.js +190 -0
  137. package/src/audit/languageAnalysisEngine/sendSnapshot.js +51 -0
  138. package/src/audit/languageAnalysisEngine/util/capabilities.js +12 -0
  139. package/src/audit/languageAnalysisEngine/util/generalAPI.js +43 -0
  140. package/src/audit/languageAnalysisEngine/util/requestUtils.js +17 -0
  141. package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +49 -0
  142. package/src/audit/nodeAnalysisEngine/index.js +35 -0
  143. package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +20 -0
  144. package/src/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +63 -0
  145. package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +26 -0
  146. package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +23 -0
  147. package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +27 -0
  148. package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +36 -0
  149. package/src/audit/nodeAnalysisEngine/sanitizer.js +11 -0
  150. package/src/audit/phpAnalysisEngine/index.js +27 -0
  151. package/src/audit/phpAnalysisEngine/parseLockFileContents.js +60 -0
  152. package/src/audit/phpAnalysisEngine/readLockFileContents.js +14 -0
  153. package/src/audit/phpAnalysisEngine/readProjectFileContents.js +25 -0
  154. package/src/audit/phpAnalysisEngine/sanitizer.js +4 -0
  155. package/src/audit/pythonAnalysisEngine/index.js +55 -0
  156. package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +23 -0
  157. package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +33 -0
  158. package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +16 -0
  159. package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +22 -0
  160. package/src/audit/pythonAnalysisEngine/sanitizer.js +9 -0
  161. package/src/audit/rubyAnalysisEngine/index.js +30 -0
  162. package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +215 -0
  163. package/src/audit/rubyAnalysisEngine/parsedGemfile.js +39 -0
  164. package/src/audit/rubyAnalysisEngine/readGemfileContents.js +18 -0
  165. package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +17 -0
  166. package/src/audit/rubyAnalysisEngine/sanitizer.js +8 -0
  167. package/src/commands/audit/auditConfig.ts +30 -0
  168. package/src/commands/audit/auditController.ts +31 -0
  169. package/src/commands/audit/help.ts +48 -0
  170. package/src/commands/audit/processAudit.ts +19 -0
  171. package/src/commands/auth/auth.js +1 -1
  172. package/src/commands/scan/processScan.js +20 -5
  173. package/src/common/HTTPClient.js +136 -14
  174. package/src/common/errorHandling.ts +56 -1
  175. package/src/common/findLatestCLIVersion.ts +27 -0
  176. package/src/constants/constants.js +1 -1
  177. package/src/constants/lambda.js +45 -4
  178. package/src/constants/locales.js +48 -20
  179. package/src/constants.js +168 -22
  180. package/src/index.ts +9 -2
  181. package/src/lambda/aws.ts +13 -12
  182. package/src/lambda/help.ts +4 -0
  183. package/src/lambda/lambda.ts +53 -34
  184. package/src/lambda/lambdaUtils.ts +111 -0
  185. package/src/lambda/logUtils.ts +19 -1
  186. package/src/lambda/scanDetailCompletion.ts +4 -4
  187. package/src/lambda/scanRequest.ts +13 -11
  188. package/src/lambda/utils.ts +149 -81
  189. package/src/scan/autoDetection.js +0 -29
  190. package/src/scan/fileUtils.js +1 -1
  191. package/src/scan/help.js +12 -45
  192. package/src/scan/populateProjectIdAndProjectName.js +4 -0
  193. package/src/scan/saveResults.js +15 -0
  194. package/src/scan/scan.js +95 -59
  195. package/src/scan/scanConfig.js +29 -0
  196. package/src/scan/scanController.js +13 -13
  197. package/src/scan/scanResults.js +21 -19
  198. package/src/utils/commonApi.js +2 -3
  199. package/src/utils/paramsUtil/commandlineParams.js +1 -26
  200. package/src/utils/paramsUtil/paramHandler.js +3 -7
  201. package/src/utils/parsedCLIOptions.js +11 -9
@@ -4,7 +4,7 @@ const fs = require('fs');
4
4
  const i18n = require('i18n');
5
5
  const findFile = async () => {
6
6
  console.log(i18n.__('searchingScanFileDirectory', process.cwd()));
7
- return fg(['**/*.jar', '**/*.war', '**/*.zip', '**/*.dll'], {
7
+ return fg(['**/*.jar', '**/*.war', '**/*.zip', '**/*.dll', '**/*.exe'], {
8
8
  dot: false,
9
9
  deep: 3,
10
10
  onlyFiles: true
package/dist/scan/help.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  const commandLineUsage = require('command-line-usage');
3
3
  const i18n = require('i18n');
4
+ const constants = require('../constants');
4
5
  const scanUsageGuide = commandLineUsage([
5
6
  {
6
7
  header: i18n.__('scanHeader')
@@ -17,46 +18,17 @@ const scanUsageGuide = commandLineUsage([
17
18
  },
18
19
  {
19
20
  header: i18n.__('constantsScanOptions'),
20
- content: [
21
- {
22
- name: i18n.__('scanOptionsFileName'),
23
- summary: '{italic ' +
24
- i18n.__('constantsOptional') +
25
- '}: ' +
26
- i18n.__('scanOptionsFileNameSummary')
27
- },
28
- {
29
- name: i18n.__('scanOptionsLanguage'),
30
- summary: '{italic ' +
31
- i18n.__('constantsOptional') +
32
- '}: ' +
33
- i18n.__('scanOptionsLanguageSummaryOptional') +
34
- '{italic ' +
35
- i18n.__('constantsRequired') +
36
- '}: ' +
37
- i18n.__('scanOptionsLanguageSummaryRequired')
38
- },
39
- {
40
- name: i18n.__('scanOptionsName'),
41
- summary: '{italic ' +
42
- i18n.__('constantsOptional') +
43
- '}: ' +
44
- i18n.__('scanOptionsNameSummary')
45
- },
46
- {
47
- name: i18n.__('scanOptionsTimeout'),
48
- summary: '{italic ' +
49
- i18n.__('constantsOptional') +
50
- '}: ' +
51
- i18n.__('scanOptionsTimeoutSummary')
52
- },
53
- {
54
- name: i18n.__('scanOptionsVerbose'),
55
- summary: '{italic ' +
56
- i18n.__('constantsOptional') +
57
- '}: ' +
58
- i18n.__('scanOptionsVerboseSummary')
59
- }
21
+ optionList: constants.commandLineDefinitions.scanOptionDefinitions,
22
+ hide: [
23
+ 'project-id',
24
+ 'language',
25
+ 'organization-id',
26
+ 'api-key',
27
+ 'authorization',
28
+ 'host',
29
+ 'proxy',
30
+ 'ff',
31
+ 'ignore-cert-errors'
60
32
  ]
61
33
  },
62
34
  {
@@ -19,6 +19,10 @@ const createProjectId = async (config, client) => {
19
19
  console.log(i18n.__('foundExistingProjectScan'));
20
20
  return;
21
21
  }
22
+ if (res.statusCode === 403) {
23
+ console.log(i18n.__('permissionsError'));
24
+ return;
25
+ }
22
26
  if (res.statusCode === 201) {
23
27
  console.log(i18n.__('projectCreatedScan'));
24
28
  if (config.verbose) {
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ const fs = require('fs');
3
+ const writeResultsToFile = (responseBody, name = 'results.sarif') => {
4
+ fs.writeFile(name, JSON.stringify(responseBody, null, 2), err => {
5
+ if (err) {
6
+ console.log('Error writing Scan Results to file');
7
+ }
8
+ else {
9
+ console.log(`Scan Results saved to ${name}`);
10
+ }
11
+ });
12
+ };
13
+ module.exports = {
14
+ writeResultsToFile
15
+ };
package/dist/scan/scan.js CHANGED
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  const commonApi = require('../utils/commonApi.js');
3
3
  const fileUtils = require('../scan/fileUtils');
4
- const allowedFileTypes = ['.jar', '.war', '.js', '.zip'];
4
+ const allowedFileTypes = ['.jar', '.war', '.js', '.zip', '.exe'];
5
5
  const i18n = require('i18n');
6
- const AdmZip = require('adm-zip');
7
6
  const oraWrapper = require('../utils/oraWrapper');
8
- const { supportedLanguages } = require('../constants/constants');
7
+ const chalk = require('chalk');
9
8
  const isFileAllowed = scanOption => {
10
9
  let valid = false;
11
10
  allowedFileTypes.forEach(fileType => {
@@ -15,6 +14,13 @@ const isFileAllowed = scanOption => {
15
14
  });
16
15
  return valid;
17
16
  };
17
+ const stripMustacheTags = oldString => {
18
+ return oldString
19
+ .replace(/\n/g, ' ')
20
+ .replace(/{{.*?}}/g, '\n')
21
+ .replace(/\s+/g, ' ')
22
+ .trim();
23
+ };
18
24
  const sendScan = async (config) => {
19
25
  if (!isFileAllowed(config.file)) {
20
26
  console.log(i18n.__('scanErrorFileMessage'));
@@ -36,7 +42,14 @@ const sendScan = async (config) => {
36
42
  return res.body.id;
37
43
  }
38
44
  else {
45
+ if (config.debug) {
46
+ console.log(res.statusCode);
47
+ console.log(config);
48
+ }
39
49
  oraWrapper.failSpinner(startUploadSpinner, i18n.__('uploadingScanFail'));
50
+ if (res.statusCode === 403) {
51
+ console.log(i18n.__('permissionsError'));
52
+ }
40
53
  process.exit(1);
41
54
  }
42
55
  })
@@ -45,52 +58,74 @@ const sendScan = async (config) => {
45
58
  });
46
59
  }
47
60
  };
48
- const zipValidator = configToUse => {
49
- if (configToUse.file.endsWith('.zip')) {
50
- let zipFileName = configToUse.file.split('/').pop();
51
- try {
52
- let zip = new AdmZip(configToUse.file);
53
- let zipEntries = zip.getEntries();
54
- zipEntries.forEach(function (zipEntry) {
55
- if (!zipEntry.entryName.includes('._') &&
56
- !zipEntry.entryName.includes('/.')) {
57
- if (!zipEntry.isDirectory) {
58
- if (!zipEntry.entryName.endsWith('.js')) {
59
- console.log(i18n.__('scanZipError', zipFileName));
60
- process.exit(1);
61
- }
62
- }
63
- }
64
- });
65
- configToUse.language = supportedLanguages.JAVASCRIPT;
66
- }
67
- catch {
68
- console.log(i18n.__('zipFileException'));
69
- }
70
- }
71
- };
72
61
  const formatScanOutput = (overview, results) => {
73
62
  console.log();
74
- console.log('Here are your top priorities to fix');
75
- console.log();
76
- results.content.forEach(entry => {
77
- console.log(entry.severity, 'ID:', entry.id);
78
- console.log(entry.ruleId, 'in', entry.locations[0]?.physicalLocation.artifactLocation.uri, '@', entry.codeFlows[0]?.threadFlows[0]?.locations[0]?.location
79
- ?.physicalLocation?.region?.startLine);
63
+ if (results.content.length === 0) {
64
+ console.log(i18n.__('scanNoVulnerabilitiesFound'));
65
+ }
66
+ else {
67
+ console.log(chalk.bold('Here are your top priorities to fix'));
80
68
  console.log();
69
+ const groups = getGroups(results.content);
70
+ groups.forEach(entry => {
71
+ console.log(chalk.bold(`${entry.severity} | ${entry.ruleId} (${entry.lineInfoSet.size})`));
72
+ let count = 1;
73
+ entry.lineInfoSet.forEach(lineInfo => {
74
+ console.log(`\t ${count}. ${lineInfo}`);
75
+ count++;
76
+ });
77
+ console.log(chalk.bold('How to fix:'));
78
+ console.log(entry.recommendation);
79
+ console.log();
80
+ });
81
+ const totalVulnerabilities = overview.critical +
82
+ overview.high +
83
+ overview.medium +
84
+ overview.low +
85
+ overview.note;
86
+ console.log(chalk.bold(`Found ${totalVulnerabilities} vulnerabilities`));
87
+ console.log(i18n.__('foundDetailedVulnerabilities', overview.critical, overview.high, overview.medium, overview.low, overview.note));
88
+ }
89
+ };
90
+ const getGroups = content => {
91
+ const groupTypeSet = new Set(content.map(({ ruleId }) => ruleId));
92
+ let groupTypeResults = [];
93
+ groupTypeSet.forEach(groupName => {
94
+ let groupResultsObj = {
95
+ ruleId: groupName,
96
+ lineInfoSet: new Set(),
97
+ recommendation: '',
98
+ severity: ''
99
+ };
100
+ content.forEach(resultEntry => {
101
+ if (resultEntry.ruleId === groupName) {
102
+ groupResultsObj.severity = resultEntry.severity;
103
+ groupResultsObj.recommendation = resultEntry.recommendation
104
+ ? stripMustacheTags(resultEntry.recommendation)
105
+ : '';
106
+ groupResultsObj.lineInfoSet.add(formattedCodeLine(resultEntry));
107
+ }
108
+ });
109
+ groupTypeResults.push(groupResultsObj);
81
110
  });
82
- const totalVulnerabilities = overview.critical +
83
- overview.high +
84
- overview.medium +
85
- overview.low +
86
- overview.note;
87
- console.log(`Found ${totalVulnerabilities} vulnerabilities`);
88
- console.log(i18n.__('foundDetailedVulnerabilities', overview.critical, overview.high, overview.medium, overview.low, overview.note));
111
+ return groupTypeResults;
112
+ };
113
+ const formattedCodeLine = resultEntry => {
114
+ let lineUri = resultEntry.locations[0]?.physicalLocation.artifactLocation.uri;
115
+ return lineUri + ' @ ' + setLineNumber(resultEntry);
116
+ };
117
+ const setLineNumber = resultEntry => {
118
+ return resultEntry.codeFlows?.[0]?.threadFlows[0]?.locations[0]?.location
119
+ ?.physicalLocation?.region?.startLine
120
+ ? resultEntry.codeFlows[0]?.threadFlows[0]?.locations[0]?.location
121
+ ?.physicalLocation?.region?.startLine
122
+ : resultEntry.locations[0]?.physicalLocation?.region?.startLine;
89
123
  };
90
124
  module.exports = {
91
125
  sendScan: sendScan,
126
+ getGroups: getGroups,
92
127
  allowedFileTypes: allowedFileTypes,
93
128
  isFileAllowed: isFileAllowed,
94
- formatScanOutput: formatScanOutput,
95
- zipValidator: zipValidator
129
+ stripMustacheTags: stripMustacheTags,
130
+ formatScanOutput: formatScanOutput
96
131
  };
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ const paramHandler = require('../utils/paramsUtil/paramHandler');
3
+ const constants = require('../../src/constants.js');
4
+ const parsedCLIOptions = require('../../src/utils/parsedCLIOptions');
5
+ const path = require('path');
6
+ const getScanConfig = argv => {
7
+ let scanParams = parsedCLIOptions.getCommandLineArgsCustom(argv, constants.commandLineDefinitions.scanOptionDefinitions);
8
+ const paramsAuth = paramHandler.getAuth(scanParams);
9
+ if (!scanParams.name && scanParams.file) {
10
+ scanParams.name = getFileName(scanParams.file);
11
+ }
12
+ return { ...paramsAuth, ...scanParams };
13
+ };
14
+ const getFileName = file => {
15
+ return file.split(path.sep).pop();
16
+ };
17
+ module.exports = {
18
+ getScanConfig,
19
+ getFileName
20
+ };
@@ -5,7 +5,6 @@ const populateProjectIdAndProjectName = require('./populateProjectIdAndProjectNa
5
5
  const scan = require('./scan');
6
6
  const scanResults = require('./scanResults');
7
7
  const autoDetection = require('./autoDetection');
8
- const paramHandler = require('../utils/paramsUtil/paramHandler');
9
8
  const fileFunctions = require('./fileUtils');
10
9
  const getTimeout = config => {
11
10
  if (config.timeout) {
@@ -18,23 +17,22 @@ const getTimeout = config => {
18
17
  return 300;
19
18
  }
20
19
  };
21
- const startScan = async () => {
22
- let paramsAuth = paramHandler.getAuth();
23
- let getScanSubCommands = paramHandler.getScanSubCommands();
24
- const configToUse = { ...paramsAuth, ...getScanSubCommands };
25
- if (configToUse.file === undefined || configToUse.file === null) {
26
- await autoDetection.autoDetectFileAndLanguage(configToUse);
27
- }
28
- else {
29
- if (fileFunctions.fileExists(configToUse.file)) {
30
- scan.zipValidator(configToUse);
31
- autoDetection.assignLanguage([configToUse.file], configToUse);
32
- }
33
- else {
20
+ const fileAndLanguageLogic = async (configToUse) => {
21
+ if (configToUse.file) {
22
+ if (!fileFunctions.fileExists(configToUse.file)) {
34
23
  console.log(i18n.__('fileNotExist'));
35
24
  process.exit(0);
36
25
  }
26
+ return configToUse;
37
27
  }
28
+ else {
29
+ if (configToUse.file === undefined || configToUse.file === null) {
30
+ await autoDetection.autoDetectFileAndLanguage(configToUse);
31
+ }
32
+ }
33
+ };
34
+ const startScan = async (configToUse) => {
35
+ await fileAndLanguageLogic(configToUse);
38
36
  if (!configToUse.projectId) {
39
37
  configToUse.projectId = await populateProjectIdAndProjectName.populateProjectId(configToUse);
40
38
  }
@@ -46,7 +44,7 @@ const startScan = async () => {
46
44
  const scanResultsInstances = await scanResults.returnScanResultsInstances(configToUse, scanDetail.id);
47
45
  succeedSpinner(startScanSpinner, 'Contrast Scan complete');
48
46
  const projectOverview = await scanResults.returnScanProjectById(configToUse);
49
- return { projectOverview, scanResultsInstances };
47
+ return { projectOverview, scanDetail, scanResultsInstances };
50
48
  }
51
49
  };
52
50
  module.exports = {
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  const commonApi = require('../utils/commonApi');
3
3
  const requestUtils = require('../../src/utils/requestUtils');
4
- const i18n = require('i18n');
5
4
  const oraFunctions = require('../utils/oraWrapper');
5
+ const _ = require('lodash');
6
6
  const getScanId = async (config, codeArtifactId, client) => {
7
7
  return client
8
8
  .getScanId(config, codeArtifactId)
@@ -29,25 +29,27 @@ const returnScanResults = async (config, codeArtifactId, timeout, startScanSpinn
29
29
  let scanId = await getScanId(config, codeArtifactId, client);
30
30
  let startTime = new Date();
31
31
  let complete = false;
32
- while (!complete) {
33
- let result = await pollScanResults(config, scanId, client);
34
- if (JSON.stringify(result.statusCode) == 200) {
35
- if (result.body.status === 'COMPLETED') {
36
- complete = true;
37
- return result.body;
32
+ if (!_.isNil(scanId)) {
33
+ while (!complete) {
34
+ let result = await pollScanResults(config, scanId, client);
35
+ if (JSON.stringify(result.statusCode) == 200) {
36
+ if (result.body.status === 'COMPLETED') {
37
+ complete = true;
38
+ return result.body;
39
+ }
40
+ if (result.body.status === 'FAILED') {
41
+ complete = true;
42
+ oraFunctions.failSpinner(startScanSpinner, 'Contrast Scan Failed.');
43
+ process.exit(1);
44
+ }
38
45
  }
39
- if (result.body.status === 'FAILED') {
40
- complete = true;
41
- oraFunctions.failSpinner(startScanSpinner, 'Contrast Scan Failed.');
46
+ let endTime = new Date() - startTime;
47
+ if (requestUtils.millisToSeconds(endTime) > timeout) {
48
+ oraFunctions.failSpinner(startScanSpinner, 'Contrast Scan timed out at the specified ' + timeout + ' seconds.');
49
+ console.log('Please try again, allowing more time.');
42
50
  process.exit(1);
43
51
  }
44
52
  }
45
- let endTime = new Date() - startTime;
46
- if (requestUtils.millisToSeconds(endTime) > timeout) {
47
- oraFunctions.failSpinner(startScanSpinner, 'Contrast Scan timed out at the specified ' + timeout + ' seconds.');
48
- console.log('Please try again, allowing more time.');
49
- process.exit(1);
50
- }
51
53
  }
52
54
  };
53
55
  const returnScanResultsInstances = async (config, scanId) => {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  const HttpClient = require('./../common/HTTPClient');
3
- const { badRequestError, unauthenticatedError, forbiddenError, proxyError, hostWarningError, genericError } = require('../common/errorHandling');
4
- const handleResponseErrors = (res, api, hostPresent) => {
3
+ const { badRequestError, unauthenticatedError, forbiddenError, proxyError, genericError } = require('../common/errorHandling');
4
+ const handleResponseErrors = (res, api) => {
5
5
  if (res.statusCode === 400) {
6
6
  api === 'catalogue' ? badRequestError(true) : badRequestError(false);
7
7
  }
@@ -15,7 +15,7 @@ const handleResponseErrors = (res, api, hostPresent) => {
15
15
  proxyError();
16
16
  }
17
17
  else {
18
- hostPresent === false ? hostWarningError() : genericError();
18
+ genericError();
19
19
  }
20
20
  };
21
21
  const getProtocol = host => {
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ const fg = require('fast-glob');
3
+ const fs = require('fs');
4
+ const i18n = require('i18n');
5
+ const findFile = async () => {
6
+ console.log(i18n.__('searchingScanFileDirectory', process.cwd()));
7
+ return fg(['**/*.jar', '**/*.war', '**/*.zip', '**/*.dll'], {
8
+ dot: false,
9
+ deep: 3,
10
+ onlyFiles: true
11
+ });
12
+ };
13
+ const checkFilePermissions = file => {
14
+ let readableFile = false;
15
+ try {
16
+ fs.accessSync(file, fs.constants.R_OK);
17
+ return (readableFile = true);
18
+ }
19
+ catch (err) {
20
+ console.log('Invalid permissions found on ', file);
21
+ process.exit(0);
22
+ }
23
+ };
24
+ const fileExists = path => {
25
+ return fs.existsSync(path);
26
+ };
27
+ module.exports = {
28
+ findFile,
29
+ fileExists,
30
+ checkFilePermissions
31
+ };
@@ -1,7 +1,5 @@
1
1
  "use strict";
2
- const cliOptions = require('../parsedCLIOptions');
3
- const parsedCLIOptions = cliOptions.getCommandLineArgs();
4
- const getAuth = () => {
2
+ const getAuth = parsedCLIOptions => {
5
3
  let params = {};
6
4
  params.apiKey = parsedCLIOptions['apiKey'];
7
5
  params.authorization = parsedCLIOptions['authorization'];
@@ -9,23 +7,6 @@ const getAuth = () => {
9
7
  params.organizationId = parsedCLIOptions['organizationId'];
10
8
  return params;
11
9
  };
12
- const getScanParams = () => {
13
- let scanParams = {};
14
- scanParams.help = parsedCLIOptions['help'];
15
- scanParams.file = parsedCLIOptions['file'];
16
- scanParams.language = parsedCLIOptions['language']
17
- ? parsedCLIOptions['language'].toUpperCase()
18
- : parsedCLIOptions['language'];
19
- scanParams.ff = parsedCLIOptions['ff'];
20
- scanParams.timeout = parsedCLIOptions['timeout'];
21
- scanParams.name = parsedCLIOptions['name'];
22
- scanParams.verbose = parsedCLIOptions['verbose'];
23
- if (!scanParams.name) {
24
- scanParams.name = scanParams.file;
25
- }
26
- return scanParams;
27
- };
28
10
  module.exports = {
29
- getScanParams: getScanParams,
30
11
  getAuth: getAuth
31
12
  };
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ const cliOptions = require('../parsedCLIOptions');
3
+ const getGenericCommandLineParams = () => {
4
+ return cliOptions.getCommandLineArgsGeneric();
5
+ };
6
+ const getSpecificCommandLineParams = (parameterList, optionDefinition) => {
7
+ return cliOptions.getCommandLineArgsCustom(parameterList, optionDefinition);
8
+ };
9
+ module.exports = {
10
+ getSpecificCommandLineParams,
11
+ getGenericCommandLineParams
12
+ };
@@ -4,8 +4,8 @@ const configStoreParams = require('./configStoreParams');
4
4
  const envVariableParams = require('./envVariableParams');
5
5
  const { validateAuthParams } = require('../validationCheck');
6
6
  const i18n = require('i18n');
7
- const getAuth = () => {
8
- let commandLineAuthParamsAuth = commandlineAuth.getAuth();
7
+ const getAuth = params => {
8
+ let commandLineAuthParamsAuth = commandlineAuth.getAuth(params);
9
9
  let envVariableParamsAuth = envVariableParams.getAuth();
10
10
  let configStoreParamsAuth = configStoreParams.getAuth();
11
11
  if (validateAuthParams(commandLineAuthParamsAuth)) {
@@ -22,7 +22,4 @@ const getAuth = () => {
22
22
  process.exit(1);
23
23
  }
24
24
  };
25
- const getScanSubCommands = () => {
26
- return commandlineAuth.getScanParams();
27
- };
28
- module.exports = { getAuth: getAuth, getScanSubCommands: getScanSubCommands };
25
+ module.exports = { getAuth: getAuth };
@@ -1,13 +1,19 @@
1
1
  "use strict";
2
- const constants = require('../constants');
3
2
  const commandLineArgs = require('command-line-args');
4
- const getCommandLineArgs = () => {
5
- return commandLineArgs(constants.commandLineDefinitions.scanOptionDefinitions, {
6
- partial: true,
7
- camelCase: true,
8
- caseInsensitive: true
9
- });
3
+ const getCommandLineArgsCustom = (parameterList, optionDefinitions) => {
4
+ try {
5
+ return commandLineArgs(optionDefinitions, {
6
+ argv: parameterList,
7
+ partial: false,
8
+ camelCase: true,
9
+ caseInsensitive: true
10
+ });
11
+ }
12
+ catch (e) {
13
+ console.log(e.message.toString());
14
+ process.exit(1);
15
+ }
10
16
  };
11
17
  module.exports = {
12
- getCommandLineArgs: getCommandLineArgs
18
+ getCommandLineArgsCustom
13
19
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/contrast",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Contrast Security's command line tool",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -21,7 +21,9 @@
21
21
  "scripts": {
22
22
  "build": "tsc",
23
23
  "test": "jest --testPathIgnorePatterns=./test-integration/",
24
- "test-int": "jest ./test-integration/scan/",
24
+ "test-int": "jest ./test-integration/",
25
+ "test-int-scan": "jest ./test-integration/scan",
26
+ "test-int-audit": "jest ./test-integration/audit",
25
27
  "format": "prettier --write \"**/*.{ts,tsx,js,css,scss,json,md,yml}\" .eslintrc.* .babelrc",
26
28
  "check-format": "prettier --check \"**/*.{ts,tsx,js,css,scss,json,md,yml}\" .eslintrc.* .babelrc",
27
29
  "coverage-local": "nyc --reporter=text mocha './test/**/*.spec.js'",
@@ -36,26 +38,28 @@
36
38
  "node": ">=16.13.2 <17"
37
39
  },
38
40
  "dependencies": {
39
- "@aws-sdk/client-iam": "^3.53.0",
40
- "@aws-sdk/client-lambda": "^3.53.0",
41
+ "@aws-sdk/client-iam": "^3.78.0",
42
+ "@aws-sdk/client-lambda": "^3.78.0",
43
+ "@types/semver": "^7.3.9",
41
44
  "@yarnpkg/lockfile": "^1.1.0",
42
- "adm-zip": "^0.5.9",
43
45
  "bluebird": "^3.7.2",
44
- "chalk": "^4.1.2",
46
+ "boxen": "5.1.2",
47
+ "chalk": "4.1.2",
45
48
  "command-line-args": "^5.2.1",
46
- "command-line-usage": "^6.1.1",
47
- "conf": "^10.1.1",
49
+ "command-line-usage": "^6.1.3",
50
+ "conf": "^10.1.2",
48
51
  "dotenv": "^16.0.0",
49
52
  "fast-glob": "^3.2.11",
50
- "i18n": "^0.14.1",
53
+ "i18n": "^0.14.2",
51
54
  "js-yaml": "^4.1.0",
55
+ "latest-version": "5.1.0",
52
56
  "lodash": "^4.17.21",
53
57
  "log-symbols": "^4.1.0",
54
58
  "open": "^8.4.0",
55
59
  "ora": "5.4.1",
56
60
  "prettyjson": "^1.2.5",
57
61
  "request": "^2.88.2",
58
- "semver": "^7.3.5",
62
+ "semver": "^7.3.7",
59
63
  "string-builder": "^0.1.8",
60
64
  "string-multiple-replace": "^1.0.5",
61
65
  "tmp": "^0.2.1",
@@ -68,24 +72,25 @@
68
72
  "@types/command-line-usage": "^5.0.2",
69
73
  "@types/i18n": "^0.13.2",
70
74
  "@types/jest": "^27.4.1",
71
- "@types/lodash": "^4.14.181",
72
- "@typescript-eslint/eslint-plugin": "^5.13.0",
73
- "@typescript-eslint/parser": "^5.13.0",
75
+ "@types/lodash": "^4.14.182",
76
+ "@typescript-eslint/eslint-plugin": "^5.21.0",
77
+ "@typescript-eslint/parser": "^5.21.0",
74
78
  "csv-writer": "^1.6.0",
75
- "eslint": "^8.8.0",
76
- "eslint-config-prettier": "^8.3.0",
79
+ "eslint": "^8.14.0",
80
+ "eslint-config-prettier": "^8.5.0",
77
81
  "eslint-plugin-prettier": "^4.0.0",
78
- "husky": "^3.0.9",
79
- "jest": "^27.4.7",
80
- "mocha": "^9.2.1",
82
+ "husky": "^3.1.0",
83
+ "jest": "^27.5.1",
84
+ "jest-junit": "^13.2.0",
85
+ "mocha": "^9.2.2",
81
86
  "npm-license-crawler": "^0.2.1",
82
87
  "nyc": "^15.1.0",
83
- "pkg": "^5.5.2",
88
+ "pkg": "^5.6.0",
84
89
  "prettier": "^1.19.1",
85
90
  "tmp": "^0.2.1",
86
- "ts-jest": "^27.1.3",
91
+ "ts-jest": "^27.1.4",
87
92
  "ts-node": "^10.7.0",
88
- "typescript": "^4.6.2",
93
+ "typescript": "^4.6.3",
89
94
  "uuid": "^8.3.2"
90
95
  },
91
96
  "resolutions": {