@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.
- package/.prettierignore +0 -6
- package/dist/audit/catalogueApplication/catalogueApplication.js +23 -5
- package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +10 -19
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +98 -37
- package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +2 -1
- package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +4 -3
- package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +3 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +87 -19
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +46 -16
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +57 -19
- package/dist/audit/save.js +37 -0
- package/dist/commands/audit/auditConfig.js +0 -16
- package/dist/commands/audit/auditController.js +18 -11
- package/dist/commands/audit/help.js +31 -25
- package/dist/commands/audit/processAudit.js +3 -3
- package/dist/commands/audit/saveFile.js +8 -4
- package/dist/commands/scan/sca/scaAnalysis.js +55 -10
- package/dist/common/HTTPClient.js +64 -23
- package/dist/common/errorHandling.js +6 -1
- package/dist/common/versionChecker.js +20 -5
- package/dist/constants/constants.js +7 -2
- package/dist/constants/locales.js +35 -38
- package/dist/constants.js +20 -13
- package/dist/index.js +55 -45
- package/dist/lambda/analytics.js +11 -0
- package/dist/lambda/lambda.js +38 -4
- package/dist/lambda/types.js +13 -0
- package/dist/sbom/generateSbom.js +5 -4
- package/dist/scaAnalysis/common/formatMessage.js +44 -1
- package/dist/scaAnalysis/common/treeUpload.js +4 -6
- package/dist/scaAnalysis/dotnet/analysis.js +43 -0
- package/dist/scaAnalysis/dotnet/index.js +10 -0
- package/dist/scaAnalysis/go/goReadDepFile.js +1 -3
- package/dist/scaAnalysis/java/analysis.js +5 -8
- package/dist/scaAnalysis/java/index.js +2 -2
- package/dist/scaAnalysis/javascript/analysis.js +107 -0
- package/dist/scaAnalysis/javascript/index.js +50 -0
- package/dist/scaAnalysis/php/analysis.js +70 -0
- package/dist/scaAnalysis/php/index.js +17 -0
- package/dist/scaAnalysis/python/analysis.js +42 -0
- package/dist/scaAnalysis/python/index.js +10 -0
- package/dist/scaAnalysis/ruby/analysis.js +218 -0
- package/dist/scaAnalysis/ruby/index.js +10 -0
- package/dist/scan/autoDetection.js +23 -22
- package/dist/scan/fileUtils.js +57 -20
- package/dist/scan/formatScanOutput.js +12 -14
- package/dist/scan/models/groupedResultsModel.js +1 -1
- package/dist/scan/models/scanResultsModel.js +3 -1
- package/dist/scan/populateProjectIdAndProjectName.js +2 -1
- package/dist/scan/scan.js +1 -0
- package/dist/scan/scanConfig.js +8 -3
- package/dist/scan/scanController.js +16 -3
- package/dist/scan/scanResults.js +5 -1
- package/dist/utils/commonApi.js +4 -1
- package/dist/utils/filterProjectPath.js +7 -2
- package/dist/utils/getConfig.js +1 -6
- package/package.json +12 -9
- package/src/audit/catalogueApplication/catalogueApplication.js +28 -7
- package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +10 -39
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +183 -68
- package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +3 -3
- package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +18 -11
- package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +11 -5
- package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +6 -1
- package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +4 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +86 -32
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +87 -32
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +69 -20
- package/src/audit/save.js +48 -0
- package/src/commands/audit/auditConfig.ts +0 -25
- package/src/commands/audit/auditController.ts +18 -20
- package/src/commands/audit/help.ts +31 -25
- package/src/commands/audit/processAudit.ts +3 -6
- package/src/commands/audit/saveFile.ts +6 -2
- package/src/commands/scan/processScan.js +0 -1
- package/src/commands/scan/sca/scaAnalysis.js +84 -30
- package/src/common/HTTPClient.js +81 -34
- package/src/common/errorHandling.ts +10 -1
- package/src/common/versionChecker.ts +24 -5
- package/src/constants/constants.js +9 -3
- package/src/constants/locales.js +58 -43
- package/src/constants.js +21 -14
- package/src/index.ts +70 -58
- package/src/lambda/analytics.ts +9 -0
- package/src/lambda/arn.ts +2 -1
- package/src/lambda/lambda.ts +40 -17
- package/src/lambda/types.ts +36 -0
- package/src/lambda/utils.ts +2 -7
- package/src/sbom/generateSbom.ts +2 -2
- package/src/scaAnalysis/common/formatMessage.js +48 -1
- package/src/scaAnalysis/common/treeUpload.js +4 -6
- package/src/scaAnalysis/dotnet/analysis.js +54 -0
- package/src/scaAnalysis/dotnet/index.js +11 -0
- package/src/scaAnalysis/go/goAnalysis.js +2 -3
- package/src/scaAnalysis/go/goReadDepFile.js +1 -3
- package/src/scaAnalysis/java/analysis.js +7 -8
- package/src/scaAnalysis/java/index.js +2 -2
- package/src/scaAnalysis/javascript/analysis.js +126 -0
- package/src/scaAnalysis/javascript/index.js +72 -0
- package/src/scaAnalysis/php/analysis.js +78 -0
- package/src/scaAnalysis/php/index.js +22 -0
- package/src/scaAnalysis/python/analysis.js +49 -0
- package/src/scaAnalysis/python/index.js +11 -0
- package/src/scaAnalysis/ruby/analysis.js +273 -0
- package/src/scaAnalysis/ruby/index.js +11 -0
- package/src/scan/autoDetection.js +24 -26
- package/src/scan/fileUtils.js +60 -20
- package/src/scan/formatScanOutput.ts +14 -15
- package/src/scan/models/groupedResultsModel.ts +3 -3
- package/src/scan/models/resultContentModel.ts +1 -1
- package/src/scan/models/scanResultsModel.ts +5 -2
- package/src/scan/populateProjectIdAndProjectName.js +3 -1
- package/src/scan/scan.ts +1 -0
- package/src/scan/scanConfig.js +7 -5
- package/src/scan/scanController.js +18 -4
- package/src/scan/scanResults.js +10 -0
- package/src/utils/commonApi.js +4 -1
- package/src/utils/filterProjectPath.js +6 -2
- package/src/utils/getConfig.ts +1 -12
- package/dist/audit/AnalysisEngine.js +0 -37
- package/dist/audit/autodetection/autoDetectLanguage.js +0 -32
- package/dist/audit/dotnetAnalysisEngine/index.js +0 -25
- package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -35
- package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -15
- package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -18
- package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -14
- package/dist/audit/dotnetAnalysisEngine/sanitizer.js +0 -9
- package/dist/audit/goAnalysisEngine/index.js +0 -17
- package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +0 -164
- package/dist/audit/goAnalysisEngine/readProjectFileContents.js +0 -21
- package/dist/audit/goAnalysisEngine/sanitizer.js +0 -5
- package/dist/audit/javaAnalysisEngine/index.js +0 -34
- package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -153
- package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -353
- package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +0 -98
- package/dist/audit/javaAnalysisEngine/sanitizer.js +0 -5
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -24
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -24
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -35
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -23
- package/dist/audit/languageAnalysisEngine/constants.js +0 -20
- package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -25
- package/dist/audit/languageAnalysisEngine/index.js +0 -39
- package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -87
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -150
- package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -40
- package/dist/audit/nodeAnalysisEngine/index.js +0 -31
- package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -18
- package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -18
- package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -17
- package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -14
- package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -24
- package/dist/audit/nodeAnalysisEngine/sanitizer.js +0 -9
- package/dist/audit/phpAnalysisEngine/index.js +0 -23
- package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +0 -52
- package/dist/audit/phpAnalysisEngine/readLockFileContents.js +0 -13
- package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +0 -16
- package/dist/audit/phpAnalysisEngine/sanitizer.js +0 -5
- package/dist/audit/pythonAnalysisEngine/index.js +0 -25
- package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -17
- package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -21
- package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -13
- package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -14
- package/dist/audit/pythonAnalysisEngine/sanitizer.js +0 -7
- package/dist/audit/rubyAnalysisEngine/index.js +0 -25
- package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -176
- package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +0 -22
- package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +0 -14
- package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -14
- package/dist/audit/rubyAnalysisEngine/sanitizer.js +0 -6
- package/src/audit/AnalysisEngine.js +0 -103
- package/src/audit/autodetection/autoDetectLanguage.ts +0 -40
- package/src/audit/dotnetAnalysisEngine/index.js +0 -26
- package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +0 -47
- package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +0 -29
- package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +0 -30
- package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +0 -26
- package/src/audit/dotnetAnalysisEngine/sanitizer.js +0 -11
- package/src/audit/goAnalysisEngine/index.js +0 -18
- package/src/audit/goAnalysisEngine/parseProjectFileContents.js +0 -209
- package/src/audit/goAnalysisEngine/readProjectFileContents.js +0 -31
- package/src/audit/goAnalysisEngine/sanitizer.js +0 -7
- package/src/audit/javaAnalysisEngine/index.js +0 -41
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +0 -222
- package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +0 -420
- package/src/audit/javaAnalysisEngine/readProjectFileContents.js +0 -141
- package/src/audit/javaAnalysisEngine/sanitizer.js +0 -6
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +0 -35
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +0 -41
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +0 -54
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +0 -32
- package/src/audit/languageAnalysisEngine/constants.js +0 -23
- package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +0 -41
- package/src/audit/languageAnalysisEngine/index.js +0 -45
- package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +0 -116
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +0 -249
- package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +0 -49
- package/src/audit/nodeAnalysisEngine/index.js +0 -35
- package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +0 -20
- package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +0 -26
- package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +0 -23
- package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +0 -27
- package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +0 -36
- package/src/audit/nodeAnalysisEngine/sanitizer.js +0 -11
- package/src/audit/phpAnalysisEngine/index.js +0 -27
- package/src/audit/phpAnalysisEngine/parseLockFileContents.js +0 -60
- package/src/audit/phpAnalysisEngine/readLockFileContents.js +0 -14
- package/src/audit/phpAnalysisEngine/readProjectFileContents.js +0 -25
- package/src/audit/phpAnalysisEngine/sanitizer.js +0 -4
- package/src/audit/pythonAnalysisEngine/index.js +0 -55
- package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +0 -23
- package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +0 -33
- package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +0 -16
- package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +0 -22
- package/src/audit/pythonAnalysisEngine/sanitizer.js +0 -9
- package/src/audit/rubyAnalysisEngine/index.js +0 -30
- package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +0 -215
- package/src/audit/rubyAnalysisEngine/parsedGemfile.js +0 -39
- package/src/audit/rubyAnalysisEngine/readGemfileContents.js +0 -18
- package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +0 -17
- 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
|
|
18
|
+
import { SeverityCountModel } from './models/severityCountModel'
|
|
18
19
|
import {
|
|
19
20
|
ReportOutputBodyModel,
|
|
20
21
|
ReportOutputHeaderModel,
|
|
21
22
|
ReportOutputModel
|
|
22
|
-
} from
|
|
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
|
|
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
|
-
`
|
|
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
|
-
|
|
61
|
-
|
|
62
|
+
config: any,
|
|
63
|
+
vulnerableLibraries: ReportLibraryModel[],
|
|
64
|
+
numberOfVulnerableLibraries: number,
|
|
65
|
+
numberOfCves: number,
|
|
66
|
+
guidance: any
|
|
62
67
|
) => {
|
|
63
68
|
let hasSomeVulnerabilitiesReported = false
|
|
64
|
-
printFormattedOutput(
|
|
65
|
-
|
|
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
|
-
|
|
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
|
|
111
|
+
const outputOrderedByLowestSeverityAndLowestNumOfCvesFirst = orderBy(
|
|
93
112
|
report.reportOutputList,
|
|
94
|
-
|
|
95
|
-
|
|
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
|
|
125
|
+
for (const reportModel of outputOrderedByLowestSeverityAndLowestNumOfCvesFirst) {
|
|
100
126
|
contrastHeaderNumCounter++
|
|
101
|
-
const {libraryName, libraryVersion, highestSeverity} =
|
|
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
|
|
113
|
-
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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 =
|
|
202
|
+
const vulnerabilityPluralised =
|
|
203
|
+
numOfCVEs > 1 ? 'vulnerabilities' : 'vulnerability'
|
|
131
204
|
const formattedHeaderNum = buildFormattedHeaderNum(contrastHeaderNum)
|
|
132
205
|
|
|
133
206
|
const vulnMessage = chalk
|
|
134
|
-
|
|
135
|
-
|
|
207
|
+
.hex(highestSeverity.outputColour)
|
|
208
|
+
.bold(
|
|
209
|
+
`${formattedHeaderNum} - [${highestSeverity.severity}] ${libraryName}-${version}`
|
|
210
|
+
)
|
|
136
211
|
|
|
137
|
-
const introducesMessage =
|
|
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(
|
|
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
|
-
|
|
153
|
-
|
|
226
|
+
.hex(outputColour)
|
|
227
|
+
.bold(`[${severity.charAt(0).toUpperCase()}]`)
|
|
154
228
|
|
|
155
|
-
const builtMessage =
|
|
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
|
|
166
|
-
` ${chalk.bold('Advice')} : ${chalk.bold('Update to latest version')}.`
|
|
238
|
+
const issueMessageCves = ['', '', cveMessages.join(', ')]
|
|
167
239
|
|
|
168
|
-
|
|
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
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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
|
-
|
|
203
|
-
|
|
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
|
|
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
|
|
2
|
-
import {ReportCVEModel} from
|
|
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
|
|
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
|
|
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
|
-
|
|
22
|
+
issueMessage: string[]
|
|
23
|
+
issueMessageCves: string[]
|
|
24
|
+
adviceMessage: string[]
|
|
24
25
|
|
|
25
|
-
constructor(
|
|
26
|
-
|
|
27
|
-
|
|
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(
|
|
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
|
|
@@ -1,56 +1,110 @@
|
|
|
1
1
|
import {
|
|
2
|
-
createLibraryHeader,
|
|
3
2
|
getReport,
|
|
4
3
|
printVulnerabilityResponse
|
|
5
4
|
} from './commonReportingFunctions'
|
|
6
5
|
import {
|
|
7
|
-
|
|
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
|
|
12
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
34
|
-
|
|
47
|
+
config: any,
|
|
48
|
+
remediationGuidance: any
|
|
35
49
|
) {
|
|
36
|
-
const vulnerableLibraries =
|
|
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
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
}
|