@contrast/contrast 1.0.14 → 1.0.16
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/dist/audit/languageAnalysisEngine/sendSnapshot.js +2 -2
- package/dist/audit/report/commonReportingFunctions.js +1 -19
- package/dist/audit/save.js +7 -2
- package/dist/{constants.js → cliConstants.js} +70 -31
- package/dist/commands/audit/auditConfig.js +2 -2
- package/dist/commands/audit/help.js +5 -3
- package/dist/commands/auth/auth.js +1 -1
- package/dist/commands/config/config.js +1 -1
- package/dist/commands/scan/processScan.js +0 -6
- package/dist/commands/scan/sca/scaAnalysis.js +64 -33
- package/dist/common/HTTPClient.js +25 -4
- package/dist/constants/constants.js +10 -2
- package/dist/constants/locales.js +7 -30
- package/dist/index.js +5 -5
- package/dist/sbom/generateSbom.js +18 -1
- package/dist/scaAnalysis/common/auditReport.js +3 -2
- package/dist/scaAnalysis/common/scaParserForGoAndJava.js +1 -1
- package/dist/scaAnalysis/common/scaServicesUpload.js +14 -7
- package/dist/scaAnalysis/javascript/scaServiceParser.js +2 -2
- package/dist/scaAnalysis/php/phpNewServicesMapper.js +3 -3
- package/dist/scaAnalysis/python/analysis.js +1 -1
- package/dist/scaAnalysis/repoMode/gradleParser.js +75 -0
- package/dist/scaAnalysis/repoMode/index.js +21 -0
- package/dist/scaAnalysis/repoMode/mavenParser.js +76 -0
- package/dist/scaAnalysis/ruby/analysis.js +4 -4
- package/dist/scan/help.js +1 -1
- package/dist/scan/scanConfig.js +1 -1
- package/dist/utils/commonApi.js +1 -0
- package/dist/utils/settingsHelper.js +24 -0
- package/package.json +2 -1
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +2 -6
- package/src/audit/report/commonReportingFunctions.js +1 -23
- package/src/audit/save.js +14 -6
- package/src/{constants.js → cliConstants.js} +79 -35
- package/src/commands/audit/auditConfig.ts +1 -1
- package/src/commands/audit/help.ts +4 -2
- package/src/commands/auth/auth.js +1 -1
- package/src/commands/config/config.js +1 -1
- package/src/commands/scan/processScan.js +0 -8
- package/src/commands/scan/sca/scaAnalysis.js +85 -54
- package/src/common/HTTPClient.js +29 -4
- package/src/constants/constants.js +12 -2
- package/src/constants/locales.js +9 -44
- package/src/index.ts +1 -1
- package/src/sbom/generateSbom.ts +20 -0
- package/src/scaAnalysis/common/auditReport.js +3 -4
- package/src/scaAnalysis/common/scaParserForGoAndJava.js +1 -1
- package/src/scaAnalysis/common/scaServicesUpload.js +15 -7
- package/src/scaAnalysis/javascript/scaServiceParser.js +8 -2
- package/src/scaAnalysis/php/phpNewServicesMapper.js +3 -3
- package/src/scaAnalysis/python/analysis.js +1 -1
- package/src/scaAnalysis/repoMode/gradleParser.js +88 -0
- package/src/scaAnalysis/repoMode/index.js +21 -0
- package/src/scaAnalysis/repoMode/mavenParser.js +89 -0
- package/src/scaAnalysis/ruby/analysis.js +4 -4
- package/src/scan/help.js +1 -1
- package/src/scan/scanConfig.js +1 -1
- package/src/utils/commonApi.js +1 -0
- package/src/utils/settingsHelper.js +26 -0
|
@@ -11,8 +11,53 @@ i18n.configure({
|
|
|
11
11
|
defaultLocale: 'en'
|
|
12
12
|
})
|
|
13
13
|
|
|
14
|
+
const sharedOptionDefinitions = [
|
|
15
|
+
{
|
|
16
|
+
name: 'proxy',
|
|
17
|
+
description:
|
|
18
|
+
'{bold ' +
|
|
19
|
+
i18n.__('constantsOptional') +
|
|
20
|
+
'}: ' +
|
|
21
|
+
i18n.__('constantsProxyServer')
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'key',
|
|
25
|
+
description:
|
|
26
|
+
'{bold ' +
|
|
27
|
+
i18n.__('constantsOptional') +
|
|
28
|
+
'}: ' +
|
|
29
|
+
i18n.__('constantsProxyKey')
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'cacert',
|
|
33
|
+
description:
|
|
34
|
+
'{bold ' +
|
|
35
|
+
i18n.__('constantsOptional') +
|
|
36
|
+
'}: ' +
|
|
37
|
+
i18n.__('constantsProxyCaCert')
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'cert',
|
|
41
|
+
description:
|
|
42
|
+
'{bold ' +
|
|
43
|
+
i18n.__('constantsOptional') +
|
|
44
|
+
'}: ' +
|
|
45
|
+
i18n.__('constantsProxyCert')
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'ignore-cert-errors',
|
|
49
|
+
type: Boolean,
|
|
50
|
+
description:
|
|
51
|
+
'{bold ' +
|
|
52
|
+
i18n.__('constantsOptional') +
|
|
53
|
+
'}:' +
|
|
54
|
+
i18n.__('constantsIgnoreCertErrors')
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
|
|
14
58
|
// CLI options that we will allow and handle
|
|
15
59
|
const scanOptionDefinitions = [
|
|
60
|
+
...sharedOptionDefinitions,
|
|
16
61
|
{
|
|
17
62
|
name: 'name',
|
|
18
63
|
alias: 'n',
|
|
@@ -100,14 +145,6 @@ const scanOptionDefinitions = [
|
|
|
100
145
|
'}: ' +
|
|
101
146
|
i18n.__('constantsHostId')
|
|
102
147
|
},
|
|
103
|
-
{
|
|
104
|
-
name: 'proxy',
|
|
105
|
-
description:
|
|
106
|
-
'{bold ' +
|
|
107
|
-
i18n.__('constantsOptional') +
|
|
108
|
-
'}: ' +
|
|
109
|
-
i18n.__('constantsProxyServer')
|
|
110
|
-
},
|
|
111
148
|
{
|
|
112
149
|
name: 'fail',
|
|
113
150
|
type: Boolean,
|
|
@@ -133,16 +170,7 @@ const scanOptionDefinitions = [
|
|
|
133
170
|
'{bold ' +
|
|
134
171
|
i18n.__('constantsOptional') +
|
|
135
172
|
'}: ' +
|
|
136
|
-
i18n.__('
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
name: 'ignore-cert-errors',
|
|
140
|
-
type: Boolean,
|
|
141
|
-
description:
|
|
142
|
-
'{bold ' +
|
|
143
|
-
i18n.__('constantsOptional') +
|
|
144
|
-
'}:' +
|
|
145
|
-
i18n.__('constantsIgnoreCertErrors')
|
|
173
|
+
i18n.__('constantsDoNotWaitForScan')
|
|
146
174
|
},
|
|
147
175
|
{
|
|
148
176
|
name: 'verbose',
|
|
@@ -214,6 +242,7 @@ const configOptionDefinitions = [
|
|
|
214
242
|
]
|
|
215
243
|
|
|
216
244
|
const auditOptionDefinitions = [
|
|
245
|
+
...sharedOptionDefinitions,
|
|
217
246
|
{
|
|
218
247
|
name: 'application-id',
|
|
219
248
|
description:
|
|
@@ -338,23 +367,6 @@ const auditOptionDefinitions = [
|
|
|
338
367
|
'}: ' +
|
|
339
368
|
i18n.__('constantsHostId')
|
|
340
369
|
},
|
|
341
|
-
{
|
|
342
|
-
name: 'proxy',
|
|
343
|
-
description:
|
|
344
|
-
'{bold ' +
|
|
345
|
-
i18n.__('constantsOptional') +
|
|
346
|
-
'}: ' +
|
|
347
|
-
i18n.__('constantsProxyServer')
|
|
348
|
-
},
|
|
349
|
-
{
|
|
350
|
-
name: 'ignore-cert-errors',
|
|
351
|
-
type: Boolean,
|
|
352
|
-
description:
|
|
353
|
-
'{bold ' +
|
|
354
|
-
i18n.__('constantsOptional') +
|
|
355
|
-
'}:' +
|
|
356
|
-
i18n.__('constantsIgnoreCertErrors')
|
|
357
|
-
},
|
|
358
370
|
{
|
|
359
371
|
name: 'save',
|
|
360
372
|
alias: 's',
|
|
@@ -384,6 +396,38 @@ const auditOptionDefinitions = [
|
|
|
384
396
|
name: 'help',
|
|
385
397
|
alias: 'h',
|
|
386
398
|
type: Boolean
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
name: 'debug',
|
|
402
|
+
alias: 'd',
|
|
403
|
+
type: Boolean
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
name: 'verbose',
|
|
407
|
+
alias: 'v',
|
|
408
|
+
type: Boolean,
|
|
409
|
+
description:
|
|
410
|
+
'{bold ' +
|
|
411
|
+
i18n.__('constantsOptional') +
|
|
412
|
+
'}:' +
|
|
413
|
+
i18n.__('scanOptionsVerboseSummary')
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
name: 'track',
|
|
417
|
+
type: Boolean,
|
|
418
|
+
description:
|
|
419
|
+
'{bold ' +
|
|
420
|
+
i18n.__('constantsOptional') +
|
|
421
|
+
'}:' +
|
|
422
|
+
i18n.__('auditOptionsTrackSummary')
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
name: 'branch',
|
|
426
|
+
description:
|
|
427
|
+
'{bold ' +
|
|
428
|
+
i18n.__('constantsOptional') +
|
|
429
|
+
'}:' +
|
|
430
|
+
i18n.__('auditOptionsBranchSummary')
|
|
387
431
|
}
|
|
388
432
|
]
|
|
389
433
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import paramHandler from '../../utils/paramsUtil/paramHandler'
|
|
2
|
-
import constants from '../../
|
|
2
|
+
import constants from '../../cliConstants'
|
|
3
3
|
import { getCommandLineArgsCustom } from '../../utils/parsedCLIOptions'
|
|
4
4
|
import { ContrastConf } from '../../utils/getConfig'
|
|
5
5
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import commandLineUsage from 'command-line-usage'
|
|
2
2
|
import i18n from 'i18n'
|
|
3
|
-
import constants from '../../
|
|
3
|
+
import constants from '../../cliConstants'
|
|
4
4
|
import { commonHelpLinks } from '../../common/commonHelp'
|
|
5
5
|
|
|
6
6
|
const auditUsageGuide = commandLineUsage([
|
|
@@ -47,7 +47,9 @@ const auditUsageGuide = commandLineUsage([
|
|
|
47
47
|
'language',
|
|
48
48
|
'experimental',
|
|
49
49
|
'app-groups',
|
|
50
|
-
'metadata'
|
|
50
|
+
'metadata',
|
|
51
|
+
'track',
|
|
52
|
+
'branch'
|
|
51
53
|
]
|
|
52
54
|
},
|
|
53
55
|
commonHelpLinks()
|
|
@@ -12,7 +12,7 @@ const {
|
|
|
12
12
|
} = require('../../utils/oraWrapper')
|
|
13
13
|
const { TIMEOUT, AUTH_UI_URL } = require('../../constants/constants')
|
|
14
14
|
const parsedCLIOptions = require('../../utils/parsedCLIOptions')
|
|
15
|
-
const constants = require('../../
|
|
15
|
+
const constants = require('../../cliConstants')
|
|
16
16
|
const commandLineUsage = require('command-line-usage')
|
|
17
17
|
|
|
18
18
|
const processAuth = async (argv, config) => {
|
|
@@ -3,21 +3,13 @@ const { startScan } = require('../../scan/scanController')
|
|
|
3
3
|
const { saveScanFile } = require('../../utils/saveFile')
|
|
4
4
|
const { ScanResultsModel } = require('../../scan/models/scanResultsModel')
|
|
5
5
|
const { formatScanOutput } = require('../../scan/formatScanOutput')
|
|
6
|
-
const { processSca } = require('./sca/scaAnalysis')
|
|
7
6
|
const common = require('../../common/fail')
|
|
8
7
|
const { sendTelemetryConfigAsObject } = require('../../telemetry/telemetry')
|
|
9
8
|
const chalk = require('chalk')
|
|
10
|
-
const generalAPI = require('../../utils/generalAPI')
|
|
11
9
|
|
|
12
10
|
const processScan = async (contrastConf, argv) => {
|
|
13
11
|
let config = await scanConfig.getScanConfig(contrastConf, 'scan', argv)
|
|
14
12
|
let output = undefined
|
|
15
|
-
config.mode = await generalAPI.getMode(config)
|
|
16
|
-
|
|
17
|
-
//try SCA analysis first
|
|
18
|
-
if (config.experimental) {
|
|
19
|
-
await processSca(config, argv)
|
|
20
|
-
}
|
|
21
13
|
|
|
22
14
|
let scanResults = new ScanResultsModel(await startScan(config))
|
|
23
15
|
await sendTelemetryConfigAsObject(
|
|
@@ -1,36 +1,41 @@
|
|
|
1
|
-
const autoDetection = require('../../../scan/autoDetection')
|
|
2
|
-
const javaAnalysis = require('../../../scaAnalysis/java')
|
|
3
|
-
const treeUpload = require('../../../scaAnalysis/common/treeUpload')
|
|
4
|
-
const auditController = require('../../audit/auditController')
|
|
5
1
|
const {
|
|
6
2
|
supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET }
|
|
7
3
|
} = require('../../../constants/constants')
|
|
8
|
-
const goAnalysis = require('../../../scaAnalysis/go/goAnalysis')
|
|
9
|
-
const phpAnalysis = require('../../../scaAnalysis/php/index')
|
|
10
|
-
const { rubyAnalysis } = require('../../../scaAnalysis/ruby')
|
|
11
|
-
const { pythonAnalysis } = require('../../../scaAnalysis/python')
|
|
12
|
-
const javascriptAnalysis = require('../../../scaAnalysis/javascript')
|
|
13
4
|
const {
|
|
14
|
-
|
|
5
|
+
pollForSnapshotCompletion
|
|
15
6
|
} = require('../../../audit/languageAnalysisEngine/sendSnapshot')
|
|
16
7
|
const {
|
|
17
8
|
returnOra,
|
|
18
9
|
startSpinner,
|
|
19
10
|
succeedSpinner
|
|
20
11
|
} = require('../../../utils/oraWrapper')
|
|
21
|
-
const i18n = require('i18n')
|
|
22
12
|
const {
|
|
23
13
|
vulnerabilityReportV2
|
|
24
14
|
} = require('../../../audit/report/reportingFeature')
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
15
|
+
const autoDetection = require('../../../scan/autoDetection')
|
|
16
|
+
const treeUpload = require('../../../scaAnalysis/common/treeUpload')
|
|
17
|
+
const auditController = require('../../audit/auditController')
|
|
28
18
|
const rootFile = require('../../../audit/languageAnalysisEngine/getProjectRootFilenames')
|
|
29
19
|
const path = require('path')
|
|
30
|
-
const
|
|
20
|
+
const i18n = require('i18n')
|
|
21
|
+
const auditSave = require('../../../audit/save')
|
|
22
|
+
const { auditUsageGuide } = require('../../audit/help')
|
|
23
|
+
const { buildRepo } = require('../../../scaAnalysis/repoMode/index')
|
|
24
|
+
const { dotNetAnalysis } = require('../../../scaAnalysis/dotnet')
|
|
25
|
+
const { goAnalysis } = require('../../../scaAnalysis/go/goAnalysis')
|
|
26
|
+
const { phpAnalysis } = require('../../../scaAnalysis/php/index')
|
|
27
|
+
const { rubyAnalysis } = require('../../../scaAnalysis/ruby')
|
|
28
|
+
const { pythonAnalysis } = require('../../../scaAnalysis/python')
|
|
29
|
+
const javaAnalysis = require('../../../scaAnalysis/java')
|
|
30
|
+
const jsAnalysis = require('../../../scaAnalysis/javascript')
|
|
31
|
+
const auditReport = require('../../../scaAnalysis/common/auditReport')
|
|
32
|
+
const scaUpload = require('../../../scaAnalysis/common/scaServicesUpload')
|
|
33
|
+
const settingsHelper = require('../../../utils/settingsHelper')
|
|
34
|
+
const chalk = require('chalk')
|
|
31
35
|
|
|
32
36
|
const processSca = async config => {
|
|
33
|
-
|
|
37
|
+
//checks to see whether to use old TS / new SCA path
|
|
38
|
+
config = await settingsHelper.getSettings(config)
|
|
34
39
|
|
|
35
40
|
const startTime = performance.now()
|
|
36
41
|
let filesFound
|
|
@@ -59,6 +64,15 @@ const processSca = async config => {
|
|
|
59
64
|
// files found looks like [ { javascript: [ Array ] } ]
|
|
60
65
|
//check we have the language and call the right analyser
|
|
61
66
|
//refactor new analyser and see if we can clean it up
|
|
67
|
+
if (config.mode === 'repo') {
|
|
68
|
+
try {
|
|
69
|
+
return buildRepo(config, filesFound[0])
|
|
70
|
+
} catch (e) {
|
|
71
|
+
console.log('Unable to build in repository mode. Check your project file')
|
|
72
|
+
process.exit(0)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
62
76
|
let messageToSend = undefined
|
|
63
77
|
if (filesFound.length === 1) {
|
|
64
78
|
switch (Object.keys(filesFound[0])[0]) {
|
|
@@ -67,10 +81,7 @@ const processSca = async config => {
|
|
|
67
81
|
config.language = JAVA
|
|
68
82
|
break
|
|
69
83
|
case JAVASCRIPT:
|
|
70
|
-
messageToSend = await
|
|
71
|
-
config,
|
|
72
|
-
filesFound[0]
|
|
73
|
-
)
|
|
84
|
+
messageToSend = await jsAnalysis.jsAnalysis(config, filesFound[0])
|
|
74
85
|
config.language = NODE
|
|
75
86
|
break
|
|
76
87
|
case PYTHON:
|
|
@@ -82,11 +93,11 @@ const processSca = async config => {
|
|
|
82
93
|
config.language = RUBY
|
|
83
94
|
break
|
|
84
95
|
case PHP:
|
|
85
|
-
messageToSend = phpAnalysis
|
|
96
|
+
messageToSend = phpAnalysis(config, filesFound[0])
|
|
86
97
|
config.language = PHP
|
|
87
98
|
break
|
|
88
99
|
case GO:
|
|
89
|
-
messageToSend = goAnalysis
|
|
100
|
+
messageToSend = goAnalysis(config, filesFound[0])
|
|
90
101
|
config.language = GO
|
|
91
102
|
break
|
|
92
103
|
case DOTNET:
|
|
@@ -103,48 +114,68 @@ const processSca = async config => {
|
|
|
103
114
|
config.applicationId = await auditController.dealWithNoAppId(config)
|
|
104
115
|
}
|
|
105
116
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const snapshotResponse = await treeUpload.commonSendSnapShot(
|
|
115
|
-
messageToSend,
|
|
116
|
-
config
|
|
117
|
-
)
|
|
117
|
+
if (config.experimental) {
|
|
118
|
+
console.log('') //empty log for space before spinner
|
|
119
|
+
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
|
|
120
|
+
startSpinner(reportSpinner)
|
|
121
|
+
const [reports, reportId] = await scaUpload.scaTreeUpload(
|
|
122
|
+
messageToSend,
|
|
123
|
+
config
|
|
124
|
+
)
|
|
118
125
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
config,
|
|
122
|
-
snapshotResponse.id,
|
|
123
|
-
reportSpinner
|
|
124
|
-
)
|
|
125
|
-
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
|
|
126
|
+
auditReport.processAuditReport(config, reports[0])
|
|
127
|
+
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
|
|
126
128
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
const endTime = performance.now() - startTime
|
|
132
|
-
const scanDurationMs = endTime - startTime
|
|
129
|
+
if (config.save !== undefined) {
|
|
130
|
+
await auditSave.auditSave(config, reportId)
|
|
131
|
+
}
|
|
133
132
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
133
|
+
const endTime = performance.now() - startTime
|
|
134
|
+
const scanDurationMs = endTime - startTime
|
|
135
|
+
console.log(
|
|
136
|
+
`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
|
|
137
|
+
)
|
|
138
|
+
} else {
|
|
139
|
+
console.log('') //empty log for space before spinner
|
|
140
|
+
//send message to TS
|
|
141
|
+
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
|
|
142
|
+
startSpinner(reportSpinner)
|
|
143
|
+
const snapshotResponse = await treeUpload.commonSendSnapShot(
|
|
144
|
+
messageToSend,
|
|
145
|
+
config
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
// poll for completion
|
|
149
|
+
await pollForSnapshotCompletion(
|
|
150
|
+
config,
|
|
151
|
+
snapshotResponse.id,
|
|
152
|
+
reportSpinner
|
|
153
|
+
)
|
|
154
|
+
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
|
|
155
|
+
|
|
156
|
+
await vulnerabilityReportV2(config, snapshotResponse.id)
|
|
157
|
+
if (config.save !== undefined) {
|
|
158
|
+
await auditSave.auditSave(config)
|
|
159
|
+
}
|
|
160
|
+
const endTime = performance.now() - startTime
|
|
161
|
+
const scanDurationMs = endTime - startTime
|
|
162
|
+
|
|
163
|
+
console.log(
|
|
164
|
+
`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
|
|
165
|
+
)
|
|
166
|
+
}
|
|
138
167
|
} else {
|
|
139
168
|
if (filesFound.length === 0) {
|
|
140
169
|
console.log(i18n.__('languageAnalysisNoLanguage'))
|
|
141
170
|
console.log(i18n.__('languageAnalysisNoLanguageHelpLine'))
|
|
142
171
|
throw new Error()
|
|
143
172
|
} else {
|
|
173
|
+
console.log(chalk.bold(`\nMultiple language files detected \n`))
|
|
174
|
+
filesFound.forEach(file => {
|
|
175
|
+
console.log(`${Object.keys(file)[0]} : `, Object.values(file)[0])
|
|
176
|
+
})
|
|
144
177
|
throw new Error(
|
|
145
|
-
`
|
|
146
|
-
JSON.stringify(filesFound) +
|
|
147
|
-
`\nplease use --file to audit one language only. Example: contrast audit --file package-lock.json`
|
|
178
|
+
`Please use --file to audit one language only. \nExample: contrast audit --file package-lock.json`
|
|
148
179
|
)
|
|
149
180
|
}
|
|
150
181
|
}
|
package/src/common/HTTPClient.js
CHANGED
|
@@ -41,7 +41,7 @@ HTTPClient.prototype.maybeAddCertsToRequest = function (config) {
|
|
|
41
41
|
const caFileContent = fs.readFileSync(caCertFilePath)
|
|
42
42
|
if (caFileContent instanceof Error) {
|
|
43
43
|
throw new Error(
|
|
44
|
-
`Unable to read CA from
|
|
44
|
+
`Unable to read CA from ${caCertFilePath}, msg: ${caFileContent.message}`
|
|
45
45
|
)
|
|
46
46
|
}
|
|
47
47
|
this.requestOptions.ca = caFileContent
|
|
@@ -246,6 +246,13 @@ HTTPClient.prototype.scaServiceReportStatus = function scaServiceReport(
|
|
|
246
246
|
return requestUtils.sendRequest({ method: 'get', options })
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
+
HTTPClient.prototype.scaServiceIngests = function scaServiceIngests(config) {
|
|
250
|
+
const options = _.cloneDeep(this.requestOptions)
|
|
251
|
+
let url = createScaServiceIngestsURL(config)
|
|
252
|
+
options.url = url
|
|
253
|
+
return requestUtils.sendRequest({ method: 'get', options })
|
|
254
|
+
}
|
|
255
|
+
|
|
249
256
|
HTTPClient.prototype.getReportById = function getReportById(config, reportId) {
|
|
250
257
|
const options = _.cloneDeep(this.requestOptions)
|
|
251
258
|
if (config.ignoreDev) {
|
|
@@ -370,6 +377,12 @@ HTTPClient.prototype.getSbom = function getSbom(config, type) {
|
|
|
370
377
|
return requestUtils.sendRequest({ method: 'get', options })
|
|
371
378
|
}
|
|
372
379
|
|
|
380
|
+
HTTPClient.prototype.getSCASbom = function getSbom(config, type, reportId) {
|
|
381
|
+
const options = _.cloneDeep(this.requestOptions)
|
|
382
|
+
options.url = createSCASbomUrl(config, type, reportId)
|
|
383
|
+
return requestUtils.sendRequest({ method: 'get', options })
|
|
384
|
+
}
|
|
385
|
+
|
|
373
386
|
HTTPClient.prototype.getLatestVersion = function getLatestVersion() {
|
|
374
387
|
const options = _.cloneDeep(this.requestOptions)
|
|
375
388
|
options.url =
|
|
@@ -447,15 +460,23 @@ function createSnapshotURL(config) {
|
|
|
447
460
|
}
|
|
448
461
|
|
|
449
462
|
function createScaServiceReportURL(config, reportId) {
|
|
450
|
-
|
|
463
|
+
let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/applications/${config.applicationId}/reports/${reportId}`
|
|
464
|
+
baseUrl = config.ignoreDev ? baseUrl.concat('?nodesToInclude=PROD') : baseUrl
|
|
465
|
+
return baseUrl
|
|
451
466
|
}
|
|
452
467
|
|
|
453
468
|
function createScaServiceReportStatusURL(config, reportId) {
|
|
454
|
-
return
|
|
469
|
+
return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/${reportId}/status`
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
function createScaServiceIngestsURL(config) {
|
|
473
|
+
return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests`
|
|
455
474
|
}
|
|
456
475
|
|
|
457
476
|
function createScaServiceIngestURL(config) {
|
|
458
|
-
|
|
477
|
+
let baseUrl = `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/ingests/tree`
|
|
478
|
+
baseUrl = config.track ? baseUrl.concat('?persist=true') : baseUrl
|
|
479
|
+
return baseUrl
|
|
459
480
|
}
|
|
460
481
|
|
|
461
482
|
const createAppCreateURL = config => {
|
|
@@ -492,6 +513,10 @@ function createSbomUrl(config, type) {
|
|
|
492
513
|
return `${config.host}/Contrast/api/ng/${config.organizationId}/applications/${config.applicationId}/libraries/sbom/${type}`
|
|
493
514
|
}
|
|
494
515
|
|
|
516
|
+
function createSCASbomUrl(config, type, reportId) {
|
|
517
|
+
return `${config.host}/Contrast/api/sca/organizations/${config.organizationId}/libraries/applications/${config.applicationId}/sbom/${reportId}?toolType=${type}`
|
|
518
|
+
}
|
|
519
|
+
|
|
495
520
|
function createTelemetryEventUrl(config) {
|
|
496
521
|
return `${config.host}/Contrast/api/sast/organizations/${config.organizationId}/cli`
|
|
497
522
|
}
|
|
@@ -14,7 +14,7 @@ const HIGH = 'HIGH'
|
|
|
14
14
|
const CRITICAL = 'CRITICAL'
|
|
15
15
|
// App
|
|
16
16
|
const APP_NAME = 'contrast'
|
|
17
|
-
const APP_VERSION = '1.0.
|
|
17
|
+
const APP_VERSION = '1.0.16'
|
|
18
18
|
const TIMEOUT = 120000
|
|
19
19
|
const HIGH_COLOUR = '#ff9900'
|
|
20
20
|
const CRITICAL_COLOUR = '#e35858'
|
|
@@ -34,6 +34,12 @@ const SBOM_CYCLONE_DX_FILE = 'cyclonedx'
|
|
|
34
34
|
const SBOM_SPDX_FILE = 'spdx'
|
|
35
35
|
const CE_URL = 'https://ce.contrastsecurity.com'
|
|
36
36
|
|
|
37
|
+
//configuration
|
|
38
|
+
const SAAS = 'SAAS'
|
|
39
|
+
const EOP = 'EOP'
|
|
40
|
+
const MODE_BUILD = 'BUILD'
|
|
41
|
+
const MODE_REPO = 'REPO'
|
|
42
|
+
|
|
37
43
|
module.exports = {
|
|
38
44
|
supportedLanguages: { NODE, DOTNET, JAVA, RUBY, PYTHON, GO, PHP, JAVASCRIPT },
|
|
39
45
|
supportedLanguagesScan: { JAVASCRIPT, DOTNET, JAVA },
|
|
@@ -59,5 +65,9 @@ module.exports = {
|
|
|
59
65
|
LOW_PRIORITY,
|
|
60
66
|
NOTE_PRIORITY,
|
|
61
67
|
SBOM_CYCLONE_DX_FILE,
|
|
62
|
-
SBOM_SPDX_FILE
|
|
68
|
+
SBOM_SPDX_FILE,
|
|
69
|
+
SAAS,
|
|
70
|
+
EOP,
|
|
71
|
+
MODE_BUILD,
|
|
72
|
+
MODE_REPO
|
|
63
73
|
}
|
package/src/constants/locales.js
CHANGED
|
@@ -137,7 +137,7 @@ const en_locales = () => {
|
|
|
137
137
|
constantsGradleMultiProject:
|
|
138
138
|
'Specify the sub project within your gradle application.',
|
|
139
139
|
constantsScan: 'Upload java binaries to the static scan service',
|
|
140
|
-
|
|
140
|
+
constantsDoNotWaitForScan: 'Do not wait for the result of the scan',
|
|
141
141
|
constantsProjectName:
|
|
142
142
|
'Contrast project name. If not specified, Contrast uses contrast.settings to identify the project or creates a project.',
|
|
143
143
|
constantsProjectId:
|
|
@@ -201,56 +201,19 @@ const en_locales = () => {
|
|
|
201
201
|
'After successful auth try the following command: contrast scan -f "<file>"',
|
|
202
202
|
constantsHowToRunDev3:
|
|
203
203
|
'Allowable languages are java (.jar and .war) and javascript (.js or .zip), if the language is not autodetected please use --language to specify',
|
|
204
|
-
constantsHowToRunContent1:
|
|
205
|
-
'You can run the tool on the command line and manually add the parameters, or you can put the parameters in a YAML file.',
|
|
206
|
-
constantsHowToRunContent2:
|
|
207
|
-
'If you are assessing an application that has not been instrumented by a Contrast agent you must first use the tool to register the application (Catalogue command). This will give you an application ID that you can then use in the Run Command.',
|
|
208
|
-
constantsHowToRunContent3:
|
|
209
|
-
'Allowable language values are JAVA, NODE, PYTHON, RUBY and GO.',
|
|
210
|
-
constantsManualInputHeader: 'Manual Input of Command:',
|
|
211
|
-
constantsManualInputCatalogue: 'Catalogue Command:',
|
|
212
|
-
constantsManualInputCatalogueInstruction:
|
|
213
|
-
'To analyse a new application not already instrumented by Contrast, run the following command:',
|
|
214
|
-
constantsManualInputCatalogueRun:
|
|
215
|
-
'After you run this command, you are provided a new application ID in the console. Use this ID in the Run command:',
|
|
216
|
-
constantsManualInputCatalogueRunTitle: 'Run Command:',
|
|
217
|
-
constantsManualInputCatalogueRunInstruction:
|
|
218
|
-
'To analyse an application catalogued by Contrast, run the following command:',
|
|
219
|
-
constantsYaml: 'Yaml:',
|
|
220
|
-
constantsYamlRunCommand:
|
|
221
|
-
'After you catalogue your application go to Run Command above.',
|
|
222
204
|
constantsOptions: 'Options',
|
|
223
|
-
constantsCatalogueCommand:
|
|
224
|
-
'%s YourApiKey %s YourAuthorizationKey %s YourOrganizationId %s YourHost %s YourApplicationName %s YourApplicationLanguage',
|
|
225
|
-
constantsRunCommand:
|
|
226
|
-
'%s YourApiKey %s YourAuthorizationKey %s YourOrganizationId %s YourHost %s YourApplicationId',
|
|
227
205
|
constantsSpecialCharacterWarning:
|
|
228
206
|
'Please Note: Parameters may need to be quoted to avoid issues with special characters.',
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
'Please Note: We currently do not support having a proxy server and TLS enabled at the same time.',
|
|
233
|
-
TlsHeader: 'TLS',
|
|
234
|
-
TlsBody:
|
|
235
|
-
'To enable TLS please use the YAML file with the following parameters:',
|
|
236
|
-
TlsKey: 'key: pathToKey',
|
|
237
|
-
TlsCert: 'cert: pathToCert',
|
|
238
|
-
TlsCaCert: 'cacert: pathToCaCert',
|
|
207
|
+
constantsProxyKey: 'Path to the Certificate Key',
|
|
208
|
+
constantsProxyCert: 'Path to the Cert file',
|
|
209
|
+
constantsProxyCaCert: 'Path to the CaCert file',
|
|
239
210
|
goReadProjectFile: 'Failed to read the project file @ "%s" because: "%s"',
|
|
240
|
-
goAnalysisError: 'GO analysis failed because: ',
|
|
241
|
-
goParseProjectFile: 'Failed to parse go mod graph output because: ',
|
|
242
|
-
mavenNotInstalledError:
|
|
243
|
-
"'mvn' is not available. Please ensure you have Maven installed and available on your path.",
|
|
244
211
|
mavenDependencyTreeNonZero:
|
|
245
212
|
'Building maven dependancy tree failed with a non 0 exit code',
|
|
246
213
|
gradleWrapperUnavailable:
|
|
247
214
|
'Gradle wrapper not found in root of project. Please ensure gradlew or gradlew.bat is in root of the project.',
|
|
248
215
|
gradleDependencyTreeNonZero:
|
|
249
216
|
"Building gradle dependancy tree failed with a non 0 exit code. \n Please check you have the correct version of Java installed to compile your project? \n If running against a muti module project ensure you are using the '--sub-project' flag",
|
|
250
|
-
yamlPathCamelCaseError:
|
|
251
|
-
'Warning: The "yamlPath" parameter will be deprecated in a future release. Please look at our documentation for further guidance.',
|
|
252
|
-
constantsSbom:
|
|
253
|
-
'Generate the Software Bill of Materials (SBOM) for the given application',
|
|
254
217
|
constantsMetadata:
|
|
255
218
|
'Define a set of key=value pairs (which conforms to RFC 2253) for specifying user-defined metadata associated with the application.',
|
|
256
219
|
constantsTags:
|
|
@@ -266,9 +229,7 @@ const en_locales = () => {
|
|
|
266
229
|
'Excludes developer dependencies from the results. All dependencies are included by default.',
|
|
267
230
|
constantsCommands: 'Commands',
|
|
268
231
|
constantsScanOptions: 'Scan Options',
|
|
269
|
-
sbomError: 'All required parameters are not present.',
|
|
270
232
|
sbomRetrievalError: 'Unable to retrieve Software Bill of Materials (SBOM)',
|
|
271
|
-
ignoreDevDep: 'No private libraries that are not scoped detected',
|
|
272
233
|
foundExistingProjectScan: 'Found existing project...',
|
|
273
234
|
projectCreatedScan: 'Project created',
|
|
274
235
|
uploadingScan: 'Uploading file to scan.',
|
|
@@ -284,7 +245,6 @@ const en_locales = () => {
|
|
|
284
245
|
specifyFileAuditNotFound: 'No files found for library analysis',
|
|
285
246
|
populateProjectIdMessage: 'project ID is %s',
|
|
286
247
|
genericServiceError: 'returned with status code %s',
|
|
287
|
-
projectIdError: 'Your project ID is %s please check this is correct',
|
|
288
248
|
permissionsError:
|
|
289
249
|
'You do not have the correct permissions here. \n Contact support@contrastsecurity.com to get this fixed.',
|
|
290
250
|
scanErrorFileMessage:
|
|
@@ -317,6 +277,9 @@ const en_locales = () => {
|
|
|
317
277
|
scanOptionsFileNameSummary:
|
|
318
278
|
'Path of the file you want to scan. If no file is specified, Contrast searches for a .jar, .war, .exe or .zip file in the working directory.',
|
|
319
279
|
scanOptionsVerboseSummary: ' Returns extended information to the terminal.',
|
|
280
|
+
auditOptionsTrackSummary: ' Save the results to the UI.',
|
|
281
|
+
auditOptionsBranchSummary:
|
|
282
|
+
' Set the branch name to associate the library results to.',
|
|
320
283
|
authSuccessMessage: 'Authentication successful',
|
|
321
284
|
runAuthSuccessMessage:
|
|
322
285
|
chalk.bold('CodeSec by Contrast') +
|
|
@@ -443,6 +406,8 @@ const en_locales = () => {
|
|
|
443
406
|
auditBadFiletypeSpecifiedForSave: `\n ${chalk.yellow.bold(
|
|
444
407
|
'Bad file type specified for --save option. Use audit --help to see valid --save options.'
|
|
445
408
|
)}`,
|
|
409
|
+
auditServicesMessageForTS:
|
|
410
|
+
'View your vulnerable library list or full dependency tree in Contrast:',
|
|
446
411
|
auditReportWaiting: 'Waiting for report...',
|
|
447
412
|
auditReportFail: 'Report Retrieval Failed, please try again',
|
|
448
413
|
auditReportSuccessMessage: 'Report successfully retrieved',
|
package/src/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { processAudit } from './commands/audit/processAudit'
|
|
|
5
5
|
import { processAuth } from './commands/auth/auth'
|
|
6
6
|
import { processConfig } from './commands/config/config'
|
|
7
7
|
import { processScan } from './commands/scan/processScan'
|
|
8
|
-
import constants from './
|
|
8
|
+
import constants from './cliConstants'
|
|
9
9
|
import { APP_NAME, APP_VERSION } from './constants/constants'
|
|
10
10
|
import { processLambda } from './lambda/lambda'
|
|
11
11
|
import { localConfig } from './utils/getConfig'
|
package/src/sbom/generateSbom.ts
CHANGED
|
@@ -15,3 +15,23 @@ export const generateSbom = (config: any, type: string) => {
|
|
|
15
15
|
console.log(err)
|
|
16
16
|
})
|
|
17
17
|
}
|
|
18
|
+
|
|
19
|
+
export const generateSCASbom = (
|
|
20
|
+
config: any,
|
|
21
|
+
type: string,
|
|
22
|
+
reportId: string
|
|
23
|
+
) => {
|
|
24
|
+
const client = getHttpClient(config)
|
|
25
|
+
return client
|
|
26
|
+
.getSCASbom(config, type, reportId)
|
|
27
|
+
.then((res: { statusCode: number; body: any }) => {
|
|
28
|
+
if (res.statusCode === 200) {
|
|
29
|
+
return res.body
|
|
30
|
+
} else {
|
|
31
|
+
console.log('Unable to retrieve Software Bill of Materials (SBOM)')
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
.catch((err: any) => {
|
|
35
|
+
console.log(err)
|
|
36
|
+
})
|
|
37
|
+
}
|