@contrast/contrast 1.0.22 → 2.0.0
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 +21 -138
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +2 -19
- package/dist/audit/report/commonReportingFunctions.js +1 -1
- package/dist/audit/save.js +16 -5
- package/dist/cliConstants.js +29 -0
- package/dist/commands/audit/auditController.js +2 -1
- package/dist/commands/audit/help.js +3 -3
- package/dist/commands/audit/processAudit.js +3 -1
- package/dist/commands/audit/saveFile.js +5 -1
- package/dist/commands/github/projectGroup.js +164 -0
- package/dist/common/HTTPClient.js +165 -13
- package/dist/constants/constants.js +3 -5
- package/dist/constants/locales.js +7 -3
- package/dist/index.js +0 -4
- package/dist/lambda/lambda.js +3 -1
- package/dist/sbom/generateSbom.js +7 -0
- package/dist/scaAnalysis/common/commonReportingFunctionsSca.js +6 -6
- package/dist/scaAnalysis/common/scaServicesUpload.js +77 -7
- package/dist/scaAnalysis/common/treeUpload.js +1 -1
- package/dist/scaAnalysis/go/goAnalysis.js +1 -1
- package/dist/scaAnalysis/java/analysis.js +24 -32
- package/dist/scaAnalysis/java/index.js +1 -1
- package/dist/scaAnalysis/javascript/index.js +3 -3
- package/dist/scaAnalysis/legacy/legacyFlow.js +33 -0
- package/dist/scaAnalysis/php/index.js +1 -1
- package/dist/scaAnalysis/processServicesFlow.js +21 -0
- package/dist/scaAnalysis/python/analysis.js +1 -1
- package/dist/scaAnalysis/python/index.js +1 -1
- package/dist/scaAnalysis/repoMode/index.js +2 -2
- package/dist/scaAnalysis/ruby/analysis.js +1 -1
- package/dist/scaAnalysis/ruby/index.js +1 -1
- package/dist/scaAnalysis/scaAnalysis.js +16 -36
- package/dist/scan/autoDetection.js +41 -2
- package/dist/scan/fileUtils.js +5 -4
- package/dist/utils/commonApi.js +26 -1
- package/dist/utils/settingsHelper.js +7 -17
- package/package.json +6 -6
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +3 -22
- package/src/audit/report/commonReportingFunctions.js +1 -1
- package/src/audit/save.js +21 -10
- package/src/cliConstants.js +32 -0
- package/src/commands/audit/auditController.js +2 -1
- package/src/commands/audit/help.js +3 -3
- package/src/commands/audit/processAudit.js +4 -5
- package/src/commands/audit/saveFile.js +6 -1
- package/src/commands/github/projectGroup.js +187 -0
- package/src/common/HTTPClient.js +221 -13
- package/src/constants/constants.js +3 -5
- package/src/constants/locales.js +9 -3
- package/src/index.ts +0 -5
- package/src/lambda/lambda.ts +3 -1
- package/src/lambda/lambdaUtils.ts +1 -1
- package/src/sbom/generateSbom.ts +8 -0
- package/src/scaAnalysis/common/commonReportingFunctionsSca.js +6 -6
- package/src/scaAnalysis/common/scaServicesUpload.js +92 -7
- package/src/scaAnalysis/common/treeUpload.js +1 -1
- package/src/scaAnalysis/go/goAnalysis.js +1 -1
- package/src/scaAnalysis/java/analysis.js +29 -34
- package/src/scaAnalysis/java/index.js +1 -1
- package/src/scaAnalysis/javascript/index.js +3 -6
- package/src/scaAnalysis/legacy/legacyFlow.js +48 -0
- package/src/scaAnalysis/php/index.js +1 -1
- package/src/scaAnalysis/processServicesFlow.js +29 -0
- package/src/scaAnalysis/python/analysis.js +1 -1
- package/src/scaAnalysis/python/index.js +1 -1
- package/src/scaAnalysis/repoMode/index.js +2 -2
- package/src/scaAnalysis/ruby/analysis.js +1 -1
- package/src/scaAnalysis/ruby/index.js +1 -1
- package/src/scaAnalysis/scaAnalysis.js +21 -57
- package/src/scan/autoDetection.js +44 -3
- package/src/scan/fileUtils.js +5 -4
- package/src/utils/commonApi.js +29 -1
- package/src/utils/settingsHelper.js +8 -18
- package/dist/commands/fingerprint/processFingerprint.js +0 -14
- package/src/commands/fingerprint/processFingerprint.js +0 -21
- /package/dist/commands/{fingerprint → github}/fingerprintConfig.js +0 -0
- /package/src/commands/{fingerprint → github}/fingerprintConfig.js +0 -0
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
const commonApi = require('../../utils/commonApi')
|
|
2
2
|
const { APP_VERSION } = require('../../constants/constants')
|
|
3
3
|
const requestUtils = require('../../utils/requestUtils')
|
|
4
|
+
const { performance } = require('perf_hooks')
|
|
4
5
|
|
|
5
|
-
const scaTreeUpload = async (analysis, config) => {
|
|
6
|
+
const scaTreeUpload = async (analysis, config, reportSpinner) => {
|
|
7
|
+
if (config.projectId === '') {
|
|
8
|
+
console.log(
|
|
9
|
+
'We were unable to create/locate a project for this manifest, please try again or run with --debug for more information'
|
|
10
|
+
)
|
|
11
|
+
process.exit(1)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
config.language = config.language === 'JAVASCRIPT' ? 'NODE' : config.language
|
|
15
|
+
const startTime = performance.now()
|
|
16
|
+
const timeout = commonApi.getTimeout(config)
|
|
6
17
|
const requestBody = {
|
|
7
|
-
applicationId: config.applicationId,
|
|
8
18
|
dependencyTree: analysis,
|
|
9
19
|
organizationId: config.organizationId,
|
|
10
20
|
language: config.language,
|
|
@@ -22,7 +32,7 @@ const scaTreeUpload = async (analysis, config) => {
|
|
|
22
32
|
const reportID = await client
|
|
23
33
|
.scaServiceIngest(requestBody, config)
|
|
24
34
|
.then(res => {
|
|
25
|
-
if (res.statusCode === 201) {
|
|
35
|
+
if (res.statusCode === 201 || res.statusCode === 200) {
|
|
26
36
|
return res.body.libraryIngestJobId
|
|
27
37
|
} else {
|
|
28
38
|
throw new Error(res.statusCode + ` error ingesting dependencies`)
|
|
@@ -40,21 +50,95 @@ const scaTreeUpload = async (analysis, config) => {
|
|
|
40
50
|
while (keepChecking) {
|
|
41
51
|
res = await client.scaServiceReportStatus(config, reportID).then(res => {
|
|
42
52
|
if (config.debug) {
|
|
43
|
-
console.log(res.statusCode)
|
|
53
|
+
console.log('scaServiceReportStatus', res.statusCode)
|
|
44
54
|
console.log(res.body)
|
|
45
55
|
}
|
|
46
56
|
if (res.body.status === 'COMPLETED') {
|
|
47
57
|
keepChecking = false
|
|
48
58
|
return client.scaServiceReport(config, reportID).then(res => {
|
|
49
59
|
const reportBody = res.body
|
|
50
|
-
return { reportBody, reportID }
|
|
60
|
+
return { reportBody, reportId: reportID }
|
|
51
61
|
})
|
|
52
62
|
}
|
|
53
63
|
})
|
|
54
64
|
|
|
55
65
|
if (!keepChecking) {
|
|
56
|
-
return { reportArray: res.reportBody, reportID }
|
|
66
|
+
return { reportArray: res.reportBody, reportId: reportID }
|
|
57
67
|
}
|
|
68
|
+
|
|
69
|
+
commonApi.handleTimeout(startTime, timeout, reportSpinner)
|
|
70
|
+
|
|
71
|
+
await requestUtils.sleep(5000)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return { reportArray: res, reportID }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const noProjectUpload = async (analysis, config, reportSpinner) => {
|
|
78
|
+
config.language = config.language === 'JAVASCRIPT' ? 'NODE' : config.language
|
|
79
|
+
const startTime = performance.now()
|
|
80
|
+
const timeout = commonApi.getTimeout(config)
|
|
81
|
+
const requestBody = {
|
|
82
|
+
dependencyTree: analysis,
|
|
83
|
+
language: config.language,
|
|
84
|
+
tool: {
|
|
85
|
+
name: 'Contrast Codesec',
|
|
86
|
+
version: APP_VERSION
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (config.branch) {
|
|
91
|
+
requestBody.branchName = config.branch
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const client = commonApi.getHttpClient(config)
|
|
95
|
+
const reportID = await client
|
|
96
|
+
.noProjectIdUpload(requestBody, config)
|
|
97
|
+
.then(res => {
|
|
98
|
+
if (res.statusCode === 201 || res.statusCode === 200) {
|
|
99
|
+
return res.body.libraryIngestJobId
|
|
100
|
+
} else {
|
|
101
|
+
throw new Error(
|
|
102
|
+
res.statusCode + ` error ingesting dependencies with no project id`
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
.catch(err => {
|
|
107
|
+
throw err
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
if (config.debug) {
|
|
111
|
+
console.log(' polling report no project', reportID)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let keepChecking = true
|
|
115
|
+
let res
|
|
116
|
+
while (keepChecking) {
|
|
117
|
+
res = await client
|
|
118
|
+
.scaServiceNoProjectIdReportStatus(config, reportID)
|
|
119
|
+
.then(res => {
|
|
120
|
+
if (config.debug) {
|
|
121
|
+
console.log('\nscaServiceReportStatus')
|
|
122
|
+
console.log(res.statusCode)
|
|
123
|
+
console.log(res.body)
|
|
124
|
+
}
|
|
125
|
+
if (res.body.status === 'COMPLETED') {
|
|
126
|
+
keepChecking = false
|
|
127
|
+
return client
|
|
128
|
+
.scaServiceReportNoProjectId(config, reportID)
|
|
129
|
+
.then(res => {
|
|
130
|
+
const reportBody = res.body
|
|
131
|
+
return { reportBody, reportId: reportID }
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
if (!keepChecking) {
|
|
137
|
+
return { reportArray: res.reportBody, reportId: reportID }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
commonApi.handleTimeout(startTime, timeout, reportSpinner)
|
|
141
|
+
|
|
58
142
|
await requestUtils.sleep(5000)
|
|
59
143
|
}
|
|
60
144
|
|
|
@@ -62,5 +146,6 @@ const scaTreeUpload = async (analysis, config) => {
|
|
|
62
146
|
}
|
|
63
147
|
|
|
64
148
|
module.exports = {
|
|
65
|
-
scaTreeUpload
|
|
149
|
+
scaTreeUpload,
|
|
150
|
+
noProjectUpload
|
|
66
151
|
}
|
|
@@ -3,7 +3,7 @@ const { APP_VERSION } = require('../../constants/constants')
|
|
|
3
3
|
|
|
4
4
|
const commonSendSnapShot = async (analysis, config) => {
|
|
5
5
|
let requestBody = {}
|
|
6
|
-
config.
|
|
6
|
+
config.legacy === false
|
|
7
7
|
? (requestBody = sendToSCAServices(config, analysis))
|
|
8
8
|
: (requestBody = {
|
|
9
9
|
appID: config.applicationId,
|
|
@@ -11,7 +11,7 @@ const goAnalysis = config => {
|
|
|
11
11
|
const parsedGoDependencies =
|
|
12
12
|
goParseDeps.parseGoDependencies(rawGoDependencies)
|
|
13
13
|
|
|
14
|
-
if (config.
|
|
14
|
+
if (config.legacy === false) {
|
|
15
15
|
return parseDependenciesForSCAServices(parsedGoDependencies)
|
|
16
16
|
} else {
|
|
17
17
|
return createGoTSMessage(parsedGoDependencies)
|
|
@@ -3,8 +3,6 @@ const spawn = require('cross-spawn')
|
|
|
3
3
|
const path = require('path')
|
|
4
4
|
const i18n = require('i18n')
|
|
5
5
|
const fs = require('fs')
|
|
6
|
-
const readLine = require('readline')
|
|
7
|
-
const paramHandler = require('../../utils/paramsUtil/paramHandler')
|
|
8
6
|
|
|
9
7
|
const MAVEN = 'maven'
|
|
10
8
|
const GRADLE = 'gradle'
|
|
@@ -31,30 +29,31 @@ const determineProjectTypeAndCwd = (files, config) => {
|
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
const buildMaven = (config, projectData, timeout) => {
|
|
34
|
-
let
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
args.push(config.mavenSettingsPath)
|
|
41
|
-
}
|
|
42
|
-
// Allow users to provide a custom location for their settings.xml
|
|
32
|
+
let command = 'mvn'
|
|
33
|
+
let args = ['dependency:tree', '-B']
|
|
34
|
+
if (config.mavenSettingsPath) {
|
|
35
|
+
args.push('-s')
|
|
36
|
+
args.push(config.mavenSettingsPath)
|
|
37
|
+
}
|
|
43
38
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
.stdout.toString()
|
|
39
|
+
// Allow users to provide a custom location for their settings.xml
|
|
40
|
+
const cmdDepTree = spawn.sync(command, args, {
|
|
41
|
+
env: process.env,
|
|
42
|
+
cwd: projectData.cwd,
|
|
43
|
+
timeout
|
|
44
|
+
})
|
|
51
45
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
if (cmdDepTree.status !== 0) {
|
|
47
|
+
//if maven not found
|
|
48
|
+
if (config.debug && cmdDepTree.error.code === 'ENOENT') {
|
|
49
|
+
console.log(`ERROR: mvn not found`)
|
|
50
|
+
console.log('Please make sure mvn is installed and accessible')
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
throw new Error(i18n.__('mavenDependencyTreeNonZero', projectData.cwd))
|
|
57
54
|
}
|
|
55
|
+
|
|
56
|
+
return cmdDepTree.stdout.toString()
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
const buildGradle = (config, projectData, timeout) => {
|
|
@@ -133,18 +132,14 @@ const getJavaBuildDeps = (config, files) => {
|
|
|
133
132
|
projectType: undefined
|
|
134
133
|
}
|
|
135
134
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
output.mvnDependancyTreeOutput = buildGradle(config, projectData, timeout)
|
|
142
|
-
}
|
|
143
|
-
output.projectType = projectData.projectType
|
|
144
|
-
return output
|
|
145
|
-
} catch (err) {
|
|
146
|
-
console.log(err.message.toString())
|
|
135
|
+
const projectData = determineProjectTypeAndCwd(files, config)
|
|
136
|
+
if (projectData.projectType === MAVEN) {
|
|
137
|
+
output.mvnDependancyTreeOutput = buildMaven(config, projectData, timeout)
|
|
138
|
+
} else if (projectData.projectType === GRADLE) {
|
|
139
|
+
output.mvnDependancyTreeOutput = buildGradle(config, projectData, timeout)
|
|
147
140
|
}
|
|
141
|
+
output.projectType = projectData.projectType
|
|
142
|
+
return output
|
|
148
143
|
}
|
|
149
144
|
|
|
150
145
|
module.exports = {
|
|
@@ -12,7 +12,7 @@ const javaAnalysis = async (config, languageFiles) => {
|
|
|
12
12
|
|
|
13
13
|
const javaDeps = buildJavaTree(config, languageFiles.JAVA)
|
|
14
14
|
|
|
15
|
-
if (config.
|
|
15
|
+
if (config.legacy === false) {
|
|
16
16
|
return parseDependenciesForSCAServices(javaDeps)
|
|
17
17
|
} else {
|
|
18
18
|
return createJavaTSMessage(javaDeps)
|
|
@@ -14,8 +14,7 @@ const jsAnalysis = async (config, languageFiles) => {
|
|
|
14
14
|
const buildNodeTree = async (config, files) => {
|
|
15
15
|
let analysis = await readFiles(config, files)
|
|
16
16
|
const rawNode = await parseFiles(config, files, analysis)
|
|
17
|
-
|
|
18
|
-
if (config.experimental) {
|
|
17
|
+
if (config.legacy === false) {
|
|
19
18
|
return scaServiceParser.parseJS(rawNode)
|
|
20
19
|
}
|
|
21
20
|
|
|
@@ -65,10 +64,8 @@ const parseFiles = async (config, files, js) => {
|
|
|
65
64
|
)
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
if (currentLockFileVersion === 3 &&
|
|
69
|
-
throw new Error(
|
|
70
|
-
`NPM lockfileVersion 3 is only supported when using the '-e' flag.`
|
|
71
|
-
)
|
|
67
|
+
if (currentLockFileVersion === 3 && config.legacy) {
|
|
68
|
+
throw new Error(`NPM lockfileVersion 3 is not support with --legacy`)
|
|
72
69
|
}
|
|
73
70
|
|
|
74
71
|
js.npmLockFile = await analysis.parseNpmLockFile(npmLockFile)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const auditController = require('../../commands/audit/auditController')
|
|
2
|
+
const {
|
|
3
|
+
returnOra,
|
|
4
|
+
startSpinner,
|
|
5
|
+
succeedSpinner
|
|
6
|
+
} = require('../../utils/oraWrapper')
|
|
7
|
+
const i18n = require('i18n')
|
|
8
|
+
const treeUpload = require('../common/treeUpload')
|
|
9
|
+
const {
|
|
10
|
+
pollForSnapshotCompletion
|
|
11
|
+
} = require('../../audit/languageAnalysisEngine/sendSnapshot')
|
|
12
|
+
const { vulnerabilityReportV2 } = require('../../audit/report/reportingFeature')
|
|
13
|
+
const { auditSave } = require('../../audit/save')
|
|
14
|
+
|
|
15
|
+
const legacyFlow = async (config, messageToSend) => {
|
|
16
|
+
const startTime = performance.now()
|
|
17
|
+
if (!config.applicationId) {
|
|
18
|
+
config.applicationId = await auditController.dealWithNoAppId(config)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log('') //empty log for space before spinner
|
|
22
|
+
//send message to TS
|
|
23
|
+
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
|
|
24
|
+
startSpinner(reportSpinner)
|
|
25
|
+
const snapshotResponse = await treeUpload.commonSendSnapShot(
|
|
26
|
+
messageToSend,
|
|
27
|
+
config
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
// poll for completion
|
|
31
|
+
await pollForSnapshotCompletion(config, snapshotResponse.id, reportSpinner)
|
|
32
|
+
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
|
|
33
|
+
|
|
34
|
+
await vulnerabilityReportV2(config, snapshotResponse.id)
|
|
35
|
+
if (config.save !== undefined) {
|
|
36
|
+
await auditSave(config)
|
|
37
|
+
} else {
|
|
38
|
+
console.log('\nUse contrast audit --save to generate an SBOM')
|
|
39
|
+
}
|
|
40
|
+
const endTime = performance.now() - startTime
|
|
41
|
+
const scanDurationMs = endTime - startTime
|
|
42
|
+
|
|
43
|
+
console.log(`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = {
|
|
47
|
+
legacyFlow
|
|
48
|
+
}
|
|
@@ -5,7 +5,7 @@ const { parsePHPLockFileForScaServices } = require('./phpNewServicesMapper')
|
|
|
5
5
|
const phpAnalysis = config => {
|
|
6
6
|
let analysis = readFiles(config)
|
|
7
7
|
|
|
8
|
-
if (config.
|
|
8
|
+
if (config.legacy === false) {
|
|
9
9
|
return parsePHPLockFileForScaServices(analysis.rawLockFileContents)
|
|
10
10
|
} else {
|
|
11
11
|
const phpDep = parseProjectFiles(analysis)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const projectConfig = require('../commands/github/projectGroup')
|
|
2
|
+
const scaServicesUpload = require('../scaAnalysis/common/scaServicesUpload')
|
|
3
|
+
const processUpload = async (analysis, config, reportSpinner) => {
|
|
4
|
+
let projectId = await projectConfig.getProjectIdByOrg(config)
|
|
5
|
+
|
|
6
|
+
if (projectId === '') {
|
|
7
|
+
if (config.track === true) {
|
|
8
|
+
await projectConfig.registerNewProjectGroup(config)
|
|
9
|
+
projectId = await projectConfig.getProjectIdByOrg(config)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (config.track === false || config.track === undefined) {
|
|
13
|
+
return await scaServicesUpload.noProjectUpload(
|
|
14
|
+
analysis,
|
|
15
|
+
config,
|
|
16
|
+
reportSpinner
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
await projectConfig.registerProjectIdOnCliServices(config, projectId)
|
|
22
|
+
config.projectId = projectId
|
|
23
|
+
|
|
24
|
+
return await scaServicesUpload.scaTreeUpload(analysis, config, reportSpinner)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = {
|
|
28
|
+
processUpload
|
|
29
|
+
}
|
|
@@ -60,7 +60,7 @@ const checkForCorrectFiles = languageFiles => {
|
|
|
60
60
|
|
|
61
61
|
const getPythonDeps = (config, languageFiles) => {
|
|
62
62
|
try {
|
|
63
|
-
if (config.
|
|
63
|
+
if (config.legacy === false) {
|
|
64
64
|
let pythonLockFileContents = readLockFile(config.file)
|
|
65
65
|
return scaPythonParser(pythonLockFileContents)
|
|
66
66
|
} else {
|
|
@@ -4,7 +4,7 @@ const { getPythonDeps, secondaryParser } = require('./analysis')
|
|
|
4
4
|
const pythonAnalysis = (config, languageFiles) => {
|
|
5
5
|
const pythonDeps = getPythonDeps(config, languageFiles.PYTHON)
|
|
6
6
|
|
|
7
|
-
if (config.
|
|
7
|
+
if (config.legacy === false) {
|
|
8
8
|
return pythonDeps
|
|
9
9
|
} else {
|
|
10
10
|
return createPythonTSMessage(pythonDeps)
|
|
@@ -7,10 +7,10 @@ const buildRepo = async (config, languageFiles) => {
|
|
|
7
7
|
|
|
8
8
|
if (project.projectType === 'maven') {
|
|
9
9
|
let jsonPomFile = mavenParser.readPomFile(project)
|
|
10
|
-
mavenParser.parsePomFile(jsonPomFile)
|
|
10
|
+
return mavenParser.parsePomFile(jsonPomFile)
|
|
11
11
|
} else if (project.projectType === 'gradle') {
|
|
12
12
|
const gradleJson = gradleParser.readBuildGradleFile(project)
|
|
13
|
-
gradleParser.parseGradleJson(await gradleJson)
|
|
13
|
+
return gradleParser.parseGradleJson(await gradleJson)
|
|
14
14
|
} else {
|
|
15
15
|
console.log('Unable to read project files.')
|
|
16
16
|
}
|
|
@@ -6,7 +6,7 @@ const getRubyDeps = (config, languageFiles) => {
|
|
|
6
6
|
checkForCorrectFiles(languageFiles)
|
|
7
7
|
const parsedGem = readAndParseGemfile(config.file)
|
|
8
8
|
const parsedLock = readAndParseGemLockFile(config.file)
|
|
9
|
-
if (config.
|
|
9
|
+
if (config.legacy === false) {
|
|
10
10
|
const rubyArray = removeRedundantAndPopulateDefinedElements(
|
|
11
11
|
parsedLock.sources
|
|
12
12
|
)
|
|
@@ -4,7 +4,7 @@ const { createRubyTSMessage } = require('../common/formatMessage')
|
|
|
4
4
|
const rubyAnalysis = (config, languageFiles) => {
|
|
5
5
|
const rubyDeps = analysis.getRubyDeps(config, languageFiles.RUBY)
|
|
6
6
|
|
|
7
|
-
if (config.
|
|
7
|
+
if (config.legacy === false) {
|
|
8
8
|
return rubyDeps
|
|
9
9
|
} else {
|
|
10
10
|
return createRubyTSMessage(rubyDeps)
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
const {
|
|
2
2
|
supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET }
|
|
3
3
|
} = require('../constants/constants')
|
|
4
|
-
const {
|
|
5
|
-
pollForSnapshotCompletion
|
|
6
|
-
} = require('../audit/languageAnalysisEngine/sendSnapshot')
|
|
7
4
|
const {
|
|
8
5
|
returnOra,
|
|
9
6
|
startSpinner,
|
|
10
7
|
succeedSpinner
|
|
11
8
|
} = require('../utils/oraWrapper')
|
|
12
|
-
const { vulnerabilityReportV2 } = require('../audit/report/reportingFeature')
|
|
13
9
|
const autoDetection = require('../scan/autoDetection')
|
|
14
|
-
const treeUpload = require('./common/treeUpload')
|
|
15
|
-
const auditController = require('../commands/audit/auditController')
|
|
16
10
|
const rootFile = require('../audit/languageAnalysisEngine/getProjectRootFilenames')
|
|
17
11
|
const path = require('path')
|
|
18
12
|
const i18n = require('i18n')
|
|
@@ -27,19 +21,15 @@ const { pythonAnalysis } = require('./python')
|
|
|
27
21
|
const javaAnalysis = require('./java')
|
|
28
22
|
const jsAnalysis = require('./javascript')
|
|
29
23
|
const auditReport = require('./common/auditReport')
|
|
30
|
-
const
|
|
31
|
-
const settingsHelper = require('../utils/settingsHelper')
|
|
24
|
+
const processServices = require('./processServicesFlow')
|
|
32
25
|
const chalk = require('chalk')
|
|
33
|
-
const saveResults = require('../scan/saveResults')
|
|
34
26
|
const {
|
|
35
27
|
convertGenericToTypedReportModelSca
|
|
36
28
|
} = require('./common/utils/reportUtilsSca')
|
|
29
|
+
const projectConfig = require('../commands/github/projectGroup')
|
|
30
|
+
const { legacyFlow } = require('./legacy/legacyFlow')
|
|
37
31
|
|
|
38
32
|
const processSca = async config => {
|
|
39
|
-
//checks to see whether to use old TS / new SCA path
|
|
40
|
-
config = await settingsHelper.getSettings(config)
|
|
41
|
-
|
|
42
|
-
const startTime = performance.now()
|
|
43
33
|
let filesFound
|
|
44
34
|
|
|
45
35
|
if (config.help) {
|
|
@@ -72,10 +62,9 @@ const processSca = async config => {
|
|
|
72
62
|
switch (Object.keys(filesFound[0])[0]) {
|
|
73
63
|
case JAVA:
|
|
74
64
|
config.language = JAVA
|
|
75
|
-
|
|
76
|
-
if (config.mode === 'repo') {
|
|
65
|
+
if (config.repo && !config.legacy) {
|
|
77
66
|
try {
|
|
78
|
-
|
|
67
|
+
messageToSend = await repoMode.buildRepo(config, filesFound[0])
|
|
79
68
|
} catch (e) {
|
|
80
69
|
throw new Error(
|
|
81
70
|
'Unable to build in repository mode. Check your project file'
|
|
@@ -106,7 +95,7 @@ const processSca = async config => {
|
|
|
106
95
|
config.language = GO
|
|
107
96
|
break
|
|
108
97
|
case DOTNET:
|
|
109
|
-
if (config.
|
|
98
|
+
if (config.legacy === false) {
|
|
110
99
|
console.log(
|
|
111
100
|
`${chalk.bold(
|
|
112
101
|
'\n.NET project found\n'
|
|
@@ -124,65 +113,40 @@ const processSca = async config => {
|
|
|
124
113
|
return
|
|
125
114
|
}
|
|
126
115
|
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
116
|
+
if (config.legacy === false) {
|
|
117
|
+
if (!config.name) {
|
|
118
|
+
config = await projectConfig.dealWithNoName(config)
|
|
119
|
+
}
|
|
120
|
+
const startTime = performance.now()
|
|
132
121
|
console.log('') //empty log for space before spinner
|
|
133
122
|
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
|
|
134
123
|
startSpinner(reportSpinner)
|
|
135
|
-
|
|
124
|
+
|
|
125
|
+
let reportResponse = await processServices.processUpload(
|
|
136
126
|
messageToSend,
|
|
137
|
-
config
|
|
127
|
+
config,
|
|
128
|
+
reportSpinner
|
|
138
129
|
)
|
|
139
130
|
|
|
140
|
-
const reportModelLibraryList =
|
|
141
|
-
|
|
131
|
+
const reportModelLibraryList = convertGenericToTypedReportModelSca(
|
|
132
|
+
reportResponse.reportArray
|
|
133
|
+
)
|
|
142
134
|
auditReport.processAuditReport(config, reportModelLibraryList)
|
|
143
|
-
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
|
|
144
|
-
|
|
145
135
|
if (config.save !== undefined) {
|
|
146
|
-
await auditSave.auditSave(config, reportId)
|
|
136
|
+
await auditSave.auditSave(config, reportResponse.reportId)
|
|
147
137
|
} else {
|
|
148
138
|
console.log('Use contrast audit --save to generate an SBOM')
|
|
149
139
|
}
|
|
150
140
|
|
|
151
|
-
const endTime = performance.now() - startTime
|
|
152
|
-
const scanDurationMs = endTime - startTime
|
|
153
|
-
console.log(
|
|
154
|
-
`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
|
|
155
|
-
)
|
|
156
|
-
} else {
|
|
157
|
-
console.log('') //empty log for space before spinner
|
|
158
|
-
//send message to TS
|
|
159
|
-
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
|
|
160
|
-
startSpinner(reportSpinner)
|
|
161
|
-
const snapshotResponse = await treeUpload.commonSendSnapShot(
|
|
162
|
-
messageToSend,
|
|
163
|
-
config
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
// poll for completion
|
|
167
|
-
await pollForSnapshotCompletion(
|
|
168
|
-
config,
|
|
169
|
-
snapshotResponse.id,
|
|
170
|
-
reportSpinner
|
|
171
|
-
)
|
|
172
141
|
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
|
|
173
142
|
|
|
174
|
-
await vulnerabilityReportV2(config, snapshotResponse.id)
|
|
175
|
-
if (config.save !== undefined) {
|
|
176
|
-
await auditSave.auditSave(config)
|
|
177
|
-
} else {
|
|
178
|
-
console.log('\nUse contrast audit --save to generate an SBOM')
|
|
179
|
-
}
|
|
180
143
|
const endTime = performance.now() - startTime
|
|
181
144
|
const scanDurationMs = endTime - startTime
|
|
182
|
-
|
|
183
145
|
console.log(
|
|
184
146
|
`----- completed in ${(scanDurationMs / 1000).toFixed(2)}s -----`
|
|
185
147
|
)
|
|
148
|
+
} else {
|
|
149
|
+
await legacyFlow(config, messageToSend)
|
|
186
150
|
}
|
|
187
151
|
} else {
|
|
188
152
|
if (filesFound.length === 0) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const i18n = require('i18n')
|
|
2
2
|
const fileFinder = require('./fileUtils')
|
|
3
|
-
|
|
3
|
+
const {
|
|
4
|
+
supportedLanguages: { JAVA, GO, PYTHON, RUBY, JAVASCRIPT, NODE, PHP, DOTNET }
|
|
5
|
+
} = require('../constants/constants')
|
|
4
6
|
const autoDetectFingerprintInfo = async (filePath, depth) => {
|
|
5
7
|
let complexObj = await fileFinder.findAllFiles(filePath, depth)
|
|
6
8
|
let result = []
|
|
@@ -13,6 +15,44 @@ const autoDetectFingerprintInfo = async (filePath, depth) => {
|
|
|
13
15
|
return result
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
const detectPackageManager = async array => {
|
|
19
|
+
array.forEach(i => {
|
|
20
|
+
if (i.filePath.includes('pom.xml')) {
|
|
21
|
+
i['language'] = JAVA
|
|
22
|
+
i['packageManager'] = 'MAVEN'
|
|
23
|
+
}
|
|
24
|
+
if (i.filePath.includes('build.gradle.kts')) {
|
|
25
|
+
i['language'] = JAVA
|
|
26
|
+
i['packageManager'] = 'GRADLE'
|
|
27
|
+
}
|
|
28
|
+
if (i.filePath.includes('build.gradle')) {
|
|
29
|
+
i['language'] = JAVA
|
|
30
|
+
i['packageManager'] = 'GRADLE'
|
|
31
|
+
}
|
|
32
|
+
if (i.filePath.includes('package.json')) {
|
|
33
|
+
i['language'] = JAVASCRIPT
|
|
34
|
+
i['packageManager'] = 'NPM'
|
|
35
|
+
}
|
|
36
|
+
if (i.filePath.includes('yarn.lock')) {
|
|
37
|
+
i['language'] = JAVASCRIPT
|
|
38
|
+
i['packageManager'] = 'YARN'
|
|
39
|
+
}
|
|
40
|
+
if (i.filePath.includes('Pipfile')) {
|
|
41
|
+
i['language'] = PYTHON
|
|
42
|
+
}
|
|
43
|
+
if (i.filePath.includes('csproj')) {
|
|
44
|
+
i['language'] = DOTNET
|
|
45
|
+
}
|
|
46
|
+
if (i.filePath.includes('Gemfile')) {
|
|
47
|
+
i['language'] = RUBY
|
|
48
|
+
}
|
|
49
|
+
if (i.filePath.includes('go.mod')) {
|
|
50
|
+
i['language'] = GO
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
return array
|
|
54
|
+
}
|
|
55
|
+
|
|
16
56
|
const autoDetectFileAndLanguage = async configToUse => {
|
|
17
57
|
const entries = await fileFinder.findFile()
|
|
18
58
|
|
|
@@ -67,7 +107,7 @@ const dealWithMultiJava = filesFound => {
|
|
|
67
107
|
let hasMultiJava =
|
|
68
108
|
filesFound.filter(data => {
|
|
69
109
|
return (
|
|
70
|
-
Object.keys(data)[0] ===
|
|
110
|
+
Object.keys(data)[0] === JAVA &&
|
|
71
111
|
Object.values(data)[0].includes('build.gradle') &&
|
|
72
112
|
Object.values(data)[0].includes('pom.xml')
|
|
73
113
|
)
|
|
@@ -119,5 +159,6 @@ module.exports = {
|
|
|
119
159
|
autoDetectAuditFilesAndLanguages,
|
|
120
160
|
errorOnAuditFileDetection,
|
|
121
161
|
autoDetectFingerprintInfo,
|
|
122
|
-
dealWithMultiJava
|
|
162
|
+
dealWithMultiJava,
|
|
163
|
+
detectPackageManager
|
|
123
164
|
}
|
package/src/scan/fileUtils.js
CHANGED
|
@@ -18,6 +18,7 @@ const findAllFiles = async (filePath, depth = 2) => {
|
|
|
18
18
|
'**/build.gradle',
|
|
19
19
|
'**/build.gradle.kts',
|
|
20
20
|
'**/package.json',
|
|
21
|
+
'**/yarn.lock',
|
|
21
22
|
'**/Pipfile',
|
|
22
23
|
'**/*.csproj',
|
|
23
24
|
'**/Gemfile',
|
|
@@ -38,19 +39,19 @@ const findAllFiles = async (filePath, depth = 2) => {
|
|
|
38
39
|
return []
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
const findFilesJava = async (languagesFound, filePath) => {
|
|
42
|
+
const findFilesJava = async (languagesFound, filePath, depth = 1) => {
|
|
42
43
|
const result = await fg(
|
|
43
44
|
['**/pom.xml', '**/build.gradle', '**/build.gradle.kts'],
|
|
44
45
|
{
|
|
45
46
|
dot: false,
|
|
46
|
-
deep:
|
|
47
|
+
deep: depth,
|
|
47
48
|
onlyFiles: true,
|
|
48
49
|
cwd: filePath ? filePath : process.cwd()
|
|
49
50
|
}
|
|
50
51
|
)
|
|
51
52
|
|
|
52
53
|
if (result.length > 0) {
|
|
53
|
-
return languagesFound.push({ JAVA: result })
|
|
54
|
+
return languagesFound.push({ JAVA: result, language: 'JAVA' })
|
|
54
55
|
}
|
|
55
56
|
return languagesFound
|
|
56
57
|
}
|
|
@@ -67,7 +68,7 @@ const findFilesJavascript = async (languagesFound, filePath) => {
|
|
|
67
68
|
)
|
|
68
69
|
|
|
69
70
|
if (result.length > 0) {
|
|
70
|
-
return languagesFound.push({ JAVASCRIPT: result })
|
|
71
|
+
return languagesFound.push({ JAVASCRIPT: result, language: 'JAVASCRIPT' })
|
|
71
72
|
}
|
|
72
73
|
return languagesFound
|
|
73
74
|
}
|