@contrast/contrast 1.0.6 → 1.0.9

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 (221) hide show
  1. package/.prettierignore +0 -6
  2. package/dist/audit/catalogueApplication/catalogueApplication.js +23 -5
  3. package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +10 -19
  4. package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +98 -37
  5. package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +2 -1
  6. package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +4 -3
  7. package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +3 -0
  8. package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +87 -19
  9. package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +46 -16
  10. package/dist/audit/languageAnalysisEngine/sendSnapshot.js +57 -19
  11. package/dist/audit/save.js +37 -0
  12. package/dist/commands/audit/auditConfig.js +0 -16
  13. package/dist/commands/audit/auditController.js +18 -11
  14. package/dist/commands/audit/help.js +31 -25
  15. package/dist/commands/audit/processAudit.js +3 -3
  16. package/dist/commands/audit/saveFile.js +8 -4
  17. package/dist/commands/scan/sca/scaAnalysis.js +55 -10
  18. package/dist/common/HTTPClient.js +64 -23
  19. package/dist/common/errorHandling.js +6 -1
  20. package/dist/common/versionChecker.js +20 -5
  21. package/dist/constants/constants.js +7 -2
  22. package/dist/constants/locales.js +35 -38
  23. package/dist/constants.js +20 -13
  24. package/dist/index.js +55 -45
  25. package/dist/lambda/analytics.js +11 -0
  26. package/dist/lambda/lambda.js +38 -4
  27. package/dist/lambda/types.js +13 -0
  28. package/dist/sbom/generateSbom.js +5 -4
  29. package/dist/scaAnalysis/common/formatMessage.js +44 -1
  30. package/dist/scaAnalysis/common/treeUpload.js +4 -6
  31. package/dist/scaAnalysis/dotnet/analysis.js +43 -0
  32. package/dist/scaAnalysis/dotnet/index.js +10 -0
  33. package/dist/scaAnalysis/go/goReadDepFile.js +1 -3
  34. package/dist/scaAnalysis/java/analysis.js +5 -8
  35. package/dist/scaAnalysis/java/index.js +2 -2
  36. package/dist/scaAnalysis/javascript/analysis.js +107 -0
  37. package/dist/scaAnalysis/javascript/index.js +50 -0
  38. package/dist/scaAnalysis/php/analysis.js +70 -0
  39. package/dist/scaAnalysis/php/index.js +17 -0
  40. package/dist/scaAnalysis/python/analysis.js +42 -0
  41. package/dist/scaAnalysis/python/index.js +10 -0
  42. package/dist/scaAnalysis/ruby/analysis.js +218 -0
  43. package/dist/scaAnalysis/ruby/index.js +10 -0
  44. package/dist/scan/autoDetection.js +23 -22
  45. package/dist/scan/fileUtils.js +57 -20
  46. package/dist/scan/formatScanOutput.js +12 -14
  47. package/dist/scan/models/groupedResultsModel.js +1 -1
  48. package/dist/scan/models/scanResultsModel.js +3 -1
  49. package/dist/scan/populateProjectIdAndProjectName.js +2 -1
  50. package/dist/scan/scan.js +1 -0
  51. package/dist/scan/scanConfig.js +8 -3
  52. package/dist/scan/scanController.js +16 -3
  53. package/dist/scan/scanResults.js +5 -1
  54. package/dist/utils/commonApi.js +4 -1
  55. package/dist/utils/filterProjectPath.js +7 -2
  56. package/dist/utils/getConfig.js +1 -6
  57. package/package.json +12 -9
  58. package/src/audit/catalogueApplication/catalogueApplication.js +28 -7
  59. package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +10 -39
  60. package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +183 -68
  61. package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +3 -3
  62. package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +18 -11
  63. package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +11 -5
  64. package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +6 -1
  65. package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +4 -0
  66. package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +86 -32
  67. package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +87 -32
  68. package/src/audit/languageAnalysisEngine/sendSnapshot.js +69 -20
  69. package/src/audit/save.js +48 -0
  70. package/src/commands/audit/auditConfig.ts +0 -25
  71. package/src/commands/audit/auditController.ts +18 -20
  72. package/src/commands/audit/help.ts +31 -25
  73. package/src/commands/audit/processAudit.ts +3 -6
  74. package/src/commands/audit/saveFile.ts +6 -2
  75. package/src/commands/scan/processScan.js +0 -1
  76. package/src/commands/scan/sca/scaAnalysis.js +84 -30
  77. package/src/common/HTTPClient.js +81 -34
  78. package/src/common/errorHandling.ts +10 -1
  79. package/src/common/versionChecker.ts +24 -5
  80. package/src/constants/constants.js +9 -3
  81. package/src/constants/locales.js +58 -43
  82. package/src/constants.js +21 -14
  83. package/src/index.ts +70 -58
  84. package/src/lambda/analytics.ts +9 -0
  85. package/src/lambda/arn.ts +2 -1
  86. package/src/lambda/lambda.ts +40 -17
  87. package/src/lambda/types.ts +36 -0
  88. package/src/lambda/utils.ts +2 -7
  89. package/src/sbom/generateSbom.ts +2 -2
  90. package/src/scaAnalysis/common/formatMessage.js +48 -1
  91. package/src/scaAnalysis/common/treeUpload.js +4 -6
  92. package/src/scaAnalysis/dotnet/analysis.js +54 -0
  93. package/src/scaAnalysis/dotnet/index.js +11 -0
  94. package/src/scaAnalysis/go/goAnalysis.js +2 -3
  95. package/src/scaAnalysis/go/goReadDepFile.js +1 -3
  96. package/src/scaAnalysis/java/analysis.js +7 -8
  97. package/src/scaAnalysis/java/index.js +2 -2
  98. package/src/scaAnalysis/javascript/analysis.js +126 -0
  99. package/src/scaAnalysis/javascript/index.js +72 -0
  100. package/src/scaAnalysis/php/analysis.js +78 -0
  101. package/src/scaAnalysis/php/index.js +22 -0
  102. package/src/scaAnalysis/python/analysis.js +49 -0
  103. package/src/scaAnalysis/python/index.js +11 -0
  104. package/src/scaAnalysis/ruby/analysis.js +273 -0
  105. package/src/scaAnalysis/ruby/index.js +11 -0
  106. package/src/scan/autoDetection.js +24 -26
  107. package/src/scan/fileUtils.js +60 -20
  108. package/src/scan/formatScanOutput.ts +14 -15
  109. package/src/scan/models/groupedResultsModel.ts +3 -3
  110. package/src/scan/models/resultContentModel.ts +1 -1
  111. package/src/scan/models/scanResultsModel.ts +5 -2
  112. package/src/scan/populateProjectIdAndProjectName.js +3 -1
  113. package/src/scan/scan.ts +1 -0
  114. package/src/scan/scanConfig.js +7 -5
  115. package/src/scan/scanController.js +18 -4
  116. package/src/scan/scanResults.js +10 -0
  117. package/src/utils/commonApi.js +4 -1
  118. package/src/utils/filterProjectPath.js +6 -2
  119. package/src/utils/getConfig.ts +1 -12
  120. package/dist/audit/AnalysisEngine.js +0 -37
  121. package/dist/audit/autodetection/autoDetectLanguage.js +0 -32
  122. package/dist/audit/dotnetAnalysisEngine/index.js +0 -25
  123. package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -35
  124. package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -15
  125. package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -18
  126. package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -14
  127. package/dist/audit/dotnetAnalysisEngine/sanitizer.js +0 -9
  128. package/dist/audit/goAnalysisEngine/index.js +0 -17
  129. package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +0 -164
  130. package/dist/audit/goAnalysisEngine/readProjectFileContents.js +0 -21
  131. package/dist/audit/goAnalysisEngine/sanitizer.js +0 -5
  132. package/dist/audit/javaAnalysisEngine/index.js +0 -34
  133. package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -153
  134. package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -353
  135. package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +0 -98
  136. package/dist/audit/javaAnalysisEngine/sanitizer.js +0 -5
  137. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -24
  138. package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -24
  139. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -35
  140. package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -23
  141. package/dist/audit/languageAnalysisEngine/constants.js +0 -20
  142. package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -25
  143. package/dist/audit/languageAnalysisEngine/index.js +0 -39
  144. package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -87
  145. package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -150
  146. package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -40
  147. package/dist/audit/nodeAnalysisEngine/index.js +0 -31
  148. package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -18
  149. package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -18
  150. package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -17
  151. package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -14
  152. package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -24
  153. package/dist/audit/nodeAnalysisEngine/sanitizer.js +0 -9
  154. package/dist/audit/phpAnalysisEngine/index.js +0 -23
  155. package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +0 -52
  156. package/dist/audit/phpAnalysisEngine/readLockFileContents.js +0 -13
  157. package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +0 -16
  158. package/dist/audit/phpAnalysisEngine/sanitizer.js +0 -5
  159. package/dist/audit/pythonAnalysisEngine/index.js +0 -25
  160. package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -17
  161. package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -21
  162. package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -13
  163. package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -14
  164. package/dist/audit/pythonAnalysisEngine/sanitizer.js +0 -7
  165. package/dist/audit/rubyAnalysisEngine/index.js +0 -25
  166. package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -176
  167. package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +0 -22
  168. package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +0 -14
  169. package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -14
  170. package/dist/audit/rubyAnalysisEngine/sanitizer.js +0 -6
  171. package/src/audit/AnalysisEngine.js +0 -103
  172. package/src/audit/autodetection/autoDetectLanguage.ts +0 -40
  173. package/src/audit/dotnetAnalysisEngine/index.js +0 -26
  174. package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -47
  175. package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -29
  176. package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -30
  177. package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -26
  178. package/src/audit/dotnetAnalysisEngine/sanitizer.js +0 -11
  179. package/src/audit/goAnalysisEngine/index.js +0 -18
  180. package/src/audit/goAnalysisEngine/parseProjectFileContents.js +0 -209
  181. package/src/audit/goAnalysisEngine/readProjectFileContents.js +0 -31
  182. package/src/audit/goAnalysisEngine/sanitizer.js +0 -7
  183. package/src/audit/javaAnalysisEngine/index.js +0 -41
  184. package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -222
  185. package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -420
  186. package/src/audit/javaAnalysisEngine/readProjectFileContents.js +0 -141
  187. package/src/audit/javaAnalysisEngine/sanitizer.js +0 -6
  188. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -35
  189. package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -41
  190. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -54
  191. package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -32
  192. package/src/audit/languageAnalysisEngine/constants.js +0 -23
  193. package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -41
  194. package/src/audit/languageAnalysisEngine/index.js +0 -45
  195. package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -116
  196. package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -249
  197. package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -49
  198. package/src/audit/nodeAnalysisEngine/index.js +0 -35
  199. package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -20
  200. package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -26
  201. package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -23
  202. package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -27
  203. package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -36
  204. package/src/audit/nodeAnalysisEngine/sanitizer.js +0 -11
  205. package/src/audit/phpAnalysisEngine/index.js +0 -27
  206. package/src/audit/phpAnalysisEngine/parseLockFileContents.js +0 -60
  207. package/src/audit/phpAnalysisEngine/readLockFileContents.js +0 -14
  208. package/src/audit/phpAnalysisEngine/readProjectFileContents.js +0 -25
  209. package/src/audit/phpAnalysisEngine/sanitizer.js +0 -4
  210. package/src/audit/pythonAnalysisEngine/index.js +0 -55
  211. package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -23
  212. package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -33
  213. package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -16
  214. package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -22
  215. package/src/audit/pythonAnalysisEngine/sanitizer.js +0 -9
  216. package/src/audit/rubyAnalysisEngine/index.js +0 -30
  217. package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -215
  218. package/src/audit/rubyAnalysisEngine/parsedGemfile.js +0 -39
  219. package/src/audit/rubyAnalysisEngine/readGemfileContents.js +0 -18
  220. package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -17
  221. package/src/audit/rubyAnalysisEngine/sanitizer.js +0 -8
