@contrast/contrast 1.0.13 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/audit/report/commonReportingFunctions.js +175 -116
  2. package/dist/audit/report/models/reportSeverityModel.js +3 -3
  3. package/dist/audit/report/reportingFeature.js +1 -10
  4. package/dist/audit/report/utils/reportUtils.js +4 -4
  5. package/dist/audit/save.js +7 -2
  6. package/dist/commands/audit/help.js +3 -1
  7. package/dist/commands/scan/processScan.js +0 -6
  8. package/dist/commands/scan/sca/scaAnalysis.js +32 -15
  9. package/dist/common/HTTPClient.js +22 -3
  10. package/dist/common/errorHandling.js +1 -2
  11. package/dist/constants/constants.js +10 -2
  12. package/dist/constants/locales.js +17 -7
  13. package/dist/constants.js +31 -2
  14. package/dist/index.js +4 -2
  15. package/dist/lambda/lambda.js +1 -1
  16. package/dist/sbom/generateSbom.js +18 -1
  17. package/dist/scaAnalysis/common/auditReport.js +78 -0
  18. package/dist/scaAnalysis/common/scaServicesUpload.js +21 -13
  19. package/dist/scan/formatScanOutput.js +4 -29
  20. package/dist/utils/commonApi.js +1 -0
  21. package/dist/utils/settingsHelper.js +24 -0
  22. package/package.json +4 -1
  23. package/src/audit/report/commonReportingFunctions.js +432 -0
  24. package/src/audit/report/models/reportSeverityModel.ts +6 -6
  25. package/src/audit/report/reportingFeature.ts +2 -16
  26. package/src/audit/report/utils/reportUtils.ts +2 -8
  27. package/src/audit/save.js +14 -6
  28. package/src/commands/audit/help.ts +3 -1
  29. package/src/commands/scan/processScan.js +0 -8
  30. package/src/commands/scan/sca/scaAnalysis.js +52 -32
  31. package/src/common/HTTPClient.js +26 -3
  32. package/src/common/errorHandling.ts +1 -2
  33. package/src/constants/constants.js +12 -2
  34. package/src/constants/locales.js +19 -7
  35. package/src/constants.js +34 -2
  36. package/src/index.ts +4 -6
  37. package/src/lambda/lambda.ts +1 -1
  38. package/src/lambda/lambdaUtils.ts +1 -1
  39. package/src/sbom/generateSbom.ts +20 -0
  40. package/src/scaAnalysis/common/auditReport.js +108 -0
  41. package/src/scaAnalysis/common/scaServicesUpload.js +24 -14
  42. package/src/scan/formatScanOutput.ts +5 -42
  43. package/src/utils/commonApi.js +1 -0
  44. package/src/utils/settingsHelper.js +26 -0
  45. package/src/audit/report/commonReportingFunctions.ts +0 -355
