@contrast/contrast 1.0.6 → 1.0.7
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/javaAnalysisEngine/parseMavenProjectFileContents.js +4 -2
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
- package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +2 -0
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +10 -1
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +6 -9
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +65 -3
- package/dist/commands/audit/processAudit.js +1 -1
- package/dist/commands/scan/sca/scaAnalysis.js +13 -2
- package/dist/common/HTTPClient.js +50 -15
- package/dist/common/errorHandling.js +6 -1
- package/dist/common/versionChecker.js +1 -1
- package/dist/constants/constants.js +1 -1
- package/dist/constants/locales.js +3 -1
- package/dist/lambda/analytics.js +11 -0
- package/dist/lambda/lambda.js +35 -4
- package/dist/lambda/types.js +13 -0
- package/dist/scaAnalysis/common/formatMessage.js +17 -1
- package/dist/scaAnalysis/java/analysis.js +3 -6
- package/dist/scaAnalysis/java/index.js +2 -2
- package/dist/scaAnalysis/python/analysis.js +41 -0
- package/dist/scaAnalysis/python/index.js +10 -0
- package/dist/scaAnalysis/ruby/analysis.js +226 -0
- package/dist/scaAnalysis/ruby/index.js +10 -0
- package/dist/scan/autoDetection.js +6 -2
- package/dist/scan/fileUtils.js +14 -7
- package/dist/scan/formatScanOutput.js +9 -11
- 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 +6 -1
- package/dist/scan/scanController.js +16 -3
- package/dist/scan/scanResults.js +5 -1
- package/dist/utils/commonApi.js +4 -1
- package/package.json +11 -7
- package/src/audit/catalogueApplication/catalogueApplication.js +0 -1
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +11 -8
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
- package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +8 -0
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +10 -9
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +34 -29
- package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +3 -3
- package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +15 -11
- package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +6 -1
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +43 -27
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +78 -3
- package/src/commands/audit/processAudit.ts +1 -1
- package/src/commands/scan/sca/scaAnalysis.js +13 -5
- package/src/common/HTTPClient.js +65 -25
- package/src/common/errorHandling.ts +10 -1
- package/src/common/versionChecker.ts +1 -1
- package/src/constants/constants.js +1 -1
- package/src/constants/locales.js +3 -1
- package/src/lambda/analytics.ts +9 -0
- package/src/lambda/arn.ts +2 -1
- package/src/lambda/lambda.ts +37 -17
- package/src/lambda/types.ts +35 -0
- package/src/lambda/utils.ts +2 -7
- package/src/scaAnalysis/common/formatMessage.js +19 -1
- package/src/scaAnalysis/go/goAnalysis.js +2 -3
- package/src/scaAnalysis/java/analysis.js +5 -6
- package/src/scaAnalysis/java/index.js +2 -2
- package/src/scaAnalysis/python/analysis.js +48 -0
- package/src/scaAnalysis/python/index.js +11 -0
- package/src/scaAnalysis/ruby/analysis.js +282 -0
- package/src/scaAnalysis/ruby/index.js +11 -0
- package/src/scan/autoDetection.js +9 -5
- package/src/scan/fileUtils.js +15 -7
- package/src/scan/formatScanOutput.ts +11 -12
- 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 +5 -1
- package/src/scan/scanController.js +18 -4
- package/src/scan/scanResults.js +10 -0
- package/src/utils/commonApi.js +4 -1
|
@@ -34,12 +34,13 @@ const formatKeyName = value => {
|
|
|
34
34
|
return tempArr[0] + '/' + tempArr[1] + '@' + tempArr[versionIndex]
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
const shaveConsoleOutputUntilItFindsFirsDigraphMention =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
mvnDependancyTreeOutput.
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
const shaveConsoleOutputUntilItFindsFirsDigraphMention =
|
|
38
|
+
mvnDependancyTreeOutput => {
|
|
39
|
+
//shaves of the console output until it reaches the first digraph
|
|
40
|
+
return mvnDependancyTreeOutput.substring(
|
|
41
|
+
mvnDependancyTreeOutput.indexOf('digraph')
|
|
42
|
+
)
|
|
43
|
+
}
|
|
43
44
|
|
|
44
45
|
const getDigraphObjInfo = editedOutput => {
|
|
45
46
|
//turns the output into an array of digraph information
|
|
@@ -211,10 +212,12 @@ const parseMvn = mvnDependancyTreeOutput => {
|
|
|
211
212
|
}
|
|
212
213
|
|
|
213
214
|
// testing purposes
|
|
214
|
-
exports.shaveConsoleOutputUntilItFindsFirsDigraphMention =
|
|
215
|
+
exports.shaveConsoleOutputUntilItFindsFirsDigraphMention =
|
|
216
|
+
shaveConsoleOutputUntilItFindsFirsDigraphMention
|
|
215
217
|
exports.getDigraphObjInfo = getDigraphObjInfo
|
|
216
218
|
exports.createDigraphObjKey = createDigraphObjKey
|
|
217
|
-
exports.turnDigraphDependanciesIntoArrOfInnerDep =
|
|
219
|
+
exports.turnDigraphDependanciesIntoArrOfInnerDep =
|
|
220
|
+
turnDigraphDependanciesIntoArrOfInnerDep
|
|
218
221
|
exports.hasVersion = hasVersion
|
|
219
222
|
exports.formatKeyName = formatKeyName
|
|
220
223
|
exports.createOuterDependanciesAndType = createOuterDependanciesAndType
|
|
@@ -32,4 +32,5 @@ const checkForMultipleIdentifiedLanguages = identifiedLanguages => {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
//For testing purposes
|
|
35
|
-
exports.checkForMultipleIdentifiedLanguages =
|
|
35
|
+
exports.checkForMultipleIdentifiedLanguages =
|
|
36
|
+
checkForMultipleIdentifiedLanguages
|
|
@@ -38,4 +38,5 @@ const checkForMultipleIdentifiedProjectFiles = identifiedLanguages => {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
//For testing purposes
|
|
41
|
-
exports.checkForMultipleIdentifiedProjectFiles =
|
|
41
|
+
exports.checkForMultipleIdentifiedProjectFiles =
|
|
42
|
+
checkForMultipleIdentifiedProjectFiles
|
|
@@ -29,4 +29,5 @@ const checkIdentifiedLanguageHasProjectFile = identifiedLanguages => {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
//For testing purposes
|
|
32
|
-
exports.checkIdentifiedLanguageHasProjectFile =
|
|
32
|
+
exports.checkIdentifiedLanguageHasProjectFile =
|
|
33
|
+
checkIdentifiedLanguageHasProjectFile
|
|
@@ -21,6 +21,7 @@ const {
|
|
|
21
21
|
startSpinner,
|
|
22
22
|
succeedSpinner
|
|
23
23
|
} = require('../../utils/oraWrapper')
|
|
24
|
+
const { pollForSnapshotCompletition } = require('./sendSnapshot')
|
|
24
25
|
|
|
25
26
|
module.exports = exports = (err, analysis) => {
|
|
26
27
|
const { identifiedLanguageInfo } = analysis.languageAnalysis
|
|
@@ -54,6 +55,13 @@ module.exports = exports = (err, analysis) => {
|
|
|
54
55
|
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
|
|
55
56
|
startSpinner(reportSpinner)
|
|
56
57
|
const snapshotResponse = await newSendSnapShot(analysis, catalogueAppId)
|
|
58
|
+
|
|
59
|
+
//poll for completion
|
|
60
|
+
const pollResult = await pollForSnapshotCompletition(
|
|
61
|
+
analysis.config,
|
|
62
|
+
snapshotResponse.id,
|
|
63
|
+
reportSpinner
|
|
64
|
+
)
|
|
57
65
|
succeedSpinner(reportSpinner, 'Contrast SCA analysis complete')
|
|
58
66
|
|
|
59
67
|
await vulnerabilityReport(analysis, catalogueAppId, snapshotResponse.id)
|
|
@@ -53,13 +53,15 @@ const deduceLanguageScaAnalysis = filenames => {
|
|
|
53
53
|
// deducedLanguages.push({language: DOTNET, projectFilename: filename})
|
|
54
54
|
// }
|
|
55
55
|
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
if (isRubyProjectFilename(filename)) {
|
|
57
|
+
deducedLanguages.push(filename)
|
|
58
|
+
language = RUBY
|
|
59
|
+
}
|
|
59
60
|
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
if (isPythonProjectFilename(filename)) {
|
|
62
|
+
deducedLanguages.push(filename)
|
|
63
|
+
language = PYTHON
|
|
64
|
+
}
|
|
63
65
|
//
|
|
64
66
|
// if (isPhpProjectFilename(filename)) {
|
|
65
67
|
// deducedLanguages.push({language: PHP, projectFilename: filename})
|
|
@@ -207,9 +209,8 @@ module.exports = exports = (analysis, next) => {
|
|
|
207
209
|
|
|
208
210
|
let language = config.language
|
|
209
211
|
if (language === undefined) {
|
|
210
|
-
languageAnalysis.identifiedLanguages =
|
|
211
|
-
identifiedLanguages
|
|
212
|
-
)
|
|
212
|
+
languageAnalysis.identifiedLanguages =
|
|
213
|
+
reduceIdentifiedLanguages(identifiedLanguages)
|
|
213
214
|
} else {
|
|
214
215
|
let refinedIdentifiedLanguages = []
|
|
215
216
|
for (let x in identifiedLanguages) {
|
|
@@ -14,12 +14,12 @@ import {
|
|
|
14
14
|
findNameAndVersion,
|
|
15
15
|
severityCountAllCVEs
|
|
16
16
|
} from './utils/reportUtils'
|
|
17
|
-
import {SeverityCountModel} from
|
|
17
|
+
import { SeverityCountModel } from './models/severityCountModel'
|
|
18
18
|
import {
|
|
19
19
|
ReportOutputBodyModel,
|
|
20
20
|
ReportOutputHeaderModel,
|
|
21
21
|
ReportOutputModel
|
|
22
|
-
} from
|
|
22
|
+
} from './models/reportOutputModel'
|
|
23
23
|
|
|
24
24
|
export const createLibraryHeader = (
|
|
25
25
|
id: string,
|
|
@@ -98,7 +98,8 @@ export const printFormattedOutput = (
|
|
|
98
98
|
let contrastHeaderNumCounter = 0
|
|
99
99
|
for (const reportModel of orderedOutputListLowestFirst) {
|
|
100
100
|
contrastHeaderNumCounter++
|
|
101
|
-
const {libraryName, libraryVersion, highestSeverity} =
|
|
101
|
+
const { libraryName, libraryVersion, highestSeverity } =
|
|
102
|
+
reportModel.compositeKey
|
|
102
103
|
const numOfCVEs = reportModel.cveArray.length
|
|
103
104
|
|
|
104
105
|
const header = buildHeader(
|
|
@@ -109,12 +110,13 @@ export const printFormattedOutput = (
|
|
|
109
110
|
numOfCVEs
|
|
110
111
|
)
|
|
111
112
|
|
|
112
|
-
const body = buildBody(
|
|
113
|
-
reportModel.cveArray
|
|
114
|
-
)
|
|
113
|
+
const body = buildBody(reportModel.cveArray)
|
|
115
114
|
|
|
116
115
|
const reportOutputModel = new ReportOutputModel(header, body)
|
|
117
|
-
console.log(
|
|
116
|
+
console.log(
|
|
117
|
+
reportOutputModel.header.vulnMessage,
|
|
118
|
+
reportOutputModel.header.introducesMessage
|
|
119
|
+
)
|
|
118
120
|
console.log(reportOutputModel.body.issueMessage)
|
|
119
121
|
console.log(reportOutputModel.body.adviceMessage)
|
|
120
122
|
}
|
|
@@ -125,14 +127,17 @@ export function buildHeader(
|
|
|
125
127
|
contrastHeaderNum: number,
|
|
126
128
|
libraryName: string,
|
|
127
129
|
version: string,
|
|
128
|
-
numOfCVEs: number
|
|
130
|
+
numOfCVEs: number
|
|
129
131
|
) {
|
|
130
|
-
const vulnerabilityPluralised =
|
|
132
|
+
const vulnerabilityPluralised =
|
|
133
|
+
numOfCVEs > 1 ? 'Vulnerabilities' : 'Vulnerability'
|
|
131
134
|
const formattedHeaderNum = buildFormattedHeaderNum(contrastHeaderNum)
|
|
132
135
|
|
|
133
136
|
const vulnMessage = chalk
|
|
134
|
-
|
|
135
|
-
|
|
137
|
+
.hex(highestSeverity.outputColour)
|
|
138
|
+
.bold(
|
|
139
|
+
`${formattedHeaderNum} - [${highestSeverity.severity}] ${libraryName}-${version}`
|
|
140
|
+
)
|
|
136
141
|
|
|
137
142
|
const introducesMessage = chalk.bold(
|
|
138
143
|
`introduces ${numOfCVEs} ${vulnerabilityPluralised}`
|
|
@@ -144,13 +149,14 @@ export function buildHeader(
|
|
|
144
149
|
export function buildBody(cveArray: ReportCVEModel[]) {
|
|
145
150
|
const cveMessages: string[] = []
|
|
146
151
|
|
|
147
|
-
findCVESeveritiesAndOrderByHighestPriority(cveArray).forEach(
|
|
152
|
+
findCVESeveritiesAndOrderByHighestPriority(cveArray).forEach(
|
|
153
|
+
reportSeverityModel => {
|
|
148
154
|
// @ts-ignore
|
|
149
|
-
const {outputColour, severity, cveName} = reportSeverityModel
|
|
155
|
+
const { outputColour, severity, cveName } = reportSeverityModel
|
|
150
156
|
|
|
151
157
|
const severityShorthand = chalk
|
|
152
|
-
|
|
153
|
-
|
|
158
|
+
.hex(outputColour)
|
|
159
|
+
.bold(`[${severity.charAt(0).toUpperCase()}]`)
|
|
154
160
|
|
|
155
161
|
const builtMessage = `${severityShorthand} ${cveName}`
|
|
156
162
|
cveMessages.push(builtMessage)
|
|
@@ -159,11 +165,13 @@ export function buildBody(cveArray: ReportCVEModel[]) {
|
|
|
159
165
|
|
|
160
166
|
const numAndSeverityType = getNumOfAndSeverityType(cveArray)
|
|
161
167
|
|
|
162
|
-
const issueMessage =
|
|
163
|
-
|
|
168
|
+
const issueMessage = ` ${chalk.bold(
|
|
169
|
+
'Issue'
|
|
170
|
+
)} : ${numAndSeverityType} ${cveMessages.join(', ')}.`
|
|
164
171
|
|
|
165
|
-
const adviceMessage =
|
|
166
|
-
|
|
172
|
+
const adviceMessage = ` ${chalk.bold('Advice')} : ${chalk.bold(
|
|
173
|
+
'Update to latest version'
|
|
174
|
+
)}.`
|
|
167
175
|
|
|
168
176
|
return new ReportOutputBodyModel(issueMessage, adviceMessage)
|
|
169
177
|
}
|
|
@@ -183,13 +191,10 @@ export function buildFormattedHeaderNum(contrastHeaderNum: number) {
|
|
|
183
191
|
}
|
|
184
192
|
|
|
185
193
|
export function getNumOfAndSeverityType(cveArray: ReportCVEModel[]) {
|
|
186
|
-
const {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
low,
|
|
191
|
-
note
|
|
192
|
-
} = severityCountAllCVEs(cveArray, new SeverityCountModel())
|
|
194
|
+
const { critical, high, medium, low, note } = severityCountAllCVEs(
|
|
195
|
+
cveArray,
|
|
196
|
+
new SeverityCountModel()
|
|
197
|
+
)
|
|
193
198
|
|
|
194
199
|
const criticalMessage = critical > 0 ? `${critical} Critical` : ''
|
|
195
200
|
const highMessage = high > 0 ? `${high} High` : ''
|
|
@@ -199,6 +204,6 @@ export function getNumOfAndSeverityType(cveArray: ReportCVEModel[]) {
|
|
|
199
204
|
|
|
200
205
|
//removes/trims whitespace to single spaces
|
|
201
206
|
return `${criticalMessage} ${highMessage} ${mediumMessage} ${lowMessage} ${noteMessage}`
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
207
|
+
.replace(/\s+/g, ' ')
|
|
208
|
+
.trim()
|
|
209
|
+
}
|
|
@@ -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,36 @@
|
|
|
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
26
|
|
|
27
|
-
constructor
|
|
27
|
+
constructor(
|
|
28
|
+
libraryName: string,
|
|
29
|
+
libraryVersion: string,
|
|
30
|
+
highestSeverity: ReportSeverityModel
|
|
31
|
+
) {
|
|
28
32
|
this.libraryName = libraryName
|
|
29
33
|
this.libraryVersion = libraryVersion
|
|
30
34
|
this.highestSeverity = highestSeverity
|
|
31
35
|
}
|
|
32
|
-
}
|
|
36
|
+
}
|
|
@@ -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
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
NOTE_PRIORITY
|
|
18
18
|
} from '../../../../constants/constants'
|
|
19
19
|
import { orderBy } from 'lodash'
|
|
20
|
-
import {SeverityCountModel} from
|
|
20
|
+
import { SeverityCountModel } from '../models/severityCountModel'
|
|
21
21
|
const {
|
|
22
22
|
supportedLanguages: { GO }
|
|
23
23
|
} = languageAnalysisEngine
|
|
@@ -29,19 +29,37 @@ export function findHighestSeverityCVE(cveArray: ReportCVEModel[]) {
|
|
|
29
29
|
return orderBy(mappedToReportSeverityModels, cve => cve?.priority)[0]
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
export function findCVESeveritiesAndOrderByHighestPriority(
|
|
33
|
+
cves: ReportCVEModel[]
|
|
34
|
+
) {
|
|
35
|
+
return orderBy(
|
|
36
|
+
cves.map(cve => findCVESeverity(cve)),
|
|
37
|
+
['priority'],
|
|
38
|
+
['asc']
|
|
39
|
+
)
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
export function findCVESeverity(cve: ReportCVEModel) {
|
|
38
43
|
const cveName = cve.name as string
|
|
39
44
|
if (cve.cvss3SeverityCode === 'CRITICAL' || cve.severityCode === 'CRITICAL') {
|
|
40
|
-
return new ReportSeverityModel(
|
|
45
|
+
return new ReportSeverityModel(
|
|
46
|
+
'CRITICAL',
|
|
47
|
+
CRITICAL_PRIORITY,
|
|
48
|
+
CRITICAL_COLOUR,
|
|
49
|
+
cveName
|
|
50
|
+
)
|
|
41
51
|
} else if (cve.cvss3SeverityCode === 'HIGH' || cve.severityCode === 'HIGH') {
|
|
42
52
|
return new ReportSeverityModel('HIGH', HIGH_PRIORITY, HIGH_COLOUR, cveName)
|
|
43
|
-
} else if (
|
|
44
|
-
|
|
53
|
+
} else if (
|
|
54
|
+
cve.cvss3SeverityCode === 'MEDIUM' ||
|
|
55
|
+
cve.severityCode === 'MEDIUM'
|
|
56
|
+
) {
|
|
57
|
+
return new ReportSeverityModel(
|
|
58
|
+
'MEDIUM',
|
|
59
|
+
MEDIUM_PRIORITY,
|
|
60
|
+
MEDIUM_COLOUR,
|
|
61
|
+
cveName
|
|
62
|
+
)
|
|
45
63
|
} else if (cve.cvss3SeverityCode === 'LOW' || cve.severityCode === 'LOW') {
|
|
46
64
|
return new ReportSeverityModel('LOW', LOW_PRIORITY, LOW_COLOUR, cveName)
|
|
47
65
|
} else if (cve.cvss3SeverityCode === 'NOTE' || cve.severityCode === 'NOTE') {
|
|
@@ -55,43 +73,41 @@ export function convertGenericToTypedLibraries(libraries: any) {
|
|
|
55
73
|
})
|
|
56
74
|
}
|
|
57
75
|
|
|
58
|
-
export function severityCountAllLibraries(
|
|
76
|
+
export function severityCountAllLibraries(
|
|
77
|
+
vulnerableLibraries: ReportLibraryModel[]
|
|
78
|
+
) {
|
|
59
79
|
const severityCount = new SeverityCountModel()
|
|
60
|
-
vulnerableLibraries.forEach(lib =>
|
|
80
|
+
vulnerableLibraries.forEach(lib =>
|
|
81
|
+
severityCountAllCVEs(lib.cveArray, severityCount)
|
|
82
|
+
)
|
|
61
83
|
return severityCount
|
|
62
84
|
}
|
|
63
85
|
|
|
64
|
-
export function severityCountAllCVEs(
|
|
86
|
+
export function severityCountAllCVEs(
|
|
87
|
+
cveArray: ReportCVEModel[],
|
|
88
|
+
severityCount: SeverityCountModel
|
|
89
|
+
) {
|
|
65
90
|
const severityCountInner = severityCount
|
|
66
91
|
cveArray.forEach(cve => severityCountSingleCVE(cve, severityCountInner))
|
|
67
92
|
return severityCountInner
|
|
68
93
|
}
|
|
69
94
|
|
|
70
|
-
export function severityCountSingleCVE(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
) {
|
|
95
|
+
export function severityCountSingleCVE(
|
|
96
|
+
cve: ReportCVEModel,
|
|
97
|
+
severityCount: SeverityCountModel
|
|
98
|
+
) {
|
|
99
|
+
if (cve.cvss3SeverityCode === 'CRITICAL' || cve.severityCode === 'CRITICAL') {
|
|
75
100
|
severityCount.critical += 1
|
|
76
|
-
} else if (
|
|
77
|
-
cve.cvss3SeverityCode === 'HIGH' ||
|
|
78
|
-
cve.severityCode === 'HIGH'
|
|
79
|
-
) {
|
|
101
|
+
} else if (cve.cvss3SeverityCode === 'HIGH' || cve.severityCode === 'HIGH') {
|
|
80
102
|
severityCount.high += 1
|
|
81
103
|
} else if (
|
|
82
104
|
cve.cvss3SeverityCode === 'MEDIUM' ||
|
|
83
105
|
cve.severityCode === 'MEDIUM'
|
|
84
106
|
) {
|
|
85
107
|
severityCount.medium += 1
|
|
86
|
-
} else if (
|
|
87
|
-
cve.cvss3SeverityCode === 'LOW' ||
|
|
88
|
-
cve.severityCode === 'LOW'
|
|
89
|
-
) {
|
|
108
|
+
} else if (cve.cvss3SeverityCode === 'LOW' || cve.severityCode === 'LOW') {
|
|
90
109
|
severityCount.low += 1
|
|
91
|
-
} else if (
|
|
92
|
-
cve.cvss3SeverityCode === 'NOTE' ||
|
|
93
|
-
cve.severityCode === 'NOTE'
|
|
94
|
-
) {
|
|
110
|
+
} else if (cve.cvss3SeverityCode === 'NOTE' || cve.severityCode === 'NOTE') {
|
|
95
111
|
severityCount.note += 1
|
|
96
112
|
}
|
|
97
113
|
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
const { getHttpClient } = require('../../utils/commonApi')
|
|
2
1
|
const { handleResponseErrors } = require('../../common/errorHandling')
|
|
3
2
|
const { APP_VERSION } = require('../../constants/constants')
|
|
3
|
+
const commonApi = require('../../utils/commonApi')
|
|
4
|
+
const _ = require('lodash')
|
|
5
|
+
const oraFunctions = require('../../utils/oraWrapper')
|
|
6
|
+
const i18n = require('i18n')
|
|
7
|
+
const oraWrapper = require('../../utils/oraWrapper')
|
|
8
|
+
const requestUtils = require('../../utils/requestUtils')
|
|
9
|
+
const { performance } = require('perf_hooks')
|
|
4
10
|
|
|
5
11
|
const newSendSnapShot = async analysis => {
|
|
6
12
|
const analysisLanguage = analysis.config.language.toLowerCase()
|
|
@@ -10,7 +16,7 @@ const newSendSnapShot = async analysis => {
|
|
|
10
16
|
snapshot: { [analysisLanguage]: analysis[analysisLanguage] }
|
|
11
17
|
}
|
|
12
18
|
|
|
13
|
-
const client = getHttpClient(analysis.config)
|
|
19
|
+
const client = commonApi.getHttpClient(analysis.config)
|
|
14
20
|
|
|
15
21
|
return client
|
|
16
22
|
.sendSnapshot(requestBody, analysis.config)
|
|
@@ -26,6 +32,75 @@ const newSendSnapShot = async analysis => {
|
|
|
26
32
|
})
|
|
27
33
|
}
|
|
28
34
|
|
|
35
|
+
const pollSnapshotResults = async (config, snapshotId, client) => {
|
|
36
|
+
await requestUtils.sleep(5000)
|
|
37
|
+
return client
|
|
38
|
+
.getReportStatusById(config, snapshotId)
|
|
39
|
+
.then(res => {
|
|
40
|
+
return res
|
|
41
|
+
})
|
|
42
|
+
.catch(err => {
|
|
43
|
+
console.log(err)
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const getTimeout = config => {
|
|
48
|
+
if (config.timeout) {
|
|
49
|
+
return config.timeout
|
|
50
|
+
} else {
|
|
51
|
+
if (config.verbose) {
|
|
52
|
+
console.log('Timeout set to 2 minutes')
|
|
53
|
+
}
|
|
54
|
+
return 120
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const pollForSnapshotCompletition = async (
|
|
59
|
+
config,
|
|
60
|
+
snapshotId,
|
|
61
|
+
reportSpinner
|
|
62
|
+
) => {
|
|
63
|
+
const client = commonApi.getHttpClient(config)
|
|
64
|
+
const startTime = performance.now()
|
|
65
|
+
const timeout = getTimeout(config)
|
|
66
|
+
|
|
67
|
+
let complete = false
|
|
68
|
+
if (!_.isNil(snapshotId)) {
|
|
69
|
+
while (!complete) {
|
|
70
|
+
let result = await pollSnapshotResults(config, snapshotId, client)
|
|
71
|
+
if (result.statusCode === 200) {
|
|
72
|
+
if (result.body.status === 'PROCESSED') {
|
|
73
|
+
complete = true
|
|
74
|
+
return result.body
|
|
75
|
+
}
|
|
76
|
+
if (result.body.status === 'FAILED') {
|
|
77
|
+
complete = true
|
|
78
|
+
if (config.debug) {
|
|
79
|
+
oraFunctions.failSpinner(
|
|
80
|
+
reportSpinner,
|
|
81
|
+
i18n.__('auditNotCompleted')
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
console.log(result.body.errorMessage)
|
|
85
|
+
oraWrapper.stopSpinner(reportSpinner)
|
|
86
|
+
console.log('Contrast audit finished')
|
|
87
|
+
process.exit(1)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const endTime = performance.now() - startTime
|
|
91
|
+
if (requestUtils.millisToSeconds(endTime) > timeout) {
|
|
92
|
+
oraFunctions.failSpinner(
|
|
93
|
+
reportSpinner,
|
|
94
|
+
'Contrast audit timed out at the specified ' + timeout + ' seconds.'
|
|
95
|
+
)
|
|
96
|
+
console.log('Please try again, allowing more time.')
|
|
97
|
+
process.exit(1)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
29
103
|
module.exports = {
|
|
30
|
-
newSendSnapShot: newSendSnapShot
|
|
104
|
+
newSendSnapShot: newSendSnapShot,
|
|
105
|
+
pollForSnapshotCompletition: pollForSnapshotCompletition
|
|
31
106
|
}
|
|
@@ -6,16 +6,19 @@ const {
|
|
|
6
6
|
} = require('../../../scan/autoDetection')
|
|
7
7
|
const auditController = require('../../audit/auditController')
|
|
8
8
|
const {
|
|
9
|
-
supportedLanguages: { JAVA, GO }
|
|
9
|
+
supportedLanguages: { JAVA, GO, RUBY, PYTHON }
|
|
10
10
|
} = require('../../../audit/languageAnalysisEngine/constants')
|
|
11
11
|
const goAnalysis = require('../../../scaAnalysis/go/goAnalysis')
|
|
12
|
+
const { rubyAnalysis } = require('../../../scaAnalysis/ruby')
|
|
13
|
+
const { pythonAnalysis } = require('../../../scaAnalysis/python')
|
|
12
14
|
|
|
13
15
|
const processSca = async config => {
|
|
14
16
|
let filesFound
|
|
15
17
|
if (config.projectPath) {
|
|
16
|
-
filesFound =
|
|
18
|
+
filesFound = manualDetectAuditFilesAndLanguages(config.projectPath)
|
|
17
19
|
} else {
|
|
18
20
|
filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config)
|
|
21
|
+
config.projectPath = process.cwd()
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
// files found looks like [ { javascript: [ Array ] } ]
|
|
@@ -34,9 +37,14 @@ const processSca = async config => {
|
|
|
34
37
|
// case 'dotnet':
|
|
35
38
|
// // code block
|
|
36
39
|
// break;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
case RUBY:
|
|
41
|
+
messageToSend = rubyAnalysis(config, filesFound[0])
|
|
42
|
+
config.language = RUBY
|
|
43
|
+
break
|
|
44
|
+
case PYTHON:
|
|
45
|
+
messageToSend = pythonAnalysis(config, filesFound[0])
|
|
46
|
+
config.language = PYTHON
|
|
47
|
+
break
|
|
40
48
|
// case 'ruby':
|
|
41
49
|
// // code block
|
|
42
50
|
// break;
|