@@ -9,29 +9,35 @@ import { orderBy } from 'lodash'
9
9
  import chalk from 'chalk'
10
10
  import { ReportCVEModel, ReportLibraryModel } from './models/reportLibraryModel'
11
11
  import {
12
+ countVulnerableLibrariesBySeverity,
12
13
  findCVESeveritiesAndOrderByHighestPriority,
13
14
  findHighestSeverityCVE,
14
15
  findNameAndVersion,
15
16
  severityCountAllCVEs
16
17
  } from './utils/reportUtils'
17
- import {SeverityCountModel} from "./models/severityCountModel";
18
+ import { SeverityCountModel } from './models/severityCountModel'
18
19
  import {
19
20
  ReportOutputBodyModel,
20
21
  ReportOutputHeaderModel,
21
22
  ReportOutputModel
22
- } from "./models/reportOutputModel";
23
+ } from './models/reportOutputModel'
24
+ import {
25
+ CRITICAL_COLOUR,
26
+ HIGH_COLOUR,
27
+ LOW_COLOUR,
28
+ MEDIUM_COLOUR,
29
+ NOTE_COLOUR
30
+ } from '../../../constants/constants'
31
+ import Table from 'cli-table3'
23
32
 
24
- export const createLibraryHeader = (
25
- id: string,
33
+ export const createSummaryMessage = (
26
34
  numberOfVulnerableLibraries: number,
27
35
  numberOfCves: number
28
36
  ) => {
29
37
  numberOfVulnerableLibraries === 1
30
- ? console.log(
31
- ` Found 1 vulnerable library containing ${numberOfCves} CVE's`
32
- )
38
+ ? console.log(`Found 1 vulnerable library containing ${numberOfCves} CVE`)
33
39
  : console.log(
34
- ` Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVE's `
40
+ `Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVEs`
35
41
  )
36
42
  }
37
43
 
@@ -43,10 +49,6 @@ export const getReport = async (config: any, reportId: string) => {
43
49
  if (res.statusCode === 200) {
44
50
  return res.body
45
51
  } else {
46
- console.log('config-------------------')
47
- console.log(config)
48
- console.log('reportId----------------')
49
- console.log(reportId)
50
52
  console.log(JSON.stringify(res))
51
53
  handleResponseErrors(res, 'report')
52
54
  }
@@ -57,21 +59,35 @@ export const getReport = async (config: any, reportId: string) => {
57
59
  }
58
60
 
59
61
  export const printVulnerabilityResponse = (
60
- vulnerabilities: ReportLibraryModel[],
61
- config: any
62
+ config: any,
63
+ vulnerableLibraries: ReportLibraryModel[],
64
+ numberOfVulnerableLibraries: number,
65
+ numberOfCves: number,
66
+ guidance: any
62
67
  ) => {
63
68
  let hasSomeVulnerabilitiesReported = false
64
- printFormattedOutput(vulnerabilities, config)
65
- if (Object.keys(vulnerabilities).length > 0) {
69
+ printFormattedOutput(
70
+ config,
71
+ vulnerableLibraries,
72
+ numberOfVulnerableLibraries,
73
+ numberOfCves,
74
+ guidance
75
+ )
76
+ if (Object.keys(vulnerableLibraries).length > 0) {
66
77
  hasSomeVulnerabilitiesReported = true
67
78
  }
68
79
  return hasSomeVulnerabilitiesReported
69
80
  }
70
81
 
71
82
  export const printFormattedOutput = (
83
+ config: any,
72
84
  libraries: ReportLibraryModel[],
73
- config: any
85
+ numberOfVulnerableLibraries: number,
86
+ numberOfCves: number,
87
+ guidance: any
74
88
  ) => {
89
+ createSummaryMessage(numberOfVulnerableLibraries, numberOfCves)
90
+ console.log()
75
91
  const report = new ReportList()
76
92
 
77
93
  for (const library of libraries) {
@@ -81,26 +97,61 @@ export const printFormattedOutput = (
81
97
  new ReportCompositeKey(
82
98
  name,
83
99
  version,
84
- findHighestSeverityCVE(library.cveArray) as ReportSeverityModel
100
+ findHighestSeverityCVE(library.cveArray) as ReportSeverityModel,
101
+ severityCountAllCVEs(
102
+ library.cveArray,
103
+ new SeverityCountModel()
104
+ ).getTotal
85
105
  ),
86
106
  library.cveArray
87
107
  )
88
-
89
108
  report.reportOutputList.push(newOutputModel)
90
109
  }
91
110
 
92
- const orderedOutputListLowestFirst = orderBy(
111
+ const outputOrderedByLowestSeverityAndLowestNumOfCvesFirst = orderBy(
93
112
  report.reportOutputList,
94
- reportListItem => reportListItem.compositeKey.highestSeverity.priority,
95
- ['desc']
113
+ [
114
+ (reportListItem: ReportModelStructure) => {
115
+ return reportListItem.compositeKey.highestSeverity.priority
116
+ },
117
+ (reportListItem: ReportModelStructure) => {
118
+ return reportListItem.compositeKey.numberOfSeverities
119
+ }
120
+ ],
121
+ ['asc', 'desc']
96
122
  )
97
123
 
98
124
  let contrastHeaderNumCounter = 0
99
- for (const reportModel of orderedOutputListLowestFirst) {
125
+ for (const reportModel of outputOrderedByLowestSeverityAndLowestNumOfCvesFirst) {
100
126
  contrastHeaderNumCounter++
101
- const {libraryName, libraryVersion, highestSeverity} = reportModel.compositeKey
127
+ const { libraryName, libraryVersion, highestSeverity } =
128
+ reportModel.compositeKey
102
129
  const numOfCVEs = reportModel.cveArray.length
103
130
 
131
+ const table = new Table({
132
+ chars: {
133
+ top: '',
134
+ 'top-mid': '',
135
+ 'top-left': '',
136
+ 'top-right': '',
137
+ bottom: '',
138
+ 'bottom-mid': '',
139
+ 'bottom-left': '',
140
+ 'bottom-right': '',
141
+ left: '',
142
+ 'left-mid': '',
143
+ mid: '',
144
+ 'mid-mid': '',
145
+ right: '',
146
+ 'right-mid': '',
147
+ middle: ' '
148
+ },
149
+ style: { 'padding-left': 0, 'padding-right': 0 },
150
+ colAligns: ['right'],
151
+ wordWrap: true,
152
+ colWidths: [12, 1, 100]
153
+ })
154
+
104
155
  const header = buildHeader(
105
156
  highestSeverity,
106
157
  contrastHeaderNumCounter,
@@ -109,15 +160,36 @@ export const printFormattedOutput = (
109
160
  numOfCVEs
110
161
  )
111
162
 
112
- const body = buildBody(
113
- reportModel.cveArray
114
- )
163
+ const advice = gatherRemediationAdvice(guidance, reportModel)
164
+
165
+ const body = buildBody(reportModel.cveArray, advice)
115
166
 
116
167
  const reportOutputModel = new ReportOutputModel(header, body)
117
- console.log(reportOutputModel.header.vulnMessage, reportOutputModel.header.introducesMessage)
118
- console.log(reportOutputModel.body.issueMessage)
119
- console.log(reportOutputModel.body.adviceMessage)
168
+
169
+ table.push(
170
+ reportOutputModel.body.issueMessage,
171
+ reportOutputModel.body.issueMessageCves,
172
+ reportOutputModel.body.adviceMessage
173
+ )
174
+
175
+ console.log(
176
+ reportOutputModel.header.vulnMessage,
177
+ reportOutputModel.header.introducesMessage
178
+ )
179
+ console.log(table.toString() + '\n')
120
180
  }
181
+
182
+ createSummaryMessage(numberOfVulnerableLibraries, numberOfCves)
183
+ const {
184
+ criticalMessage,
185
+ highMessage,
186
+ mediumMessage,
187
+ lowMessage,
188
+ noteMessage
189
+ } = buildFooter(outputOrderedByLowestSeverityAndLowestNumOfCvesFirst)
190
+ console.log(
191
+ `${criticalMessage} | ${highMessage} | ${mediumMessage} | ${lowMessage} | ${noteMessage}`
192
+ )
121
193
  }
122
194
 
123
195
  export function buildHeader(
@@ -125,71 +197,93 @@ export function buildHeader(
125
197
  contrastHeaderNum: number,
126
198
  libraryName: string,
127
199
  version: string,
128
- numOfCVEs: number,
200
+ numOfCVEs: number
129
201
  ) {
130
- const vulnerabilityPluralised = numOfCVEs > 1 ? 'Vulnerabilities' : 'Vulnerability'
202
+ const vulnerabilityPluralised =
203
+ numOfCVEs > 1 ? 'vulnerabilities' : 'vulnerability'
131
204
  const formattedHeaderNum = buildFormattedHeaderNum(contrastHeaderNum)
132
205
 
133
206
  const vulnMessage = chalk
134
- .hex(highestSeverity.outputColour)
135
- .bold(`${formattedHeaderNum} - [${highestSeverity.severity}] ${libraryName}-${version}`)
207
+ .hex(highestSeverity.outputColour)
208
+ .bold(
209
+ `${formattedHeaderNum} - [${highestSeverity.severity}] ${libraryName}-${version}`
210
+ )
136
211
 
137
- const introducesMessage = chalk.bold(
138
- `introduces ${numOfCVEs} ${vulnerabilityPluralised}`
139
- )
212
+ const introducesMessage = `introduces ${numOfCVEs} ${vulnerabilityPluralised}`
140
213
 
141
214
  return new ReportOutputHeaderModel(vulnMessage, introducesMessage)
142
215
  }
143
216
 
144
- export function buildBody(cveArray: ReportCVEModel[]) {
217
+ export function buildBody(cveArray: ReportCVEModel[], advice: any) {
145
218
  const cveMessages: string[] = []
146
219
 
147
- findCVESeveritiesAndOrderByHighestPriority(cveArray).forEach(reportSeverityModel => {
220
+ findCVESeveritiesAndOrderByHighestPriority(cveArray).forEach(
221
+ reportSeverityModel => {
148
222
  // @ts-ignore
149
- const {outputColour, severity, cveName} = reportSeverityModel
223
+ const { outputColour, severity, cveName } = reportSeverityModel
150
224
 
151
225
  const severityShorthand = chalk
152
- .hex(outputColour)
153
- .bold(`[${severity.charAt(0).toUpperCase()}]`)
226
+ .hex(outputColour)
227
+ .bold(`[${severity.charAt(0).toUpperCase()}]`)
154
228
 
155
- const builtMessage = `${severityShorthand} ${cveName}`
229
+ const builtMessage = severityShorthand + cveName
156
230
  cveMessages.push(builtMessage)
157
231
  }
158
232
  )
159
233
 
160
234
  const numAndSeverityType = getNumOfAndSeverityType(cveArray)
161
235
 
162
- const issueMessage =
163
- ` ${chalk.bold('Issue')} : ${numAndSeverityType} ${cveMessages.join(', ')}.`
236
+ const issueMessage = [chalk.bold('Issue'), ':', `${numAndSeverityType}`]
164
237
 
165
- const adviceMessage =
166
- ` ${chalk.bold('Advice')} : ${chalk.bold('Update to latest version')}.`
238
+ const issueMessageCves = ['', '', cveMessages.join(', ')]
167
239
 
168
- return new ReportOutputBodyModel(issueMessage, adviceMessage)
240
+ //todo different advice based on remediationGuidance being available or now
241
+ // console.log(advice)
242
+
243
+ const displayAdvice = advice?.minimum
244
+ ? `Update to version ${chalk.bold(advice.minimum)}`
245
+ : `Update to latest version`
246
+
247
+ const adviceMessage = [chalk.bold('Advice'), ':', displayAdvice]
248
+
249
+ return new ReportOutputBodyModel(
250
+ issueMessage,
251
+ issueMessageCves,
252
+ adviceMessage
253
+ )
169
254
  }
170
255
 
171
- export function buildFormattedHeaderNum(contrastHeaderNum: number) {
172
- let formattedHeaderNum
173
-
174
- if (contrastHeaderNum < 10) {
175
- formattedHeaderNum = `00${contrastHeaderNum}`
176
- } else if (contrastHeaderNum >= 10 && contrastHeaderNum < 100) {
177
- formattedHeaderNum = `0${contrastHeaderNum}`
178
- } else if (contrastHeaderNum >= 100) {
179
- formattedHeaderNum = contrastHeaderNum
256
+ export function gatherRemediationAdvice(guidance: any, reportModel: any) {
257
+ const guidanceData = {
258
+ minimum: undefined,
259
+ maximum: undefined,
260
+ latest: undefined
180
261
  }
181
262
 
182
- return `CONTRAST-${formattedHeaderNum}`
263
+ const data =
264
+ guidance[
265
+ reportModel.compositeKey.libraryName +
266
+ '@' +
267
+ reportModel.compositeKey.libraryVersion
268
+ ]
269
+
270
+ if (data) {
271
+ guidanceData.minimum = data.minUpgradeVersion
272
+ guidanceData.maximum = data.maxUpgradeVersion
273
+ }
274
+
275
+ return guidanceData
276
+ }
277
+
278
+ export function buildFormattedHeaderNum(contrastHeaderNum: number) {
279
+ return `CONTRAST-${contrastHeaderNum.toString().padStart(3, '0')}`
183
280
  }
184
281
 
185
282
  export function getNumOfAndSeverityType(cveArray: ReportCVEModel[]) {
186
- const {
187
- critical,
188
- high,
189
- medium,
190
- low,
191
- note
192
- } = severityCountAllCVEs(cveArray, new SeverityCountModel())
283
+ const { critical, high, medium, low, note } = severityCountAllCVEs(
284
+ cveArray,
285
+ new SeverityCountModel()
286
+ )
193
287
 
194
288
  const criticalMessage = critical > 0 ? `${critical} Critical` : ''
195
289
  const highMessage = high > 0 ? `${high} High` : ''
@@ -199,6 +293,27 @@ export function getNumOfAndSeverityType(cveArray: ReportCVEModel[]) {
199
293
 
200
294
  //removes/trims whitespace to single spaces
201
295
  return `${criticalMessage} ${highMessage} ${mediumMessage} ${lowMessage} ${noteMessage}`
202
- .replace(/\s+/g, ' ')
203
- .trim();
204
- }
296
+ .replace(/\s+/g, ' ')
297
+ .trim()
298
+ }
299
+
300
+ const buildFooter = (reportModelStructure: ReportModelStructure[]) => {
301
+ const { critical, high, medium, low, note } =
302
+ countVulnerableLibrariesBySeverity(reportModelStructure)
303
+
304
+ const criticalMessage = chalk
305
+ .hex(CRITICAL_COLOUR)
306
+ .bold(`${critical} Critical`)
307
+ const highMessage = chalk.hex(HIGH_COLOUR).bold(`${high} High`)
308
+ const mediumMessage = chalk.hex(MEDIUM_COLOUR).bold(`${medium} Medium`)
309
+ const lowMessage = chalk.hex(LOW_COLOUR).bold(`${low} Low`)
310
+ const noteMessage = chalk.hex(NOTE_COLOUR).bold(`${note} Note`)
311
+
312
+ return {
313
+ criticalMessage,
314
+ highMessage,
315
+ mediumMessage,
316
+ lowMessage,
317
+ noteMessage
318
+ }
319
+ }
@@ -2,7 +2,7 @@ export class ReportLibraryModel {
2
2
  name: string
3
3
  cveArray: ReportCVEModel[]
4
4
 
5
- constructor (name: string, cveArray: ReportCVEModel[]){
5
+ constructor(name: string, cveArray: ReportCVEModel[]) {
6
6
  this.name = name
7
7
  this.cveArray = cveArray
8
8
  }
@@ -16,12 +16,12 @@ export class ReportCVEModel {
16
16
  severityCode?: string
17
17
  cvss3SeverityCode?: string
18
18
 
19
- constructor (
19
+ constructor(
20
20
  name: string,
21
21
  description: string,
22
22
  severityCode: string,
23
23
  cvss3SeverityCode: string
24
- ){
24
+ ) {
25
25
  this.name = name
26
26
  this.description = description
27
27
  this.severityCode = severityCode
@@ -1,32 +1,39 @@
1
- import {ReportSeverityModel} from "./reportSeverityModel";
2
- import {ReportCVEModel} from "./reportLibraryModel";
1
+ import { ReportSeverityModel } from './reportSeverityModel'
2
+ import { ReportCVEModel } from './reportLibraryModel'
3
3
 
4
4
  export class ReportList {
5
5
  reportOutputList: ReportModelStructure[]
6
6
 
7
- constructor (){
7
+ constructor() {
8
8
  this.reportOutputList = []
9
9
  }
10
10
  }
11
11
 
12
12
  export class ReportModelStructure {
13
- compositeKey: ReportCompositeKey;
14
- cveArray: ReportCVEModel[];
13
+ compositeKey: ReportCompositeKey
14
+ cveArray: ReportCVEModel[]
15
15
 
16
- constructor (compositeKey: ReportCompositeKey, cveArray: ReportCVEModel[]){
16
+ constructor(compositeKey: ReportCompositeKey, cveArray: ReportCVEModel[]) {
17
17
  this.compositeKey = compositeKey
18
18
  this.cveArray = cveArray
19
19
  }
20
20
  }
21
21
 
22
22
  export class ReportCompositeKey {
23
- libraryName!: string;
24
- libraryVersion!: string;
25
- highestSeverity!: ReportSeverityModel;
23
+ libraryName!: string
24
+ libraryVersion!: string
25
+ highestSeverity!: ReportSeverityModel
26
+ numberOfSeverities!: number
26
27
 
27
- constructor (libraryName: string, libraryVersion: string, highestSeverity: ReportSeverityModel){
28
+ constructor(
29
+ libraryName: string,
30
+ libraryVersion: string,
31
+ highestSeverity: ReportSeverityModel,
32
+ numberOfSeverities: number
33
+ ) {
28
34
  this.libraryName = libraryName
29
35
  this.libraryVersion = libraryVersion
30
36
  this.highestSeverity = highestSeverity
37
+ this.numberOfSeverities = numberOfSeverities
31
38
  }
32
- }
39
+ }
@@ -19,11 +19,17 @@ export class ReportOutputHeaderModel {
19
19
  }
20
20
 
21
21
  export class ReportOutputBodyModel {
22
- issueMessage: string
23
- adviceMessage: string
22
+ issueMessage: string[]
23
+ issueMessageCves: string[]
24
+ adviceMessage: string[]
24
25
 
25
- constructor(bodyIssueMessage: string, bodyAdviceMessage: string) {
26
- this.issueMessage = bodyIssueMessage
27
- this.adviceMessage = bodyAdviceMessage
26
+ constructor(
27
+ issueMessage: string[],
28
+ issueMessageCves: string[],
29
+ adviceMessage: string[]
30
+ ) {
31
+ this.issueMessage = issueMessage
32
+ this.issueMessageCves = issueMessageCves
33
+ this.adviceMessage = adviceMessage
28
34
  }
29
35
  }
@@ -4,7 +4,12 @@ export class ReportSeverityModel {
4
4
  outputColour: string
5
5
  cveName: string
6
6
 
7
- constructor(severity: string, priority: number, outputColour: string, cveName: string) {
7
+ constructor(
8
+ severity: string,
9
+ priority: number,
10
+ outputColour: string,
11
+ cveName: string
12
+ ) {
8
13
  this.severity = severity
9
14
  this.priority = priority
10
15
  this.outputColour = outputColour
@@ -13,4 +13,8 @@ export class SeverityCountModel {
13
13
  this.low = 0
14
14
  this.note = 0
15
15
  }
16
+
17
+ get getTotal(): number {
18
+ return this.critical + this.high + this.medium + this.low + this.note
19
+ }
16
20
  }
@@ -1,56 +1,110 @@
1
1
  import {
2
- createLibraryHeader,
3
2
  getReport,
4
3
  printVulnerabilityResponse
5
4
  } from './commonReportingFunctions'
6
5
  import {
7
- convertGenericToTypedLibraries,
6
+ convertGenericToTypedLibraryVulns,
8
7
  severityCountAllLibraries
9
8
  } from './utils/reportUtils'
9
+ import i18n from 'i18n'
10
+ import chalk from 'chalk'
11
+ import * as constants from '../../../constants/constants'
10
12
 
11
- export async function vulnerabilityReport(
12
- analysis: any,
13
- applicationId: string,
14
- reportId: string
15
- ) {
16
- const reportResponse = await getReport(analysis.config, reportId)
13
+ export function convertKeysToStandardFormat(config: any, guidance: any) {
14
+ let convertedGuidance = guidance
17
15
 
18
- if (reportResponse !== undefined) {
19
- const id = applicationId
20
- const name = analysis.config.applicationName
21
- formatVulnerabilityOutput(
22
- reportResponse.vulnerabilities,
23
- id,
24
- name,
25
- analysis.config
26
- )
16
+ switch (config.language) {
17
+ case constants.supportedLanguages.JAVA:
18
+ case constants.supportedLanguages.GO:
19
+ case constants.supportedLanguages.PHP:
20
+ break
21
+ case constants.supportedLanguages.NODE:
22
+ case constants.supportedLanguages.DOTNET:
23
+ case constants.supportedLanguages.PYTHON:
24
+ case constants.supportedLanguages.RUBY:
25
+ convertedGuidance = convertJSDotNetPython(guidance)
26
+ break
27
27
  }
28
+ return convertedGuidance
29
+ }
30
+
31
+ export function convertJSDotNetPython(guidance: any) {
32
+ const returnObject = {}
33
+
34
+ Object.entries(guidance).forEach(([key, value]) => {
35
+ const splitKey = key.split('/')
36
+ if (splitKey.length === 2) {
37
+ // @ts-ignore
38
+ returnObject[splitKey[1]] = value
39
+ }
40
+ })
41
+ return returnObject
28
42
  }
29
43
 
30
44
  export function formatVulnerabilityOutput(
31
45
  libraryVulnerabilityResponse: any,
32
46
  id: string,
33
- name: string,
34
- config: any
47
+ config: any,
48
+ remediationGuidance: any
35
49
  ) {
36
- const vulnerableLibraries = convertGenericToTypedLibraries(
50
+ const vulnerableLibraries = convertGenericToTypedLibraryVulns(
37
51
  libraryVulnerabilityResponse
38
52
  )
39
53
 
54
+ const guidance = convertKeysToStandardFormat(config, remediationGuidance)
55
+
40
56
  const numberOfVulnerableLibraries = vulnerableLibraries.length
41
- let numberOfCves = 0
42
- vulnerableLibraries.forEach(lib => (numberOfCves += lib.cveArray.length))
43
57
 
44
- createLibraryHeader(id, numberOfVulnerableLibraries, numberOfCves)
58
+ if (numberOfVulnerableLibraries === 0) {
59
+ console.log(i18n.__('scanNoVulnerabilitiesFound'))
60
+ console.log(i18n.__('scanNoVulnerabilitiesFoundSecureCode'))
61
+ console.log(i18n.__('scanNoVulnerabilitiesFoundGoodWork'))
62
+ console.log(
63
+ chalk.bold(`Found ${numberOfVulnerableLibraries} vulnerabilities`)
64
+ )
65
+ console.log(
66
+ i18n.__(
67
+ 'foundDetailedVulnerabilities',
68
+ String(0),
69
+ String(0),
70
+ String(0),
71
+ String(0),
72
+ String(0)
73
+ )
74
+ )
75
+ } else {
76
+ let numberOfCves = 0
77
+ vulnerableLibraries.forEach(lib => (numberOfCves += lib.cveArray.length))
78
+
79
+ const hasSomeVulnerabilitiesReported = printVulnerabilityResponse(
80
+ config,
81
+ vulnerableLibraries,
82
+ numberOfVulnerableLibraries,
83
+ numberOfCves,
84
+ guidance
85
+ )
45
86
 
46
- const hasSomeVulnerabilitiesReported = printVulnerabilityResponse(
47
- vulnerableLibraries,
48
- config
49
- )
87
+ return [
88
+ hasSomeVulnerabilitiesReported,
89
+ numberOfCves,
90
+ severityCountAllLibraries(vulnerableLibraries)
91
+ ]
92
+ }
93
+ }
94
+
95
+ export async function vulnerabilityReportV2(config: any, reportId: string) {
96
+ console.log()
97
+ const reportResponse = await getReport(config, reportId)
50
98
 
51
- return [
52
- hasSomeVulnerabilitiesReported,
53
- numberOfCves,
54
- severityCountAllLibraries(vulnerableLibraries)
55
- ]
99
+ if (reportResponse !== undefined) {
100
+ const name = config.applicationName
101
+ formatVulnerabilityOutput(
102
+ reportResponse.vulnerabilities,
103
+ config.applicationId,
104
+ config,
105
+ reportResponse.remediationGuidance
106
+ ? reportResponse.remediationGuidance
107
+ : {}
108
+ )
109
+ }
56
110
  }