@@ -1,355 +0,0 @@
1
- import { getHttpClient, handleResponseErrors } from '../../utils/commonApi'
2
- import {
3
- ReportCompositeKey,
4
- ReportList,
5
- ReportModelStructure
6
- } from './models/reportListModel'
7
- import { ReportSeverityModel } from './models/reportSeverityModel'
8
- import { orderBy } from 'lodash'
9
- import chalk from 'chalk'
10
- import { ReportCVEModel, ReportLibraryModel } from './models/reportLibraryModel'
11
- import {
12
- countVulnerableLibrariesBySeverity,
13
- findCVESeveritiesAndOrderByHighestPriority,
14
- findHighestSeverityCVE,
15
- findNameAndVersion,
16
- severityCountAllCVEs
17
- } from './utils/reportUtils'
18
- import { SeverityCountModel } from './models/severityCountModel'
19
- import {
20
- ReportOutputBodyModel,
21
- ReportOutputHeaderModel,
22
- ReportOutputModel
23
- } from './models/reportOutputModel'
24
- import {
25
- CE_URL,
26
- CRITICAL_COLOUR,
27
- HIGH_COLOUR,
28
- LOW_COLOUR,
29
- MEDIUM_COLOUR,
30
- NOTE_COLOUR
31
- } from '../../constants/constants'
32
- import Table from 'cli-table3'
33
- import { ReportGuidanceModel } from './models/reportGuidanceModel'
34
-
35
- export const createSummaryMessageTop = (
36
- numberOfVulnerableLibraries: number,
37
- numberOfCves: number
38
- ) => {
39
- numberOfVulnerableLibraries === 1
40
- ? console.log(`Found 1 vulnerable library containing ${numberOfCves} CVE`)
41
- : console.log(
42
- `Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVEs`
43
- )
44
- }
45
-
46
- export const createSummaryMessageBottom = (
47
- numberOfVulnerableLibraries: number
48
- ) => {
49
- numberOfVulnerableLibraries === 1
50
- ? console.log(`Found 1 vulnerable library`)
51
- : console.log(`Found ${numberOfVulnerableLibraries} vulnerable libraries`)
52
- }
53
-
54
- export const getReport = async (config: any, reportId: string) => {
55
- const client = getHttpClient(config)
56
- return client
57
- .getReportById(config, reportId)
58
- .then((res: { statusCode: number; body: any }) => {
59
- if (res.statusCode === 200) {
60
- return res.body
61
- } else {
62
- console.log(JSON.stringify(res))
63
- handleResponseErrors(res, 'report')
64
- }
65
- })
66
- .catch((err: any) => {
67
- console.log(err)
68
- })
69
- }
70
-
71
- export const printVulnerabilityResponse = (
72
- config: any,
73
- vulnerableLibraries: ReportLibraryModel[],
74
- numberOfVulnerableLibraries: number,
75
- numberOfCves: number,
76
- guidance: any
77
- ) => {
78
- let hasSomeVulnerabilitiesReported = false
79
- printFormattedOutput(
80
- config,
81
- vulnerableLibraries,
82
- numberOfVulnerableLibraries,
83
- numberOfCves,
84
- guidance
85
- )
86
- if (Object.keys(vulnerableLibraries).length > 0) {
87
- hasSomeVulnerabilitiesReported = true
88
- }
89
- return hasSomeVulnerabilitiesReported
90
- }
91
-
92
- export const printFormattedOutput = (
93
- config: any,
94
- libraries: ReportLibraryModel[],
95
- numberOfVulnerableLibraries: number,
96
- numberOfCves: number,
97
- guidance: any
98
- ) => {
99
- createSummaryMessageTop(numberOfVulnerableLibraries, numberOfCves)
100
- console.log()
101
- const report = new ReportList()
102
-
103
- for (const library of libraries) {
104
- const { name, version } = findNameAndVersion(library, config)
105
-
106
- const newOutputModel = new ReportModelStructure(
107
- new ReportCompositeKey(
108
- name,
109
- version,
110
- findHighestSeverityCVE(library.cveArray) as ReportSeverityModel,
111
- severityCountAllCVEs(
112
- library.cveArray,
113
- new SeverityCountModel()
114
- ).getTotal
115
- ),
116
- library.cveArray
117
- )
118
- report.reportOutputList.push(newOutputModel)
119
- }
120
-
121
- const outputOrderedByLowestSeverityAndLowestNumOfCvesFirst = orderBy(
122
- report.reportOutputList,
123
- [
124
- (reportListItem: ReportModelStructure) => {
125
- return reportListItem.compositeKey.highestSeverity.priority
126
- },
127
- (reportListItem: ReportModelStructure) => {
128
- return reportListItem.compositeKey.numberOfSeverities
129
- }
130
- ],
131
- ['asc', 'desc']
132
- )
133
-
134
- let contrastHeaderNumCounter = 0
135
- for (const reportModel of outputOrderedByLowestSeverityAndLowestNumOfCvesFirst) {
136
- contrastHeaderNumCounter++
137
- const { libraryName, libraryVersion, highestSeverity } =
138
- reportModel.compositeKey
139
- const numOfCVEs = reportModel.cveArray.length
140
-
141
- const table = new Table({
142
- chars: {
143
- top: '',
144
- 'top-mid': '',
145
- 'top-left': '',
146
- 'top-right': '',
147
- bottom: '',
148
- 'bottom-mid': '',
149
- 'bottom-left': '',
150
- 'bottom-right': '',
151
- left: '',
152
- 'left-mid': '',
153
- mid: '',
154
- 'mid-mid': '',
155
- right: '',
156
- 'right-mid': '',
157
- middle: ' '
158
- },
159
- style: { 'padding-left': 0, 'padding-right': 0 },
160
- colAligns: ['right'],
161
- wordWrap: true,
162
- colWidths: [12, 1, 100]
163
- })
164
-
165
- const header = buildHeader(
166
- highestSeverity,
167
- contrastHeaderNumCounter,
168
- libraryName,
169
- libraryVersion,
170
- numOfCVEs
171
- )
172
-
173
- const advice = gatherRemediationAdvice(
174
- guidance,
175
- libraryName,
176
- libraryVersion
177
- )
178
-
179
- const body = buildBody(reportModel.cveArray, advice)
180
-
181
- const reportOutputModel = new ReportOutputModel(header, body)
182
-
183
- table.push(
184
- reportOutputModel.body.issueMessage,
185
- reportOutputModel.body.adviceMessage
186
- )
187
-
188
- console.log(
189
- reportOutputModel.header.vulnMessage,
190
- reportOutputModel.header.introducesMessage
191
- )
192
- console.log(table.toString() + '\n')
193
- }
194
-
195
- createSummaryMessageBottom(numberOfVulnerableLibraries)
196
- const {
197
- criticalMessage,
198
- highMessage,
199
- mediumMessage,
200
- lowMessage,
201
- noteMessage
202
- } = buildFooter(outputOrderedByLowestSeverityAndLowestNumOfCvesFirst)
203
- console.log(
204
- `${criticalMessage} | ${highMessage} | ${mediumMessage} | ${lowMessage} | ${noteMessage}`
205
- )
206
-
207
- if (config.host !== CE_URL) {
208
- console.log(
209
- '\n' + chalk.bold('View your full dependency tree in Contrast:')
210
- )
211
- console.log(
212
- `${config.host}/Contrast/static/ng/index.html#/${config.organizationId}/applications/${config.applicationId}/libs/dependency-tree`
213
- )
214
- }
215
- }
216
-
217
- export function buildHeader(
218
- highestSeverity: ReportSeverityModel,
219
- contrastHeaderNum: number,
220
- libraryName: string,
221
- version: string,
222
- numOfCVEs: number
223
- ) {
224
- const vulnerabilityPluralised =
225
- numOfCVEs > 1 ? 'vulnerabilities' : 'vulnerability'
226
- const formattedHeaderNum = buildFormattedHeaderNum(contrastHeaderNum)
227
-
228
- const headerColour = chalk.hex(highestSeverity.outputColour)
229
- const headerNumAndSeverity = headerColour(
230
- `${formattedHeaderNum} - [${highestSeverity.severity}]`
231
- )
232
- const libraryNameAndVersion = headerColour.bold(`${libraryName}-${version}`)
233
- const vulnMessage = `${headerNumAndSeverity} ${libraryNameAndVersion}`
234
-
235
- const introducesMessage = `introduces ${numOfCVEs} ${vulnerabilityPluralised}`
236
-
237
- return new ReportOutputHeaderModel(vulnMessage, introducesMessage)
238
- }
239
-
240
- export function buildBody(
241
- cveArray: ReportCVEModel[],
242
- advice: ReportGuidanceModel
243
- ) {
244
- const cveMessages: string[] = []
245
-
246
- findCVESeveritiesAndOrderByHighestPriority(cveArray).forEach(
247
- reportSeverityModel => {
248
- // @ts-ignore
249
- const { outputColour, severity, cveName } = reportSeverityModel
250
-
251
- const severityShorthand = chalk
252
- .hex(outputColour)
253
- .bold(`[${severity.charAt(0).toUpperCase()}]`)
254
-
255
- const builtMessage = severityShorthand + cveName
256
- cveMessages.push(builtMessage)
257
- }
258
- )
259
-
260
- const numAndSeverityType = getNumOfAndSeverityType(cveArray)
261
-
262
- const issueMessage = [
263
- chalk.bold('Issue'),
264
- ':',
265
- `${numAndSeverityType} ${cveMessages.join(', ')}`
266
- ]
267
-
268
- //todo different advice based on remediationGuidance being available or now
269
- // console.log(advice)
270
-
271
- const minOrMax = advice.maximum ? advice.maximum : advice.minimum
272
- const displayAdvice = minOrMax
273
- ? `Change to version ${chalk.bold(minOrMax)}`
274
- : 'No recommendation is available according to our data. Upgrade to the latest stable is the best advice we can give.'
275
-
276
- const adviceMessage = [chalk.bold('Advice'), ':', displayAdvice]
277
-
278
- return new ReportOutputBodyModel(issueMessage, adviceMessage)
279
- }
280
-
281
- export function gatherRemediationAdvice(
282
- guidance: any,
283
- libraryName: string,
284
- libraryVersion: string
285
- ) {
286
- const guidanceModel = new ReportGuidanceModel()
287
-
288
- const data = guidance[libraryName + '@' + libraryVersion]
289
-
290
- if (data) {
291
- guidanceModel.minimum = data.minUpgradeVersion
292
- guidanceModel.maximum = data.maxUpgradeVersion
293
- }
294
-
295
- return guidanceModel
296
- }
297
-
298
- export function buildFormattedHeaderNum(contrastHeaderNum: number) {
299
- return `CONTRAST-${contrastHeaderNum.toString().padStart(3, '0')}`
300
- }
301
-
302
- export function getNumOfAndSeverityType(cveArray: ReportCVEModel[]) {
303
- const { critical, high, medium, low, note } = severityCountAllCVEs(
304
- cveArray,
305
- new SeverityCountModel()
306
- )
307
-
308
- const criticalNumCheck = critical > 0
309
-
310
- const highNumCheck = high > 0
311
- const highDivider = highNumCheck ? '|' : ''
312
-
313
- const mediumNumCheck = medium > 0
314
- const mediumDivider = mediumNumCheck ? '|' : ''
315
-
316
- const lowNumCheck = low > 0
317
- const lowDivider = lowNumCheck ? '|' : ''
318
-
319
- const noteNumCheck = low > 0
320
- const noteDivider = noteNumCheck ? '|' : ''
321
-
322
- const criticalMessage = criticalNumCheck
323
- ? `${critical} Critical ${highDivider}`
324
- : ''
325
- const highMessage = highNumCheck ? `${high} High ${mediumDivider}` : ''
326
- const mediumMessage = mediumNumCheck ? `${medium} Medium ${lowDivider}` : ''
327
- const lowMessage = lowNumCheck ? `${low} Low ${noteDivider}` : ''
328
- const noteMessage = noteNumCheck ? `${note} Note` : ''
329
-
330
- //removes/trims whitespace to single spaces
331
- return `${criticalMessage} ${highMessage} ${mediumMessage} ${lowMessage} ${noteMessage}`
332
- .replace(/\s+/g, ' ')
333
- .trim()
334
- }
335
-
336
- const buildFooter = (reportModelStructure: ReportModelStructure[]) => {
337
- const { critical, high, medium, low, note } =
338
- countVulnerableLibrariesBySeverity(reportModelStructure)
339
-
340
- const criticalMessage = chalk
341
- .hex(CRITICAL_COLOUR)
342
- .bold(`${critical} Critical`)
343
- const highMessage = chalk.hex(HIGH_COLOUR).bold(`${high} High`)
344
- const mediumMessage = chalk.hex(MEDIUM_COLOUR).bold(`${medium} Medium`)
345
- const lowMessage = chalk.hex(LOW_COLOUR).bold(`${low} Low`)
346
- const noteMessage = chalk.hex(NOTE_COLOUR).bold(`${note} Note`)
347
-
348
- return {
349
- criticalMessage,
350
- highMessage,
351
- mediumMessage,
352
- lowMessage,
353
- noteMessage
354
- }
355
- }