@contrast/contrast 1.0.9 → 1.0.12
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/README.md +2 -2
- package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +17 -17
- package/dist/audit/{languageAnalysisEngine/report → report}/commonReportingFunctions.js +56 -35
- package/dist/audit/report/models/reportGuidanceModel.js +6 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportLibraryModel.js +0 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportListModel.js +0 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportOutputModel.js +1 -2
- package/dist/audit/{languageAnalysisEngine/report → report}/models/reportSeverityModel.js +0 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/models/severityCountModel.js +1 -0
- package/dist/audit/{languageAnalysisEngine/report → report}/reportingFeature.js +12 -8
- package/dist/audit/{languageAnalysisEngine/report → report}/utils/reportUtils.js +3 -4
- package/dist/commands/audit/auditConfig.js +3 -3
- package/dist/commands/audit/help.js +3 -1
- package/dist/commands/audit/processAudit.js +4 -2
- package/dist/commands/auth/auth.js +1 -1
- package/dist/commands/config/config.js +2 -2
- package/dist/commands/scan/processScan.js +11 -4
- package/dist/commands/scan/sca/scaAnalysis.js +20 -9
- package/dist/common/HTTPClient.js +9 -0
- package/dist/common/commonHelp.js +19 -0
- package/dist/common/errorHandling.js +2 -2
- package/dist/common/fail.js +66 -0
- package/dist/common/versionChecker.js +4 -2
- package/dist/constants/constants.js +2 -2
- package/dist/constants/locales.js +26 -11
- package/dist/constants.js +52 -5
- package/dist/index.js +5 -2
- package/dist/lambda/help.js +2 -3
- package/dist/scaAnalysis/common/scaParserForGoAndJava.js +32 -0
- package/dist/scaAnalysis/common/treeUpload.js +20 -5
- package/dist/scaAnalysis/dotnet/analysis.js +15 -3
- package/dist/scaAnalysis/go/goAnalysis.js +8 -2
- package/dist/scaAnalysis/java/analysis.js +10 -6
- package/dist/scaAnalysis/java/index.js +7 -1
- package/dist/scaAnalysis/java/javaBuildDepsParser.js +19 -3
- package/dist/scaAnalysis/javascript/index.js +3 -0
- package/dist/scaAnalysis/php/analysis.js +1 -1
- package/dist/scaAnalysis/php/index.js +12 -6
- package/dist/scaAnalysis/php/phpNewServicesMapper.js +62 -0
- package/dist/scaAnalysis/python/analysis.js +43 -5
- package/dist/scaAnalysis/python/index.js +7 -2
- package/dist/scaAnalysis/ruby/analysis.js +14 -4
- package/dist/scan/autoDetection.js +5 -13
- package/dist/scan/formatScanOutput.js +6 -5
- package/dist/scan/help.js +2 -3
- package/dist/scan/populateProjectIdAndProjectName.js +5 -0
- package/dist/scan/scan.js +4 -0
- package/dist/scan/scanConfig.js +4 -4
- package/dist/scan/scanResults.js +46 -3
- package/dist/telemetry/telemetry.js +137 -0
- package/dist/utils/commonApi.js +1 -1
- package/dist/utils/getConfig.js +2 -4
- package/dist/utils/parsedCLIOptions.js +3 -1
- package/dist/utils/requestUtils.js +7 -1
- package/package.json +4 -2
- package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +22 -29
- package/src/audit/{languageAnalysisEngine/report → report}/commonReportingFunctions.ts +80 -44
- package/src/audit/report/models/reportGuidanceModel.ts +5 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportLibraryModel.ts +0 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportListModel.ts +0 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportOutputModel.ts +1 -7
- package/src/audit/{languageAnalysisEngine/report → report}/models/reportSeverityModel.ts +0 -0
- package/src/audit/{languageAnalysisEngine/report → report}/models/severityCountModel.ts +2 -0
- package/src/audit/{languageAnalysisEngine/report → report}/reportingFeature.ts +16 -9
- package/src/audit/{languageAnalysisEngine/report → report}/utils/reportUtils.ts +4 -4
- package/src/commands/audit/auditConfig.ts +10 -3
- package/src/commands/audit/help.ts +3 -1
- package/src/commands/audit/processAudit.ts +16 -2
- package/src/commands/auth/auth.js +3 -1
- package/src/commands/config/config.js +4 -2
- package/src/commands/scan/processScan.js +18 -4
- package/src/commands/scan/sca/scaAnalysis.js +27 -10
- package/src/common/HTTPClient.js +15 -0
- package/src/common/commonHelp.ts +13 -0
- package/src/common/errorHandling.ts +2 -3
- package/src/common/fail.js +75 -0
- package/src/common/versionChecker.ts +4 -4
- package/src/constants/constants.js +2 -2
- package/src/constants/locales.js +35 -13
- package/src/constants.js +56 -6
- package/src/index.ts +17 -2
- package/src/lambda/help.ts +2 -3
- package/src/scaAnalysis/common/scaParserForGoAndJava.js +41 -0
- package/src/scaAnalysis/common/treeUpload.js +21 -5
- package/src/scaAnalysis/dotnet/analysis.js +21 -3
- package/src/scaAnalysis/go/goAnalysis.js +9 -2
- package/src/scaAnalysis/java/analysis.js +11 -6
- package/src/scaAnalysis/java/index.js +9 -1
- package/src/scaAnalysis/java/javaBuildDepsParser.js +25 -6
- package/src/scaAnalysis/javascript/index.js +3 -0
- package/src/scaAnalysis/php/analysis.js +1 -1
- package/src/scaAnalysis/php/index.js +12 -6
- package/src/scaAnalysis/php/phpNewServicesMapper.js +77 -0
- package/src/scaAnalysis/python/analysis.js +49 -5
- package/src/scaAnalysis/python/index.js +7 -2
- package/src/scaAnalysis/ruby/analysis.js +16 -4
- package/src/scan/autoDetection.js +6 -13
- package/src/scan/formatScanOutput.ts +7 -5
- package/src/scan/help.js +2 -3
- package/src/scan/populateProjectIdAndProjectName.js +5 -1
- package/src/scan/scan.ts +4 -0
- package/src/scan/scanConfig.js +6 -4
- package/src/scan/scanResults.js +52 -3
- package/src/telemetry/telemetry.ts +154 -0
- package/src/utils/commonApi.js +1 -1
- package/src/utils/getConfig.ts +2 -11
- package/src/utils/parsedCLIOptions.js +14 -1
- package/src/utils/requestUtils.js +8 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getHttpClient, handleResponseErrors } from '
|
|
1
|
+
import { getHttpClient, handleResponseErrors } from '../../utils/commonApi'
|
|
2
2
|
import {
|
|
3
3
|
ReportCompositeKey,
|
|
4
4
|
ReportList,
|
|
@@ -22,15 +22,17 @@ import {
|
|
|
22
22
|
ReportOutputModel
|
|
23
23
|
} from './models/reportOutputModel'
|
|
24
24
|
import {
|
|
25
|
+
CE_URL,
|
|
25
26
|
CRITICAL_COLOUR,
|
|
26
27
|
HIGH_COLOUR,
|
|
27
28
|
LOW_COLOUR,
|
|
28
29
|
MEDIUM_COLOUR,
|
|
29
30
|
NOTE_COLOUR
|
|
30
|
-
} from '
|
|
31
|
+
} from '../../constants/constants'
|
|
31
32
|
import Table from 'cli-table3'
|
|
33
|
+
import { ReportGuidanceModel } from './models/reportGuidanceModel'
|
|
32
34
|
|
|
33
|
-
export const
|
|
35
|
+
export const createSummaryMessageTop = (
|
|
34
36
|
numberOfVulnerableLibraries: number,
|
|
35
37
|
numberOfCves: number
|
|
36
38
|
) => {
|
|
@@ -41,6 +43,14 @@ export const createSummaryMessage = (
|
|
|
41
43
|
)
|
|
42
44
|
}
|
|
43
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
|
+
|
|
44
54
|
export const getReport = async (config: any, reportId: string) => {
|
|
45
55
|
const client = getHttpClient(config)
|
|
46
56
|
return client
|
|
@@ -86,7 +96,7 @@ export const printFormattedOutput = (
|
|
|
86
96
|
numberOfCves: number,
|
|
87
97
|
guidance: any
|
|
88
98
|
) => {
|
|
89
|
-
|
|
99
|
+
createSummaryMessageTop(numberOfVulnerableLibraries, numberOfCves)
|
|
90
100
|
console.log()
|
|
91
101
|
const report = new ReportList()
|
|
92
102
|
|
|
@@ -160,7 +170,11 @@ export const printFormattedOutput = (
|
|
|
160
170
|
numOfCVEs
|
|
161
171
|
)
|
|
162
172
|
|
|
163
|
-
const advice = gatherRemediationAdvice(
|
|
173
|
+
const advice = gatherRemediationAdvice(
|
|
174
|
+
guidance,
|
|
175
|
+
libraryName,
|
|
176
|
+
libraryVersion
|
|
177
|
+
)
|
|
164
178
|
|
|
165
179
|
const body = buildBody(reportModel.cveArray, advice)
|
|
166
180
|
|
|
@@ -168,7 +182,6 @@ export const printFormattedOutput = (
|
|
|
168
182
|
|
|
169
183
|
table.push(
|
|
170
184
|
reportOutputModel.body.issueMessage,
|
|
171
|
-
reportOutputModel.body.issueMessageCves,
|
|
172
185
|
reportOutputModel.body.adviceMessage
|
|
173
186
|
)
|
|
174
187
|
|
|
@@ -179,7 +192,7 @@ export const printFormattedOutput = (
|
|
|
179
192
|
console.log(table.toString() + '\n')
|
|
180
193
|
}
|
|
181
194
|
|
|
182
|
-
|
|
195
|
+
createSummaryMessageBottom(numberOfVulnerableLibraries)
|
|
183
196
|
const {
|
|
184
197
|
criticalMessage,
|
|
185
198
|
highMessage,
|
|
@@ -190,6 +203,15 @@ export const printFormattedOutput = (
|
|
|
190
203
|
console.log(
|
|
191
204
|
`${criticalMessage} | ${highMessage} | ${mediumMessage} | ${lowMessage} | ${noteMessage}`
|
|
192
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
|
+
}
|
|
193
215
|
}
|
|
194
216
|
|
|
195
217
|
export function buildHeader(
|
|
@@ -203,18 +225,22 @@ export function buildHeader(
|
|
|
203
225
|
numOfCVEs > 1 ? 'vulnerabilities' : 'vulnerability'
|
|
204
226
|
const formattedHeaderNum = buildFormattedHeaderNum(contrastHeaderNum)
|
|
205
227
|
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
.
|
|
209
|
-
|
|
210
|
-
|
|
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}`
|
|
211
234
|
|
|
212
235
|
const introducesMessage = `introduces ${numOfCVEs} ${vulnerabilityPluralised}`
|
|
213
236
|
|
|
214
237
|
return new ReportOutputHeaderModel(vulnMessage, introducesMessage)
|
|
215
238
|
}
|
|
216
239
|
|
|
217
|
-
export function buildBody(
|
|
240
|
+
export function buildBody(
|
|
241
|
+
cveArray: ReportCVEModel[],
|
|
242
|
+
advice: ReportGuidanceModel
|
|
243
|
+
) {
|
|
218
244
|
const cveMessages: string[] = []
|
|
219
245
|
|
|
220
246
|
findCVESeveritiesAndOrderByHighestPriority(cveArray).forEach(
|
|
@@ -233,46 +259,40 @@ export function buildBody(cveArray: ReportCVEModel[], advice: any) {
|
|
|
233
259
|
|
|
234
260
|
const numAndSeverityType = getNumOfAndSeverityType(cveArray)
|
|
235
261
|
|
|
236
|
-
const issueMessage = [
|
|
237
|
-
|
|
238
|
-
|
|
262
|
+
const issueMessage = [
|
|
263
|
+
chalk.bold('Issue'),
|
|
264
|
+
':',
|
|
265
|
+
`${numAndSeverityType} ${cveMessages.join(', ')}`
|
|
266
|
+
]
|
|
239
267
|
|
|
240
268
|
//todo different advice based on remediationGuidance being available or now
|
|
241
269
|
// console.log(advice)
|
|
242
270
|
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
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.'
|
|
246
275
|
|
|
247
276
|
const adviceMessage = [chalk.bold('Advice'), ':', displayAdvice]
|
|
248
277
|
|
|
249
|
-
return new ReportOutputBodyModel(
|
|
250
|
-
issueMessage,
|
|
251
|
-
issueMessageCves,
|
|
252
|
-
adviceMessage
|
|
253
|
-
)
|
|
278
|
+
return new ReportOutputBodyModel(issueMessage, adviceMessage)
|
|
254
279
|
}
|
|
255
280
|
|
|
256
|
-
export function gatherRemediationAdvice(
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
281
|
+
export function gatherRemediationAdvice(
|
|
282
|
+
guidance: any,
|
|
283
|
+
libraryName: string,
|
|
284
|
+
libraryVersion: string
|
|
285
|
+
) {
|
|
286
|
+
const guidanceModel = new ReportGuidanceModel()
|
|
262
287
|
|
|
263
|
-
const data =
|
|
264
|
-
guidance[
|
|
265
|
-
reportModel.compositeKey.libraryName +
|
|
266
|
-
'@' +
|
|
267
|
-
reportModel.compositeKey.libraryVersion
|
|
268
|
-
]
|
|
288
|
+
const data = guidance[libraryName + '@' + libraryVersion]
|
|
269
289
|
|
|
270
290
|
if (data) {
|
|
271
|
-
|
|
272
|
-
|
|
291
|
+
guidanceModel.minimum = data.minUpgradeVersion
|
|
292
|
+
guidanceModel.maximum = data.maxUpgradeVersion
|
|
273
293
|
}
|
|
274
294
|
|
|
275
|
-
return
|
|
295
|
+
return guidanceModel
|
|
276
296
|
}
|
|
277
297
|
|
|
278
298
|
export function buildFormattedHeaderNum(contrastHeaderNum: number) {
|
|
@@ -285,11 +305,27 @@ export function getNumOfAndSeverityType(cveArray: ReportCVEModel[]) {
|
|
|
285
305
|
new SeverityCountModel()
|
|
286
306
|
)
|
|
287
307
|
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
const
|
|
291
|
-
const
|
|
292
|
-
|
|
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` : ''
|
|
293
329
|
|
|
294
330
|
//removes/trims whitespace to single spaces
|
|
295
331
|
return `${criticalMessage} ${highMessage} ${mediumMessage} ${lowMessage} ${noteMessage}`
|
|
File without changes
|
|
File without changes
|
|
@@ -20,16 +20,10 @@ export class ReportOutputHeaderModel {
|
|
|
20
20
|
|
|
21
21
|
export class ReportOutputBodyModel {
|
|
22
22
|
issueMessage: string[]
|
|
23
|
-
issueMessageCves: string[]
|
|
24
23
|
adviceMessage: string[]
|
|
25
24
|
|
|
26
|
-
constructor(
|
|
27
|
-
issueMessage: string[],
|
|
28
|
-
issueMessageCves: string[],
|
|
29
|
-
adviceMessage: string[]
|
|
30
|
-
) {
|
|
25
|
+
constructor(issueMessage: string[], adviceMessage: string[]) {
|
|
31
26
|
this.issueMessage = issueMessage
|
|
32
|
-
this.issueMessageCves = issueMessageCves
|
|
33
27
|
this.adviceMessage = adviceMessage
|
|
34
28
|
}
|
|
35
29
|
}
|
|
File without changes
|
|
@@ -4,6 +4,7 @@ export class SeverityCountModel {
|
|
|
4
4
|
medium!: number
|
|
5
5
|
low!: number
|
|
6
6
|
note!: number
|
|
7
|
+
total!: number
|
|
7
8
|
|
|
8
9
|
//needed as default to stop NaN when new object constructed
|
|
9
10
|
constructor() {
|
|
@@ -12,6 +13,7 @@ export class SeverityCountModel {
|
|
|
12
13
|
this.medium = 0
|
|
13
14
|
this.low = 0
|
|
14
15
|
this.note = 0
|
|
16
|
+
this.total = 0
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
get getTotal(): number {
|
|
@@ -8,7 +8,9 @@ import {
|
|
|
8
8
|
} from './utils/reportUtils'
|
|
9
9
|
import i18n from 'i18n'
|
|
10
10
|
import chalk from 'chalk'
|
|
11
|
-
import * as constants from '
|
|
11
|
+
import * as constants from '../../constants/constants'
|
|
12
|
+
import { SeverityCountModel } from './models/severityCountModel'
|
|
13
|
+
import * as common from '../../common/fail'
|
|
12
14
|
|
|
13
15
|
export function convertKeysToStandardFormat(config: any, guidance: any) {
|
|
14
16
|
let convertedGuidance = guidance
|
|
@@ -72,6 +74,7 @@ export function formatVulnerabilityOutput(
|
|
|
72
74
|
String(0)
|
|
73
75
|
)
|
|
74
76
|
)
|
|
77
|
+
return [false, 0, [new SeverityCountModel()]]
|
|
75
78
|
} else {
|
|
76
79
|
let numberOfCves = 0
|
|
77
80
|
vulnerableLibraries.forEach(lib => (numberOfCves += lib.cveArray.length))
|
|
@@ -83,12 +86,13 @@ export function formatVulnerabilityOutput(
|
|
|
83
86
|
numberOfCves,
|
|
84
87
|
guidance
|
|
85
88
|
)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
let severityCount = new SeverityCountModel()
|
|
90
|
+
severityCount = severityCountAllLibraries(
|
|
91
|
+
vulnerableLibraries,
|
|
92
|
+
severityCount
|
|
93
|
+
)
|
|
94
|
+
severityCount.total = severityCount.getTotal
|
|
95
|
+
return [hasSomeVulnerabilitiesReported, numberOfCves, severityCount]
|
|
92
96
|
}
|
|
93
97
|
}
|
|
94
98
|
|
|
@@ -97,8 +101,7 @@ export async function vulnerabilityReportV2(config: any, reportId: string) {
|
|
|
97
101
|
const reportResponse = await getReport(config, reportId)
|
|
98
102
|
|
|
99
103
|
if (reportResponse !== undefined) {
|
|
100
|
-
|
|
101
|
-
formatVulnerabilityOutput(
|
|
104
|
+
let output = formatVulnerabilityOutput(
|
|
102
105
|
reportResponse.vulnerabilities,
|
|
103
106
|
config.applicationId,
|
|
104
107
|
config,
|
|
@@ -106,5 +109,9 @@ export async function vulnerabilityReportV2(config: any, reportId: string) {
|
|
|
106
109
|
? reportResponse.remediationGuidance
|
|
107
110
|
: {}
|
|
108
111
|
)
|
|
112
|
+
|
|
113
|
+
if (config.fail) {
|
|
114
|
+
common.processFail(config, output[2])
|
|
115
|
+
}
|
|
109
116
|
}
|
|
110
117
|
}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ReportLibraryModel
|
|
4
4
|
} from '../models/reportLibraryModel'
|
|
5
5
|
import { ReportSeverityModel } from '../models/reportSeverityModel'
|
|
6
|
-
import languageAnalysisEngine from '
|
|
6
|
+
import languageAnalysisEngine from '../../../constants/constants'
|
|
7
7
|
import {
|
|
8
8
|
CRITICAL_COLOUR,
|
|
9
9
|
CRITICAL_PRIORITY,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
MEDIUM_PRIORITY,
|
|
16
16
|
NOTE_COLOUR,
|
|
17
17
|
NOTE_PRIORITY
|
|
18
|
-
} from '
|
|
18
|
+
} from '../../../constants/constants'
|
|
19
19
|
import { orderBy } from 'lodash'
|
|
20
20
|
import { SeverityCountModel } from '../models/severityCountModel'
|
|
21
21
|
import { ReportModelStructure } from '../models/reportListModel'
|
|
@@ -75,9 +75,9 @@ export function convertGenericToTypedLibraryVulns(libraries: any) {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
export function severityCountAllLibraries(
|
|
78
|
-
vulnerableLibraries: ReportLibraryModel[]
|
|
78
|
+
vulnerableLibraries: ReportLibraryModel[],
|
|
79
|
+
severityCount: SeverityCountModel
|
|
79
80
|
) {
|
|
80
|
-
const severityCount = new SeverityCountModel()
|
|
81
81
|
vulnerableLibraries.forEach(lib =>
|
|
82
82
|
severityCountAllCVEs(lib.cveArray, severityCount)
|
|
83
83
|
)
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import paramHandler from '../../utils/paramsUtil/paramHandler'
|
|
2
2
|
import constants from '../../constants'
|
|
3
|
-
import
|
|
3
|
+
import { getCommandLineArgsCustom } from '../../utils/parsedCLIOptions'
|
|
4
|
+
import { ContrastConf } from '../../utils/getConfig'
|
|
4
5
|
|
|
5
|
-
export const getAuditConfig = (
|
|
6
|
-
|
|
6
|
+
export const getAuditConfig = async (
|
|
7
|
+
contrastConf: ContrastConf,
|
|
8
|
+
command: string,
|
|
9
|
+
argv: string[]
|
|
10
|
+
): Promise<{ [key: string]: string }> => {
|
|
11
|
+
const auditParameters = await getCommandLineArgsCustom(
|
|
12
|
+
contrastConf,
|
|
13
|
+
command,
|
|
7
14
|
argv,
|
|
8
15
|
constants.commandLineDefinitions.auditOptionDefinitions
|
|
9
16
|
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import commandLineUsage from 'command-line-usage'
|
|
2
2
|
import i18n from 'i18n'
|
|
3
3
|
import constants from '../../constants'
|
|
4
|
+
import { commonHelpLinks } from '../../common/commonHelp'
|
|
4
5
|
|
|
5
6
|
const auditUsageGuide = commandLineUsage([
|
|
6
7
|
{
|
|
@@ -48,7 +49,8 @@ const auditUsageGuide = commandLineUsage([
|
|
|
48
49
|
'app-groups',
|
|
49
50
|
'metadata'
|
|
50
51
|
]
|
|
51
|
-
}
|
|
52
|
+
},
|
|
53
|
+
commonHelpLinks()
|
|
52
54
|
])
|
|
53
55
|
|
|
54
56
|
export { auditUsageGuide }
|
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
import { getAuditConfig } from './auditConfig'
|
|
2
2
|
import { auditUsageGuide } from './help'
|
|
3
3
|
import { processSca } from '../scan/sca/scaAnalysis'
|
|
4
|
+
import { sendTelemetryConfigAsObject } from '../../telemetry/telemetry'
|
|
5
|
+
import { ContrastConf } from '../../utils/getConfig'
|
|
4
6
|
|
|
5
7
|
export type parameterInput = string[]
|
|
6
8
|
|
|
7
|
-
export const processAudit = async (
|
|
9
|
+
export const processAudit = async (
|
|
10
|
+
contrastConf: ContrastConf,
|
|
11
|
+
argv: parameterInput
|
|
12
|
+
) => {
|
|
8
13
|
if (argv.indexOf('--help') != -1) {
|
|
9
14
|
printHelpMessage()
|
|
10
15
|
process.exit(0)
|
|
11
16
|
}
|
|
12
|
-
|
|
17
|
+
|
|
18
|
+
const config = await getAuditConfig(contrastConf, 'audit', argv)
|
|
13
19
|
await processSca(config)
|
|
20
|
+
await sendTelemetryConfigAsObject(
|
|
21
|
+
config,
|
|
22
|
+
'audit',
|
|
23
|
+
argv,
|
|
24
|
+
'SUCCESS',
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
config.language
|
|
27
|
+
)
|
|
14
28
|
}
|
|
15
29
|
|
|
16
30
|
const printHelpMessage = () => {
|
|
@@ -16,7 +16,9 @@ const constants = require('../../constants')
|
|
|
16
16
|
const commandLineUsage = require('command-line-usage')
|
|
17
17
|
|
|
18
18
|
const processAuth = async (argv, config) => {
|
|
19
|
-
let authParams = parsedCLIOptions.getCommandLineArgsCustom(
|
|
19
|
+
let authParams = await parsedCLIOptions.getCommandLineArgsCustom(
|
|
20
|
+
config,
|
|
21
|
+
'auth',
|
|
20
22
|
argv,
|
|
21
23
|
constants.commandLineDefinitions.authOptionDefinitions
|
|
22
24
|
)
|
|
@@ -3,9 +3,11 @@ const constants = require('../../constants')
|
|
|
3
3
|
const commandLineUsage = require('command-line-usage')
|
|
4
4
|
const i18n = require('i18n')
|
|
5
5
|
|
|
6
|
-
const processConfig = (argv, config) => {
|
|
6
|
+
const processConfig = async (argv, config) => {
|
|
7
7
|
try {
|
|
8
|
-
let configParams = parsedCLIOptions.getCommandLineArgsCustom(
|
|
8
|
+
let configParams = await parsedCLIOptions.getCommandLineArgsCustom(
|
|
9
|
+
config,
|
|
10
|
+
'config',
|
|
9
11
|
argv,
|
|
10
12
|
constants.commandLineDefinitions.configOptionDefinitions
|
|
11
13
|
)
|
|
@@ -4,23 +4,37 @@ const { saveScanFile } = require('../../utils/saveFile')
|
|
|
4
4
|
const { ScanResultsModel } = require('../../scan/models/scanResultsModel')
|
|
5
5
|
const { formatScanOutput } = require('../../scan/formatScanOutput')
|
|
6
6
|
const { processSca } = require('./sca/scaAnalysis')
|
|
7
|
+
const common = require('../../common/fail')
|
|
8
|
+
const { sendTelemetryConfigAsObject } = require('../../telemetry/telemetry')
|
|
7
9
|
|
|
8
|
-
const processScan = async
|
|
9
|
-
let config = scanConfig.getScanConfig(
|
|
10
|
+
const processScan = async (contrastConf, argv) => {
|
|
11
|
+
let config = await scanConfig.getScanConfig(contrastConf, 'scan', argv)
|
|
12
|
+
let output = undefined
|
|
10
13
|
//try SCA analysis first
|
|
11
14
|
if (config.experimental) {
|
|
12
|
-
await processSca(config)
|
|
15
|
+
await processSca(config, argv)
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
let scanResults = new ScanResultsModel(await startScan(config))
|
|
19
|
+
await sendTelemetryConfigAsObject(
|
|
20
|
+
config,
|
|
21
|
+
'scan',
|
|
22
|
+
argv,
|
|
23
|
+
'SUCCESS',
|
|
24
|
+
scanResults.scanDetail.language
|
|
25
|
+
)
|
|
16
26
|
|
|
17
27
|
if (scanResults.scanResultsInstances !== undefined) {
|
|
18
|
-
formatScanOutput(scanResults)
|
|
28
|
+
output = formatScanOutput(scanResults)
|
|
19
29
|
}
|
|
20
30
|
|
|
21
31
|
if (config.save !== undefined) {
|
|
22
32
|
await saveScanFile(config, scanResults)
|
|
23
33
|
}
|
|
34
|
+
|
|
35
|
+
if (config.fail) {
|
|
36
|
+
common.processFail(config, output)
|
|
37
|
+
}
|
|
24
38
|
}
|
|
25
39
|
|
|
26
40
|
module.exports = {
|
|
@@ -21,20 +21,35 @@ const {
|
|
|
21
21
|
const i18n = require('i18n')
|
|
22
22
|
const {
|
|
23
23
|
vulnerabilityReportV2
|
|
24
|
-
} = require('../../../audit/
|
|
24
|
+
} = require('../../../audit/report/reportingFeature')
|
|
25
25
|
const auditSave = require('../../../audit/save')
|
|
26
26
|
const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet')
|
|
27
|
+
const { auditUsageGuide } = require('../../audit/help')
|
|
28
|
+
const rootFile = require('../../../audit/languageAnalysisEngine/getProjectRootFilenames')
|
|
29
|
+
const path = require('path')
|
|
27
30
|
const processSca = async config => {
|
|
28
31
|
const startTime = performance.now()
|
|
29
32
|
let filesFound
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
if (config.help) {
|
|
35
|
+
console.log(auditUsageGuide)
|
|
36
|
+
process.exit(0)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const projectStats = await rootFile.getProjectStats(config.file)
|
|
40
|
+
let pathWithFile = projectStats.isFile()
|
|
41
|
+
|
|
42
|
+
config.fileName = config.file
|
|
43
|
+
config.file = pathWithFile
|
|
44
|
+
? rootFile.getDirectoryFromPathGiven(config.file).concat('/')
|
|
45
|
+
: config.file
|
|
46
|
+
|
|
47
|
+
filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(config.file)
|
|
48
|
+
|
|
49
|
+
if (filesFound.length > 1 && pathWithFile) {
|
|
50
|
+
filesFound = filesFound.filter(i =>
|
|
51
|
+
Object.values(i)[0].includes(path.basename(config.fileName))
|
|
34
52
|
)
|
|
35
|
-
} else {
|
|
36
|
-
filesFound = await autoDetection.autoDetectAuditFilesAndLanguages(undefined)
|
|
37
|
-
config.file = process.cwd().concat('/')
|
|
38
53
|
}
|
|
39
54
|
|
|
40
55
|
// files found looks like [ { javascript: [ Array ] } ]
|
|
@@ -62,7 +77,7 @@ const processSca = async config => {
|
|
|
62
77
|
messageToSend = rubyAnalysis(config, filesFound[0])
|
|
63
78
|
config.language = RUBY
|
|
64
79
|
break
|
|
65
|
-
case
|
|
80
|
+
case PHP:
|
|
66
81
|
messageToSend = phpAnalysis.phpAnalysis(config, filesFound[0])
|
|
67
82
|
config.language = PHP
|
|
68
83
|
break
|
|
@@ -118,7 +133,9 @@ const processSca = async config => {
|
|
|
118
133
|
throw new Error()
|
|
119
134
|
} else {
|
|
120
135
|
throw new Error(
|
|
121
|
-
|
|
136
|
+
`multiple language files detected \n` +
|
|
137
|
+
JSON.stringify(filesFound) +
|
|
138
|
+
`\nplease use --file to audit one language only. Example: contrast audit --file package-lock.json`
|
|
122
139
|
)
|
|
123
140
|
}
|
|
124
141
|
}
|
package/src/common/HTTPClient.js
CHANGED
|
@@ -212,6 +212,7 @@ HTTPClient.prototype.sendSnapshot = function sendSnapshot(requestBody, config) {
|
|
|
212
212
|
let url = createSnapshotURL(config)
|
|
213
213
|
options.url = url
|
|
214
214
|
options.body = requestBody
|
|
215
|
+
|
|
215
216
|
return requestUtils.sendRequest({ method: 'post', options })
|
|
216
217
|
}
|
|
217
218
|
|
|
@@ -346,6 +347,16 @@ HTTPClient.prototype.getLatestVersion = function getLatestVersion() {
|
|
|
346
347
|
return requestUtils.sendRequest({ method: 'get', options })
|
|
347
348
|
}
|
|
348
349
|
|
|
350
|
+
HTTPClient.prototype.postTelemetry = function postTelemetry(
|
|
351
|
+
config,
|
|
352
|
+
requestBody
|
|
353
|
+
) {
|
|
354
|
+
const options = _.cloneDeep(this.requestOptions)
|
|
355
|
+
options.url = createTelemetryEventUrl(config)
|
|
356
|
+
options.body = requestBody
|
|
357
|
+
return requestUtils.sendRequest({ method: 'post', options })
|
|
358
|
+
}
|
|
359
|
+
|
|
349
360
|
// analytics
|
|
350
361
|
|
|
351
362
|
HTTPClient.prototype.postAnalyticsFunction = function (config, provider, body) {
|
|
@@ -439,6 +450,10 @@ function createSbomUrl(config, type) {
|
|
|
439
450
|
return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/${type}`
|
|
440
451
|
}
|
|
441
452
|
|
|
453
|
+
function createTelemetryEventUrl(config) {
|
|
454
|
+
return `${config.host}/Contrast/api/sast/organizations/${config.organizationId}/cli`
|
|
455
|
+
}
|
|
456
|
+
|
|
442
457
|
module.exports = HTTPClient
|
|
443
458
|
module.exports.pollForAuthUrl = pollForAuthUrl
|
|
444
459
|
module.exports.getServerlessHost = getServerlessHost
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import i18n from 'i18n'
|
|
2
|
+
|
|
3
|
+
export function commonHelpLinks() {
|
|
4
|
+
return {
|
|
5
|
+
header: i18n.__('commonHelpHeader'),
|
|
6
|
+
content: [
|
|
7
|
+
i18n.__('commonHelpCheckOutHeader') + i18n.__('commonHelpCheckOutText'),
|
|
8
|
+
i18n.__('commonHelpLearnMoreHeader') + i18n.__('commonHelpLearnMoreText'),
|
|
9
|
+
i18n.__('commonHelpJoinDiscussionHeader') +
|
|
10
|
+
i18n.__('commonHelpJoinDiscussionText')
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -39,9 +39,8 @@ const reportFailureError = () => {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
const genericError = (missingCliOption: string) => {
|
|
42
|
-
|
|
43
|
-
console.
|
|
44
|
-
console.error(i18n.__('yamlMissingParametersMessage'))
|
|
42
|
+
console.log(missingCliOption)
|
|
43
|
+
console.error(i18n.__('genericErrorMessage'))
|
|
45
44
|
process.exit(1)
|
|
46
45
|
}
|
|
47
46
|
|